一、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. AT1219题解

    题意 设 \(a\) 的价值为 \(a \times cnt_a\)(\(cnt_a\) 为 \(a\) 在区间中出现的次数),求区间种某种元素,使得这种元素的价值最大. 因为设计出现元素的次数,所以 ...

  2. 关于dotnet动态生成controller的问题

    一些动态生成controller的问题 前言 最近在写包, 一开始封装了仓储Repository用于操作数据库, 然后为了快速开发一些业务简单的接口, 通过QueryController , Modi ...

  3. 内网代理工具--reGeorg

    一.简介 reGeorg是reDuh的继承者,利用了会话层的socks5协议,效率更高结合Proxifier使用 Proxifier是一款功能非常强大的socks5客户端,可以让不支持通过代理服务器工 ...

  4. MSF基本使用

    MSF 链接数据库 linux查找文件 find / -name dabase.yml 链接数据库 db_connect -y path/database.yml db_status 查询数据库链接状 ...

  5. 二叉树:前序遍历、中序遍历、后序遍历,BFS,DFS

    1.定义 一棵二叉树由根结点.左子树和右子树三部分组成,若规定 D.L.R 分别代表遍历根结点.遍历左子树.遍历右子树,则二叉树的遍历方式有 6 种:DLR.DRL.LDR.LRD.RDL.RLD.由 ...

  6. docker知识点扫盲

    最近给部门同事培训docker相关的东西,把我的培训内容总结下,发到博客园上,和大家一起分享.我的培训思路是这样的 首先讲解docker的安装.然后讲下docker的基本的原理,最后讲下docker的 ...

  7. InnoDB什么时候会锁表?

    我们常常说InnoDB是行锁,但是这里介绍一下它锁表的情况. InnoDB行锁是通过索引上的索引项来实现的,这一点MySQL与Oracle不同,后者是通过在数据中对相应数据行加锁来实现的.InnoDB ...

  8. springcloud断路器的作用?

    当一个服务调用另一个服务由于网络原因或自身原因出现问题,调用者就会等待被调用者的响应 当更多的服务请求到这些资源导致更多的请求等待,发生连锁效应(雪崩效应) 断路器有完全打开状态:一段时间内 达到一定 ...

  9. SpringBoot与SpringCloud的关系与区别?

    一.SpringBoot和SpringCloud简介 1.SpringBoot:是一个快速开发框架,通过用MAVEN依赖的继承方式,帮助我们快速整合第三方常用框架,完全采用注解化(使用注解方式启动Sp ...

  10. 用 Java 实现阻塞队列 ?

    参考 java 中的阻塞队列的内容吧,直接实现有点烦