时间篇之linux系统时间和RTC时间

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

时间篇之linux系统时间和RTC时间
⼀、linux系统下包含两个时间:系统时间(刚启动时读取的是rtc时间)和RTC时间。

⼀般情况下都会选择芯⽚上最⾼精度的定时器作为系统时间的定时基准,
以避免在系统运⾏较长时间后出现⼤的时间偏移。

特点是掉电后不保存。

所以⼀旦你重启机器后,那么系统需要重新从RTC上重新获取时间,保存到系统内核⽂件中。

RTC(real_time clock)驱动程序,可以在E:\linux内核\linux-2.6.0\linux-2.6.0\drivers\char\rtc.c中找到。

设备接⼝就是 /dev/rtc, 他负责跟rtc打交道,并读取rtc中维护的时间.
它是⼀个从系统定时器中独⽴出来的虚拟设备,⽤于设置系统时钟,提供报警器或周期性的定时器.
那么系统时间⼀直运⾏吗?显然在操作系统关闭或重启期间,服务器宕机期间,整个服务器的时间就依赖于RTC芯⽚。

从这我们看出linux系统时间和RTC时间是两套独⽴的计时体系,但它们之间⼜是相互依存的:
1)刚安装操作系统后,若在安装过程不设置系统时间,那么默认的系统时间就是从服务器的RTC芯⽚中获取当前的硬件时间;
2)在linux操作系统中,⼀旦修改系统时间后,⼜重启或关闭Linux系统,则OS通常会将系统时间更新到RTC;
3)在操作系统再次启动的时候,Linux OS则会再次从RTC中获取当前的时间。

服务器异常下电后,待操作系统重新启动后,发现系统时间发⽣了跳变?
其原因通常是:修改了操作系统时间,在服务器异常下电后,操作系统并未及时将修改后的时间更新到RTC,导致操作系统重新启动后,就会从RTC芯⽚中加载了之前“⽼”的时间,从⽽在操作系统层⾯体现为“时间跳变”
⼆、关于jiffies
⼀次中断时间间隔叫⼀个tick,即每个触发周期的时间叫做tick,
⼀秒内时钟中断的次数(每个时间间隔就是⼀次)等于Hz
hz别名就是tick rate(HZ)
linux系统查看hz:
[root@k3master ~]# cat /boot/config-`uname -r` | grep 'CONFIG_HZ='
CONFIG_HZ=1000
1hz就是每秒1000次中断
每次时钟中断处理程序即每发⽣⼀次tick都会增加jiffies该变量的值,
jiffies⼀秒内增加的值也就是Hz(频率),⽐如:linux下默认是 1000次时钟中断次数/秒
系统运⾏时间以秒为单位,换算⽅法等于jiffies/Hz。

jiffies是linux内核中的⼀个全局变量,记录内核节拍时间的数值,内核在开机启动的时候会读取RTC获取⼀个时间作为基准值,
这个基准时间对应⼀个jiffies,RTC时间,只在开机时候读取⼀次,时钟节拍的时间取决于操作系统的配置,
[root@k3master ~]# cat /boot/config-`uname -r` | grep 'CONFIG_HZ='
CONFIG_HZ=1000
内核中记录⽤HZ来记录和表⽰,1000hz对应就是1/hz,也就是1ms。

jiffies是内核中的⼀个全局变量,⽤来记录⾃系统启动⼀来产⽣的节拍数。

譬如,如果计算系统运⾏了多长时间,可以⽤
jiffies/tick rate 来计算。

三、jiffies内核源码
E:\linux内核\linux-2.6.0\linux-2.6.0\include\linux\jiffies.h
#ifndef _LINUX_JIFFIES_H
#define _LINUX_JIFFIES_H
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/seqlock.h>
#include <asm/system.h>
#include <asm/param.h> /* for HZ */
/*
* The 64-bit value is not volatile - you MUST NOT read it
* without holding read_lock_irq(&xtime_lock).
* get_jiffies_64() will do this for you as appropriate.
*/
extern u64 jiffies_64;
extern unsigned long volatile jiffies;
#if (BITS_PER_LONG < 64)
u64 get_jiffies_64(void);
#else
static inline u64 get_jiffies_64(void)
{
return (u64)jiffies;
}
#endif
/*
* These inlines deal with timer wrapping correctly. You are
* strongly encouraged to use them
* 1. Because people otherwise forget
* 2. Because if the timer wrap changes in future you won't have to
* alter your driver code.
*
* time_after(a,b) returns true if the time a is after time b.
*
* Do this with "<0" and ">=0" to only test the sign of the result. A
* good compiler would generate better code (and a really good compiler
* wouldn't care). Gcc is currently neither.
*/
#define time_after(a,b) \
(typecheck(unsigned long, a) && \
typecheck(unsigned long, b) && \
((long)(b) - (long)(a) < 0))
#define time_before(a,b) time_after(b,a)
#define time_after_eq(a,b) \
(typecheck(unsigned long, a) && \
typecheck(unsigned long, b) && \
((long)(a) - (long)(b) >= 0))
#define time_before_eq(a,b) time_after_eq(b,a)
#endif
注意:date -s 2007-08-03 命令设置时间只会影响系统时间,不会设置RTC时间,
如果需要把当前系统时间同步设置到RTC中,需要额外调⽤hwclock命令。

四、我们在看看date相关源码
E:\linux内核\linux-2.6.0\linux-2.6.0\drivers\char\rtc.c
E:\linux内核\linux-2.6.0\linux-2.6.0\kernel\time.c
//开放给⽤户空间的
E:\linux内核\linux-2.6.0\linux-2.6.0\arch\x86_64\kernel\time.c
1、我们在看看rtc时钟驱动
linux-2.6.0\linux-2.6.0\drivers\char\rtc.c //的部分内容
* This driver allows use of the real time clock (built into
* nearly all computers) from user space. It exports the /dev/rtc
* interface supporting various ioctl() and also the
* /proc/driver/rtc pseudo-file for status information.
* The /dev/rtc interface will block on reads until an interrupt
* has been received. If a RTC interrupt has already happened,
* it will output an unsigned long and then block. The output value
* contains the interrupt status in the low byte and the number of
* interrupts since the last read in the remaining high bytes. The
* /dev/rtc interface can also be used with the select(2) call.
2、RTC时间:
是指系统中包含的RTC芯⽚内部所维护的时间。

RTC芯⽚都有电池+系统电源的双重供电机制,
在系统正常⼯作时由系统供电,在系统掉电后由电池进⾏供电。

因此系统电源掉电后RTC时间仍然能够正常运⾏。

从⼯作原理来说,RTC实时时钟芯⽚⼤多采⽤精度较⾼的晶体振荡器作为时钟源,对该时钟源脉冲进⾏计数。

主要靠晶振来保障准确性。

每次Linux系统启动后在启动过程中会检测和挂载RTC驱动,在挂载后会⾃动从RTC芯⽚中读取时间并设置到系统时间中去。

此后如果没有显式的通过命令去控制RTC的读写操作,系统将不会再从RTC中去获取或者同步设置时间。

hwclock 命令使⽤
//读取RTC时间(cmos时间)并设置到系统时间中去,hwclock -s 读取RTC时间(cmos时间)并设置到系统时间中去,我们看得很清楚了,时间上和我之前的系统时间不⼀样了[root@k3master ~]# hwclock -r
Mon 07 Mar 202210:48:18 PM CST -0.598781 seconds
[root@k3master ~]# hwclock -s
[root@k3master ~]# date
Mon Mar 722:48:55 CST 2022
//把当前的系统时间设置到RTC中
[root@k3master ~]# date
Mon Mar 722:52:20 CST 2022
[root@k3master ~]# hwclock -w
[root@k3master ~]# hwclock -r
Mon 07 Mar 202210:52:45 PM CST -0.614313 seconds
//如果你想启动时⾃动执⾏RTC时间同步到系统时间,可以把
hwclock -s加⼊到rc.local⽂件中。

3、RTC芯⽚举例:
4、看⼀下RTC芯⽚⼯作的驱动模型
E:\linux内核\linux-2.6.0\linux-2.6.0\kernel\time.c。

相关文档
最新文档