Linux操作系统的时间架构离不开时间硬件的支持,而且时间精度根本上是由硬件决定的。 计算机中有几个时间芯片共同为操作系统提供支持。根据功能的不同,我们可以划分三类。
-
第一类是获取当前时间。计算机在断电后,并不能继续维护时间的变化。 此时需要另外一个不断电的设备来完成这个工作。当计算机启动后,能从这个设备初始化系统的时间。
-
第二类是tick数纪录设备。计算机初始化时间后,需要维护时间的变化。 此时需要一个高效的设备来纪录数据。同时这个设备决定了时间的精度。
-
第三类是定时器设备。由定时器来发起计算机的时间中断。
RTC
大部分的PC都有一个实时时钟,叫做RTC(real time clock),是PC实时时间的来源。
RTC独立于CPU和其他芯片,有独立的电源,可能是一粒锂电池,或者是可以充放电的超级电容。
当PC主电源中断时,RTC可以持续的记录时间。
RTC的时钟频率来源是石英晶体谐振器,可以提供32.768kHz(每秒215次)的频率。
RTC在IRQ8产生频率为2Hz到8192Hz的中断,如果PC用RTC做主要时钟源,精度偏低。
因此RTC主要作用是PC启动时,用来初始化系统的当前时间。
另外RTC是一个可编程硬件,在到达某个值时激活IRQ8,可以起到定时器的作用。
TSC
CPU有一个时间戳计数器寄存器(TSC),这个寄存器记录CPU自启动以来的时钟震荡数。 Linux利用这个寄存器提供更高精度的时间管理,精度随CPU的主频,可以达到纳秒级别。 Linux在系统初始化的时候通过统计约5微妙内CPU的时钟频率计算出CPU的时钟频率和一次tick的时间。 但是CPU低电运行时,主频动态的改变,此时会影响TSC的精度。 使用汇编命令rdtsc可以读取TCS的值。
ACPI Power Management Timer
ACPI PMT是基于ACPI的主板上的时钟设备,功能和TSC类似,用于记录时钟tick数。 PMT计数器基于自己的时钟信号,时钟频率大约是3.58MHz。 与TSC相比,PMT稳定,不会因系统低电运行影响时钟频率。 但是Linux获取PMT的数值需要访问一次IO。
PIT
IBM兼容的PC有一个时间管理设备,称为可编程间隔定时器(Programmable interval timer,PIT)。 PIT作用类是于闹钟,在一定的时间间隔后发起信号激活中断,中断是全局的,可以被任意一个CPU处理 PIT自己产生一定的频率,而且可以通过编程调整频率。
HPET
高精度事件定时器(HPET)是最新的定时器电路,集成在南桥芯片中,目标是取代PIT。 HPET提供一组可被kernel访问的硬件计时器,每个计时器都是基于各自的时钟信号。 这些硬件计时器,有32bit或者64bit,可以被映射到内存进行编程。 HPET的精度不低于100纳秒。
CPU Local Timer
CPU的每一个核都有自己的定时器,这个定时器只能给自己的CPU发送中断信号。 APIC’s timer的作用和PIT类似。 CPU Local Timer为32bits,可以产生更加低频的中断,但是基于bus的时钟信号,不够灵活。