第1节 Linux时间系统
推荐给好友
打印
加入收藏
更新于2009-06-14 08:06:04

5.1 Linux时间系统

计算机是以严格精确的时间进行数值运算和和数据处理的,最基本的时间单元是时钟周期,例如取指令、执行指令、存取内存等,但是我们不讨论这些纯硬件的东西,这里要讨论的是操作系统建立的时间系统,这个时间系统是整个操作系统活动的动力。

时间系统是计算机系统非常重要的组成部分,特别是对于Unix类分时系统尤为重要。时间系统通常又被简称为时钟,它的主要任务是维持系统时间并且防止某个进程独占CPU及其他资源,也就是驱动进程的调度。本节将详细讲述时钟的来源、在Linux中的实现及其重要作用,使读者消除对时钟的神秘感。

5.1.1 时钟硬件

大部分PC机中有两个时钟源,他们分别叫做RTC和OS(操作系统)时钟。RTC(Real Time Clock,实时时钟)也叫做CMOS时钟,它是PC主机板上的一块芯片(或者叫做时钟电路),它靠电池供电,即使系统断电,也可以维持日期和时间。由于它独立于操作系统,所以也被称为硬件时钟,它为整个计算机提供一个计时标准,是最原始最底层的时钟数据。

Linux只用RTC来获得时间和日期;然而,通过作用于/dev/rtc设备文件,也允许进程对RTC编程。内核通过0x70和0x71 I/O端口存取RTC。通过执行/sbin/clock系统程序(它直接作用于这两个I/O端口),系统管理员可以配置时钟。

OS时钟产生于PC主板上的定时/计数芯片,由操作系统控制这个芯片的工作,OS时钟的基本单位就是该芯片的计数周期。在开机时操作系统取得RTC中的时间数据来初始化OS时钟,然后通过计数芯片的向下计数形成了OS时钟,所以OS时钟并不是本质意义上的时钟,它更应该被称为一个计数器。OS时钟只在开机时才有效,而且完全由操作系统控制,所以也被称为软时钟或系统时钟。下面我们重点描述OS时钟的产生。

OS时钟所用的定时/计数芯片最典型的是8253/8254可编程定时/计数芯片,其硬件结构及工作原理在这里不详细讲述,只简单地描述它是怎样维持OS时钟的。OS时钟的物理产生示意图如图5.1 所示:

图 5.1 8253/8254工作示意图

可编程定时/计数器总体上由两部分组成:计数硬件和通信寄存器。通信寄存器包含有控制寄存器、状态寄存器、计数初始值寄存器(16位)、计数输出寄存器等。通信寄存器在计数硬件和操作系统之间建立联系,用于二者之间的通信,操作系统通过这些寄存器控制计数硬件的工作方式、读取计数硬件的当前状态和计数值等信息。在Linux内核初始化时,内核写入控制字和计数初值,这样计数硬件就会按照一定的计数方式对晶振产生的输入脉冲信号(5~100MHz的频率)进行计数操作:计数器从计数初值开始,每收到一次脉冲信号,计数器减1,当计数器减至0时,就会输出高点平或低电平,然后,如果计数为循环方式(通常为循环计数方式),则重新从计数初值进行计数,从而产生如图所示的输出脉冲信号(当然不一定是很规整的方波)。这个输出脉冲是OS时钟的硬件基础,之所以这么说,是因为这个输出脉冲将接到中断控制器上 ,产生中断信号,触发后面要讲的时钟中断,由时钟中断服务程序维持OS时钟的正常工作,所谓维持,其实就是简单的加1及细微的修正操作。这就是OS时钟产生的来源。

5.1.2 时钟运作机制

不同的操作系统,RTC和OS时钟的关系是不同的。RTC和OS时钟之间的关系通常也被称作操作系统的时钟运作机制。

一般来说,RTC是OS时钟的时间基准,操作系统通过读取RTC来初始化OS时钟,此后二者保持同步运行,共同维持着系统时间。保持同步运行是什么意思呢?就是指操作系统运行过程中,每隔一个固定时间会刷新或校正RTC中的信息。

Linux中的时钟运作机制如图3.3所示。OS时钟和RTC之间要通过BIOS的连接,是因为传统PC机的BIOS中固化有对RTC进行有关操作的函数,例如INT 1AH等中断服务程序,通常操作系统也直接利用这些函数对RTC进行操作,例如从RTC中读出有关数据对OS时钟初始化、对RTC进行更新等等。实际上,不通过BIOS而直接对RTC的有关端口进行操作也是可以的。Linux中在内核初始化完成后就完全抛弃了BIOS中的程序。

图5.2 时钟运作机制

我们可以看到,RTC处于最底层,提供最原始的时钟数据。OS时钟建立在RTC之上,初始化完成后将完全由操作系统控制,和RTC脱离关系。操作系统通过OS时钟提供给应用程序所有和时间有关的服务。因为OS时钟完全是一个软件问题,其所能表达的时间由操作系统的设计者决定,将OS时钟定义为整型还是长整型或者大的超乎想象都是设计者的事。

5.1.3 Linux时间基准

以上我们了解了RTC(实时时钟、硬件时钟)和OS时钟(系统时钟、软时钟)。下面我们具体描述OS时钟。

我们知道,OS时钟是由可编程定时/计数器产生的输出脉冲触发中断而产生的。输出脉冲的周期叫做一个“时钟滴答”,有些书上也把它叫做“时标”。计算机中的时间是以时钟滴答为单位的,每一次时钟滴答,系统时间就会加1。操作系统根据当前时钟滴答的数目就可以得到以秒或毫秒等为单位的其他时间格式。

不同的操作系统采用不同的“时间基准”。定义“时间基准”的目的是为了简化计算,这样计算机中的时间只要表示为从这个时间基准开始的时钟滴答数就可以了。“时间基准是由操作系统的设计者规定的。例如DOS的时间基准是1980年1月1日,Unix和Minux的时间基准是1970年1月1日上午12点,Linux的时间基准是1970年1月1日凌晨0点。

5.1.4 Linux的时间系统

通过上面的时钟运作机制,我们知道了OS时钟在Linux中的重要地位。OS时钟记录的时间也就是通常所说的系统时间。系统时间是以“时钟滴答”为单位的,而时钟中断的频率决定了一个时钟滴答的长短,例如每秒有100次时钟中断,那么一个时钟滴答的就是10毫秒(记为10ms),相应地,系统时间就会每10ms增1。不同的操作系统对时钟滴答的定义是不同的,例如DOS的时钟滴答滴答为1/18.2s,Minix的时钟滴答为1/60s等等。

Linux中用全局变量jiffies表示系统自启动以来的时钟滴答数目。jiffy是“瞬间、一会儿”的意思,和“时钟滴答”表达的是同一个意思。jiffies是jiffy的复数形式,在/kernel/time.c中定义如下:

unsigned long volatile jiffies

在jiffies基础上,Linux提供了如下适合人们习惯的时间格式,在/include/linux/time.h中定义如下:

struct timespec { /* 这是精度很高的表示*/
long tv_sec; /* 秒 (second) */
long tv_nsec; /* 纳秒:十亿分之一秒( nanosecond)*/
};
struct timeval { /* 普通精度 */
int tv_sec; /* 秒 */
int tv_usec; /* 微秒:百万分之一秒(microsecond)*/
};
struct timezone { /* 时区 */
int tz_minuteswest; /* 格林尼治时间往西方的时差 */
int tz_dsttime; /* 时间修正方式 */
};

tv_sec表示秒(second),tv_usec表示微秒(microsecond,百万分之一秒即10-6秒),tv_nsec表示纳秒(nanosecond,十亿分之一秒即10-9秒)。定义tb_usec和tv_nsec的目的是为了适用不同的使用要求,不同的场合根据对时间精度的要求选用这两种表示。

另外,Linux还定义了用于表示更加符合大众习惯的时间表示:年、月、日。但是万变不离其宗,所有的时间应用都是建立在jiffies基础之上的,我们将详细讨论jiffies的产生和其作用。 简而言之,jiffies产生于时钟中断!

 

上一节   下一节

相关链接


 
关于我们 | 诚邀加盟 | 客户服务 | 相关法律 | 网站地图 | 友情链接 | 服务信箱:service@eefocus.com
© 2006 与非门科技信息咨询(北京)有限公司 All Rights Reserved.