回忆之城
生命在于折腾
posts - 575,comments - 9,trackbacks - 0
找到这个命令纯属意外,本来只是想简单的装个LINUX机器,而装机的时候按照文档要定时进行时间同步,那么使用NTPDATE来定时同步是个不错的选 择,那么NTPDATE后到底要不要将同步后的时间通过HWCLOCK来写入CMOS呢?这就涉及到NTPDATE后的时间会不会自动的写入到CMOS, 那么就找到了LINUX系统有开关可以设置的,打开的话,每隔11分钟,系统会把系统时间写入到CMOS,也就是做一次同步。那么这个开关在哪里呢?这才 引出了ADJTIMEX命令


首先简单介绍下LINUX下的时间。LINUX的时间分两个时间:一个叫RTC,也就是REAL TIME CLOCK,也可以叫做CMOS CLOCK或者硬件时间,这个时间是在系统CMOS中设置的时间,不管操作系统是否运行,机器是否通电,这个时间都在往前走。这个时钟是通过机器主板上的纽扣电池进行供电的(当然,把电池抠下来,这个时钟就不走了)。另一个叫系统时间,也就是内核时间或者叫软时间。这个时间是通过操作系统的软件中断调用来计算出的时间。系统时间是系统启动的时候调用HWCLOCK -HCTOSYS来生成操作系统启动时的时间的。

系统启动后,则根据CPU的频率来计算出多少频率后,系统时间该走一个TICK。在系统启动的日志中有如下信息:
Jan 5 10:10:06 localhost kernel: time.c: Using 14.318180 MHz WALL HPET GTOD HPET/TSC timer.
Jan 5 10:10:06 localhost kernel: time.c: Detected 1596.040 MHz processor.
这个应该就是因为系统CPU的频率是1596MHZ,而这里的TICK设置为每秒100个(这个定义在param.h文件中,不同版本存放的位置会有所不同),所以计算出来每14.318180 MHz的时候,操作系统计一个TICK。注意这里是有误差的。(这一段内容太深了,要设计到时间的计算以及LINUX中的时间实现方式,所以这一段是我蒙的)

有时候在系统后台日志中会发现warning: many lost ticks类似的报警,这就是说因为某些原因,导致操作系统的时钟丢失了很多TICK,也就是在某些时间点停顿了一下,对系统的影响首先就是时间不准了,其次可能会影响到某些跟时间大小密切相关的应用程序。可以参考:http://zhang41082.itpub.net/post/7167/467811

绕了半天,回到正题,来看看ADJTIMEX命令。首先看看-P的输出:
mode: 0
offset: 0
frequency: 0
maxerror: 3664912
esterror: 16
status: 16
time_constant: 0
precision: 1
tolerance: 33554432
tick: 10002
raw time: 1262680695s 929944us = 1262680695.929944
return value = 1
返回的信息是TIMER相关的一堆变量的当前值,这堆变量的定义和说明在timex.h中。其中的STATUS字段就表示了是否把系统时间定时更新到RTC,并且定义了更新的方式:
For Linux 2.0 kernels, the value is a sum of these:
1 PLL updates enabled
2 PPS freq discipline enabled
4 PPS time discipline enabled
8 frequency-lock mode enabled
16 inserting leap second
32 deleting leap second
64 clock unsynchronized
128 holding frequency
256 PPS signal present
512 PPS signal jitter exceeded
1024 PPS signal wander exceeded
2048 PPS signal calibration error
4096 clock hardware fault
因为对内核一点都没搞过,也搞不清楚其中的PLL、PPS这些定义啥意思,所以这里也不深挖这些同步的方式了,只要记得64表示是不同步的就OK了(其中的PLL表示phase-lock loop,中文怎么翻译应该大概就是渐进式的同步。比如系统时间差了10分钟,那不要一次同步完,而是一次同步一点,这个一点的大小在上面的输出的time_constant字段来表现,这个值可以通过ADJTIMEX -T N来设置)。 

其中的TICK就表示了RTC和系统时间之间的对比,比如系统时间总是比RTC快,那么可以通过ADJTIMEX -C来进行校验,输出如下:
--- current --- -- suggested --
cmos time system-cmos error_ppm tick freq tick freq
1262638224 43202.371689
1262638234 43202.368838 -285.1 10000 0
1262638244 43202.365995 -284.3 10000 0 10002 5524050
1262638254 43202.363148 -284.7 10000 0 10002 5550612
1262638264 43202.360306 -284.2 10000 0 10002 5519362
1262638274 43202.357461 -284.5 10000 0 10002 5536550
1262638284 43202.354617 -284.4 10000 0 10002 5530300
1262638294 43202.351776 -284.1 10000 0 10002 5511550
这个就表示系统的TICK跟RTC之间是有差异的,建议调整TICK为10002,那么这个可以通过ADJTIMEX -t N来进行调整,TICK每增加1,那么就是增加了100 ppm,大概就是8.64秒/天。那么看看调整后的输出:
--- current --- -- suggested --
cmos time system-cmos error_ppm tick freq tick freq
1262638602 43202.268957
1262638612 43202.268114 -84.3 10002 0
1262638622 43202.267270 -84.4 10002 0 10002 5532812
1262638632 43202.266428 -84.2 10002 0 10002 5515625
1262638642 43202.265588 -84.0 10002 0 10002 5506250
1262638652 43202.264747 -84.1 10002 0 10002 5510937
1262638662 43202.263905 -84.3 10002 0 10002 5523437
1262638672 43202.263064 -84.0 10002 0 10002 5506250
这说明已经比较精确了。

上面输出中还有一个RAW TIME,这个就是系统从1970年1月1日到现在一共走了多少秒,系统时间其实就是通过这么多的秒换算出来的。

设置系统时间是否同步以及同步的方式,可以通过ADJTIMEX -S N的命令来设置,其中N就是上面STATUS字段对应的那对数值。

而且ADJTIMEX还提供了其他的参数,不一一介绍了。



测试中发现,如果使用NTPDATE后直接REBOOT机器,那系统时间是会同步到RTC的,估计是REBOOT的时候自动做了一次同步;但是如果NTPDATE后直接拔机器电源,然后再起来的时候,发现系统时间是不会同步到RTC上去的。那么在做时间同步的时候,NTPUPDATE完了之后,可以使用HWCLOCK -W来把系统时间写到RTC时间上去来防止掉电时候发生时间不同步的问题;也可以写个跟时间服务器同步的脚本添加到启动文件中,让系统一起来就去同步一次。


引用:http://blog.itpub.net/post/7167/495601
posted on 2013-11-13 11:33 回忆之城 阅读(1022) 评论(0)  编辑 收藏 引用
只有注册用户登录后才能发表评论。