The hardware clock
There are two clocks in a Linux system, the hardware real time clock (RTC) and the Linux system time maintained by the kernel. In this tutorial, we will look at the hardware real time clock.
The hardware real time clock is an integrated circuit, a part of computer's hardware, powered by a battery and keeps on running even when the system is electrically switched off. When a Linux system boots, it initializes the system time from the hardware clock time. After that, the system time is used for all purposes.
The syntax of the hwclock command usage is,
hwclock [function] [options...]
Some important functions are, -h (or, --help) for the command syntax, -r (or, --show) to read and print the hardware clock, -s (or, --hctosys) to set the system time from the hardware clock, -w (or, --systohc) to set the hardware clock from the system time and --adjust to adjust the hardware clock for systematic drift since the last adjustment or setting. Some important options are -u (or, --utc), --localtime and -D (or, --debug).
You can query and modify the hardware clock using the hwclock program. For example, the command,
sudo hwclock -r
reads the hardware clock and prints output like,
Fri 14 Oct 2011 12:30:28 PM IST -0.890954 seconds
In the above example, there is a difference of 0.890954 seconds between the time command was given on the shell and the time the hardware clock was read. The hardware clock might be storing time in the local time zone or the UTC. So, to get the correct output, --localtime or -u (for UTC) option has to be given. If the hardware clock is storing time as per UTC, and --locatime option is given, or vice-versa, the output is incorrect and is offset by +/- the offset of local time from the UTC. The debug, -D option gives more information about the command.
$ sudo hwclock -r --localtime
Fri 14 Oct 2011 12:30:36 PM IST -0.844154 seconds
$ sudo hwclock -D
hwclock from util-linux-ng 2.17.2
Using /dev interface to clock.
Assuming hardware clock is kept in local time.
Waiting for clock tick...
...got clock tick
Time read from Hardware Clock: 2011/10/14 12:40:47
Hw clock time : 2011/10/14 12:40:47 = 1318576247 seconds since 1969
Fri 14 Oct 2011 12:40:47 PM IST -0.953797 seconds
Hardware clocks are not very accurate as these clocks gain or lose time over a period. But these clocks are inaccurate in a systematic way. The hardware clocks gain or lose the same amount of time everyday. This is called the systematic drift. We can set the hardware clock to an accurate time using the system clock a few times and note the difference between the reliable accurate time and the hardware clock time. By this, we can know time gained or lost per day by the hardware clock. This is the calibration of the hardware clock and finding the systematic drift. Using the systematic drift we can adjust the hardware clock time.
There is a text file, /etc/adjtime, which contains the parameters for adjusting the hardware clock's systematic drift. A sample /etc/adjtime file is given below:
0.000000 1318745722 0.000000
There are three lines in the /etc/adjtime file. The first line has three numbers. The first number is the systematic drift per day in seconds and is a floating point decimal number. The second number is the number of seconds since 1969 UTC timestamp at the time of last calibration or adjustment, a decimal integer. The third number on the first line is zero and is a part of this file for compatibility with the clock program. In the second line of /etc/adjtime, there is a single decimal integer, a timestamp, number of seconds since 1969 UTC of the last calibration of the hardware clock. On the third and the last line there is a string UTC or LOCAL indicating whether the time in hardware clock is UTC or localtime.
Initially there may be no /etc/adjtime file. We can create this file with hwclock --systohc --localtime. Before hwclock --systohc --localtime, we tune our system time with a reliable network time server using the ntpdate program. For example,
$ sudo ntpdate pool.ntp.org
16 Oct 11:22:38 ntpdate: step time server 184.108.40.206 offset -2.464449 sec
$ sudo hwclock --systohc --localtime
$ ls -ls /etc/adjtime
4 -rw-r--r-- 1 root root 46 2011-10-16 14:59 /etc/adjtime
$ cat /etc/adjtime
0.000000 1318757349 0.000000
We can repeat the above commands after a few days. The hardware clock might have gained or lost some time during this duration. hwclock updates the /etc/adjtime file, and on the basis of difference between the hardware clock and the system clock (the latter has the accurate time from a network time server), works out the systematic drift. After the systematic drift is in place in the /etc/adjtime file, we can execute,
sudo hwclock --adjust
to adjust the hardware clock time, periodically.