21

I'm writing a kernel module that checks to see if the time is between two specified hours, and disables input if it is. This has to do with me wanting to make sure I go to bed early. (I know I could also use any number of different techniques including cron etc, but I wanted to learn kernel programming...)

As a first version, I therefore check if the current hour is between start and end, which are set via parameters to the module.

My question is therefore : How do I get the current hour? I have no access to the usual time functions in the standard library because I am in kernel space. I'm guessing that I should be using do_gettimeofday() for this, but that only gives me seconds and nanoseconds, and I need hours in the current day.

Thanks.

Tom Macdonald
  • 6,433
  • 7
  • 39
  • 59

5 Answers5

16

time_to_tm function can be of your help, which returns the structure tm. Timezone available in variable sys_tz, it can help you to set your offset properly to get local time.

Zimbabao
  • 8,150
  • 3
  • 29
  • 36
7

To get the local time in kernel, add the below code snippet your kernel driver:

struct timeval time;
unsigned long local_time;

do_gettimeofday(&time);
local_time = (u32)(time.tv_sec - (sys_tz.tz_minuteswest * 60));
rtc_time_to_tm(local_time, &tm);

printk(" @ (%04d-%02d-%02d %02d:%02d:%02d)\n", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
Bharath
  • 71
  • 1
  • 1
  • 3
    According to https://elixir.bootlin.com/linux/latest/ident/do_gettimeofday , this function seems to have been deprecated, what is the modern way of getting current time? I assume this have to do with the recent move to 64-bit time? – Hanif Bin Ariffin Jun 06 '19 at 01:04
3

This works well for me:

#include <linux/time.h>
...
/* getnstimeofday - Returns the time of day in a timespec */
void getnstimeofday(struct timespec *ts)

For getting usual time format you can use:

printk("TIME: %.2lu:%.2lu:%.2lu:%.6lu \r\n",
                   (curr_tm.tv_sec / 3600) % (24),
                   (curr_tm.tv_sec / 60) % (60),
                   curr_tm.tv_sec % 60,
                   curr_tm.tv_nsec / 1000);
Roman
  • 350
  • 2
  • 8
-1

Converting the do_gettimeofday result to an hour is pretty simple, since it starts at midnight GMT.

time_t t = time(0);
time_t SecondsOfDay = t % (24*60*60);
time_t HourGMT = SecondsOfDay / (60*60);

Then adjust for your local timezone

Erik
  • 88,732
  • 13
  • 198
  • 189
-1

We can use clock_gettime function with CLOCK_REALTIME as the type of clock.

Reference http://linux.die.net/man/3/clock_gettime

Just doing a strace on date executable gives us an idea to get the current date in the kernel mode.

sunmoon
  • 1,448
  • 1
  • 15
  • 27