概要 shell
1)介绍Linux系统中时钟的基本概念 ide
2)探讨hwclock命令的工做方式。 ui
3)系统启动过程当中Linux系统对系统时钟和硬件时钟的同步。 this
主要术语和背景知识 spa
UTC: Coordinated Universal Time, 一种是件标准,用以规范世界各地的时间。 操作系统
Time Zone: 时区,表示方式是:UTC-xx:xx, UTC+xx:xx。好比中国的时区表示是:UTC+08:00. rest
其余一些相关术语,好比CST,DST等,咱们并不须要关心。 code
典型Linux对时钟和时间的管理 orm
一个典型的Linux系统主要有两种时钟:系统时钟(System Clock)和硬件时钟(Hardware Clock)。 ip
硬件时钟独立运行于操做系统以外,有本身的电源供给,即便当系统关机时,它也依然在跑。Hardware Clock有时也叫BIOS Clock, CMOS Clock, RTC 等。可是只有hardware clock这个词汇不容易引发误解。
系统时钟就是由操做系统维护的一个时钟。在Linux系统中,是由kernel维护,由timer的中断进行驱动的一个时钟(由于它是由计时器的中断驱动的,因此能够认为是一个软件时钟)。
有两个时钟,就须要有同步。这个同步功能由hwclock来实现。在此仅做简要介绍,详情请查询手册(man hwclock).
hwclock在各个系统上的工做方式可能并不同,可是,在大多数状况下,它经过访问/dev/rtc来进行硬件时钟的控制。在先行的发行版上,/dev/rtc不少时候是一个symlink,指向/dev/rtcX。影响hwclock工做的还有两个因素,一个是TZ环境变量,一个是/etc下的配置文件(这个文件位置不一,也可能没有,要看系统)。
一个典型的Linux系统,对时间的同步会自动发生在系统启动和系统关闭的时候。系统启动时,将Hardware Clock中的内容同步到System Clock;系统关闭时,将System Clock中的内容同步到Hardware Clock。固然,这种同步也能够本身手动进行,或者利用脚本进行(本身编写的,或者该版本系统中自带的)。
以下是一个典型的启动和关闭系统时,对系统时钟和硬件时钟进行同步的脚本,一般存在于/etc/init.d/目录下。
#!/bin/sh ### BEGIN INIT INFO # Provides: hwclock # Required-Start: # Required-Stop: $local_fs # Default-Start: S # Default-Stop: 0 6 # Short-Description: Set system clock # Description: Set system clock to hardware clock, according to the UTC # setting in /etc/default/rcS (see also rcS(5)). ### END INIT INFO # # WARNING: If your hardware clock is not in UTC/GMT, this script # must know the local time zone. This information is # stored in /etc/localtime. This might be a problem if # your /etc/localtime is a symlink to something in # /usr/share/zoneinfo AND /usr isn't in the root # partition! The workaround is to define TZ either # in /etc/default/rcS, or in the proper place below. [ ! -x /sbin/hwclock ] && exit 0 . /etc/default/rcS [ "$UTC" = "yes" ] && tz="--utc" || tz="--localtime" case "$1" in start) if [ "$VERBOSE" != no ] then echo "System time was `date`." echo "Setting the System Clock using the Hardware Clock as reference..." fi if [ "$HWCLOCKACCESS" != no ] then if [ -z "$TZ" ] then hwclock $tz --hctosys else TZ="$TZ" hwclock $tz --hctosys fi fi if [ "$VERBOSE" != no ] then echo "System Clock set. System local time is now `date`." fi ;; stop|restart|reload|force-reload) # # Updates the Hardware Clock with the System Clock time. # This will *override* any changes made to the Hardware Clock. # # WARNING: If you disable this, any changes to the system # clock will not be carried across reboots. # if [ "$VERBOSE" != no ] then echo "Saving the System Clock time to the Hardware Clock..." fi if [ "$HWCLOCKACCESS" != no ] then hwclock $tz --systohc fi if [ "$VERBOSE" != no ] then echo "Hardware Clock updated to `date`." fi exit 0 ;; show) if [ "$HWCLOCKACCESS" != no ] then hwclock $tz --show fi ;; *) echo "Usage: hwclock.sh {start|stop|show|reload|restart}" >&2 echo " start sets kernel (system) clock from hardware (RTC) clock" >&2 echo " stop and reload set hardware (RTC) clock from kernel (system) clock" >&2 exit 1 ;; esac
hwclock 和 date 命令中--utc选项
这两个命令虽然都有--utc选项,可是其含义是不一样的。首先来看一段命令和结果。
chenqi@chenqi-OptiPlex-760:/etc/default$ date Wed Oct 31 16:00:23 CST 2012 chenqi@chenqi-OptiPlex-760:/etc/default$ date --utc Wed Oct 31 08:00:24 UTC 2012 chenqi@chenqi-OptiPlex-760:/etc/default$ sudo hwclock --localtime -r Wed 31 Oct 2012 08:00:30 AM CST -0.594038 seconds chenqi@chenqi-OptiPlex-760:/etc/default$ sudo hwclock --utc -r Wed 31 Oct 2012 04:00:37 PM CST -0.937780 seconds由上可见date --utc获得的时间和hwclock --localtime获得的时间一致,而date获得的时间和hwclock --utc获得的时间一致。这一点,容易让人困扰。
实际上,date命令中--utc选项表示“对标准UTC时间进行操做”,因此date --utc是输出当前的标准UTC时间;而hwclock中--utc选项的意思是,此次操做要考虑时区上的换算,好比,若是是读取hardware clock的话,那么读出的数据(从本地读出的时间),要考虑到时区,换算出当前时区的时间后,再作输出。同理,--localtime表示不用进行时区上的考虑和换算,读出什么,就输出什么。
由此,上面的困扰就比较容易解释了,hardware clock存储的时UTC标准时间,因此用--localtime去读取,获得的就是标准UTC时间,即和date --utc一致。另一种状况就是考虑了时区换算,道理同样。
参考材料
hwclock manual
date manual
http://en.wikipedia.org/wiki/Time_zone