一、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 2022 10:48:18 PM CST -0.598781 seconds
[root@k3master ~]# hwclock -s
[root@k3master ~]# date
Mon Mar 7 22:48:55 CST 2022
//把当前的系统时间设置到RTC中
[root@k3master ~]# date
Mon Mar 7 22:52:20 CST 2022
[root@k3master ~]# hwclock -w
[root@k3master ~]# hwclock -r
Mon 07 Mar 2022 10: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

时间篇之linux系统时间和RTC时间的更多相关文章

  1. Linux入门教程:如何检查Linux系统的最后重启时间

    问题: 是否有一个命令可以快速地检查系统已经运行了多久? 也就是我怎么知道Linux系统最后的重启时间? 有许多方法来查询系统最后的重启时间. 方法一 第一种方法是使用last命令. $ last r ...

  2. Linux系统时间与RTC时间【转】

    http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=3637782 Linux的RTC驱动相对还是比较简单的,可以将它作为一个普通的字符 ...

  3. Linux系统的时区和时间调整

     linux调整系统时区: 1)tzselect命令 找到相应的时区文件/usr/share/zoneinfo/Asia/Shanghai,用这个文件替换当前的/etc/localtime文件. 或者 ...

  4. Linux系统下的单调时间函数

    欢迎转载,转载请注明出处:http://forever.blog.chinaunix.net 一.编写linux下应用程序的时候,有时候会用到高精度相对时间的概念,比如间隔100ms.那么应该使用哪个 ...

  5. 修改linux系统时间、rtc时间以及时间同步

    修改linux的系统时间用date -s [MMDDhhmm[[CC]YY][.ss]] 但是系统重启就会从新和硬件时钟同步. 要想永久修改系统时间,就需要如下命令:hwclock hwclock - ...

  6. linux 系统文件类型、系统安装时间、系统启动时间、系统运行时间、设置及显示时间、系统时间和硬件时间

    系统文件类型: 1) $mout 2) df -l:仅列出本地文件系统:-h (--human-readable):-T:文件系统类型 $df -lhf 3) file -s (--special-f ...

  7. Linux的硬件时间、校正Linux系统时间及系统时间调用流程

    第一部分: 一)概述: 事实上在Linux中有两个时钟系统,分别是系统时间和硬件时间 UTC是协调世界时(Universal Time Coordinated)英文缩写,它比北京时间早8个小时.   ...

  8. Linux下RTC时间的读写分析【转】

    本文转载自:http://blog.csdn.net/little_walt/article/details/52880840 Linux系统下包含两个时间:系统时间和RTC时间. 系统时间:是由主芯 ...

  9. 【linux 命令】:查看系统开机,关机时间【转载】

    转载原文:http://www.cnblogs.com/kerrycode/p/3759395.html 看Linux开机关机时间的方法(非常全面) 1: who 命令查看 who -b 查看最后一次 ...

随机推荐

  1. Net中委托之一

    1.委托的用法 委托是一种特殊的类型 a. 委托可以类外定义,也可以在类里面定义 b. 委托的操作步骤 1.委托的声明 2.委托的实例化 3.委托的调用 2.委托实例 amespace MyDeleg ...

  2. 最长公共子串(DP)

    DP基础_最长公共子串 Description 两个序列的最长公共子串,这个子串要求在序列中是连续的.如:"bab"和"caba" (可以看出来最长公共子串是& ...

  3. Three.js 火焰效果实现艾尔登法环动态logo 🔥

    声明:本文涉及图文和模型素材仅用于个人学习.研究和欣赏,请勿二次修改.非法传播.转载.出版.商用.及进行其他获利行为. 背景 <艾尔登法环>是最近比较火的一款游戏,观察可以发现它的 Log ...

  4. 一致性 hash 环

    一致性 hash 环 最近做项目 做了一个分发器 ,需要 根据请求携带的参数 把请求分发到 不同的服务器上面,最终我选择使用 一致性hash 环 来实现 ,本篇 就主要讲解一下 一致性hash环 它的 ...

  5. Betaflight Configurator开源仓库说明-中文版

    Betaflight Configurator Betaflight Configurator是Betaflight飞行控制系统的跨平台配置工具. 它在Google Chrome中作为应用程序运行,允 ...

  6. mysql覆盖索引与回表

    mysql覆盖索引与回表 Harri2012关注 62019.07.28 11:14:15字数 1,292阅读 77,322 select id,name where name='shenjian' ...

  7. 什么是root帐户?

    root帐户就像一个系统管理员帐户,允许你完全控制系统.你可以在此处创建和维护用户帐户,为每个帐户分配不同的权限.每次安装Linux时都是默认帐户.

  8. vue3.0的更新和defineProperty优化?

    放弃 Object.defineProperty ,使用更快的原生 Proxy (访问对象拦截器, 也成代理器) 提速, 降低内存使用, Tree-shaking更友好 支持IE11等 使用Types ...

  9. spring cloud 和dubbo区别?

    1.服务调用方式 dubbo是RPC springcloud Rest Api2.注册中心,dubbo 是zookeeper springcloud是eureka,也可以是zookeeper3.服务网 ...

  10. 使用过 Redis 做异步队列么,你是怎么用的?

    答:一般使用 list 结构作为队列,rpush 生产消息,lpop 消费消息.当 lpop 没有 消息的时候,要适当 sleep 一会再重试. 如果对方追问可不可以不用 sleep 呢? list ...