`
totoxian
  • 浏览: 1030770 次
  • 性别: Icon_minigender_2
  • 来自: 西安
文章分类
社区版块
存档分类
最新评论

关于linux内核中使用的时钟

 
阅读更多

linux内核里面用了很多的时钟,其实这些时钟的用处无外乎就几种:1.作为心跳,中断cpu;2.使得用户可以获取当前时间;3.实时测量;4.定时 服务。知道了使用目的后,我们来看看到底有哪些时钟供我们选择使用:关于这些时钟的概念,网上已经存在不少文章了,为了不重复(浪费互联网空间),咱就先来个引用。
/*摘录开始:http://blog.chinaunix.net/u1/55599/showart.php?id=1179259
1):实时时钟(RTC)
该时钟独立于CPU和其它芯片.即使PC断电,该时钟还是继续运行.该计时由一块单独的芯片处理,并把时钟值存放CMOS.该时间可参在IRQ8上周期性的产生时间信号.频率在2Hz ~ 8192Hz之间.但在linux中,只是用RTC来获取当前时间.
2):时间戳计时器(TSC)
CPU附带了一个64位的时间戳寄存器,当时钟信号到来的时候.该寄存器内容自动加1
3):可编程中断定时器(PIC)
该设备可以周期性的发送一个时间中断信号.发送中断信号的间隔可以对其进行编程控制.在linux系统中,该中断时间间隔由HZ表示.这个时间间隔也被称为一个节拍(tick).
在 ./include/asm-i386/param.h 定义
10#ifndef HZ
11#define HZ 100
12#endif
4):CPU本地定时器
在处理器的本地APIC还提供了另外的一定定时设备.CPU本地定时器也可以单次或者周期性的产生中断信号.与上次描述的PIC相比.它有以下几点的区别:
APIC本地计时器是32位.而PIC是16位.由此APIC本地计时器可以提供更低频率的中断信号
本地APIC只把中断信号发送给本地CPU.而PIC发送的中断信号任何CPU都可以处理
APIC定时器是基于总线时钟信号的.而PIC有自己的内部时钟振荡器
5):高精度计时器(HPET)
在linux2.6中增加了对HPET的支持.HPET是一种由intel开发的新型定时芯片.该设备有一组寄时器,每个寄时器对应有自己的时钟信号,时钟信号到来的时候就会自动加1.一个 hpet包括了一个固定频率的数值增加的计数器以及3到32个独立的计时器,这每一个计时器有包涵了一个比较器和一个寄存器(保存一个数值,表示触发中断时机)。每一个比较器都比较计数器中的数值和寄存器中的数值,当这两个数值相等时,将产生一个中断
实际上,在intel多理器系统与单处理器系统还有所不同:
在单处理系统中.所有计时活动过由PIC产生的时钟中断信号触发的
在多处理系统中,所有普通活动是由PIC产生的中断触发.所有具体的CPU活动,都由本地APIC触发的.
*/摘录完毕
好了,上面对这么多种时钟的概念已经阐述的很清楚了,那么他们之间到底有何联系呢?幸运的是,在2.6.21内核以后,一切变得不言自明了,2.6.21以上内核将时钟框架进行了进一步的抽象整理,抽象出了两个概念:
struct clocksource :对硬件时钟设备的抽象,描述时钟源,强调静态事物,源头
struct clock_event_device :时钟的事件的抽象,描述硬件时钟中断发生时要执行的动作,强调在时钟源上面的动态方面。
这两个概念被抽象出来以后,我们就可以用面向对象的思路来分析了。仔细看看这两个概念,它们的偶合性极低,但是还是有联系的,比如如果你将 clock_event_device设置成one-shot,而clocksource确是一个精度及其低的时钟源,那么系统的响应将会相当慢,它们实 际上会影响到对方。
仔细研究一下上面的众多时钟,有的可以产生中断,有的仅仅是一个计数器,有的...,那么我们怎么读时钟源啊,不要急,每个clocksource都有一个回调函数用来读取时钟源当前值:

struct clocksource {

char *name;

struct list_head list;

int rating;

cycle_t (*read)(void);//这就是读取回调函数

cycle_t mask;

u32 mult;

u32 shift;

unsigned long flags;

cycle_t (*vread)(void);

void (*resume)(void);

...

/* timekeeping specific data, ignore */

cycle_t cycle_interval;

u64 xtime_interval;

/*

* Second part is written at each timer interrupt

* Keep it in a different cache line to dirty no

* more than one cache line.

*/

cycle_t cycle_last ____cacheline_aligned_in_smp;

u64 xtime_nsec;

...

};

仔细看看那个read回调函数的返回值,竟然是个cycle_t。内核的设计者简直就是神,cycle_t这个值没有和任何时间的概念关联,具体怎么关联就留给clock_event_device和具体的环境了,你可以通过两个cycle_t相减得到一个值,你也可以...那么现在看一个具体的:

static struct clocksource clocksource_pit = {

.name = "pit",

.rating = 110,

.read = pit_read,

.mask = CLOCKSOURCE_MASK(32),

.mult = 0,

.shift = 20,

};

这回明白了吗?clocksource最重要的就是随时我调用你的read函数,你能返回我一个cycle_t,告诉我当前时钟源的一个计数器的值就行了,至于我要这个值有什么用,你就别管了。实际上内核可以通过这个计数器的值计算很多东西。
像tsc时钟源,你指望它产生中断吗?那是不可能的,但是它却真的是一个时钟源,pit也是一个时钟源,但是他却可以产生中断,hpet也是一个,它不但 可以产生中断,还可以代替tsc,这岂不乱套了吗?产生中断的时钟怎么能和仅仅是个计数器的时钟是并列关系,一起注册并竞争全局clocksource 呢?如果是一个tsc竞争取得胜利怎么办啊,谁来产生中断呢?
如果谁有以上问题,那就是没有理解clocksource和clock_event_device 产生的初衷,它们哥俩的出现仅仅是为了协作管理时钟,为了使内核可以提供更加灵活的策略同时为了更加方便的扩展各个不同平台的时钟框架。如果tsc注册并 取得全局clocksource权,那么也是没有关系的,产生中断的时钟不管你的软件怎么样,总会存在的,若不存在,你的计算机根本起不来,那就是出大问题了,仔细看看下面的代码:

void __init time_init_hook(void)

{

irq0.mask = cpumask_of_cpu(0);

setup_irq(0, &irq0);

}

在 一切就绪后(比如,tsc就是全局clocksource了),上述函数被调用,开始了心跳处理,也就是中断处理,而在这之前,时钟中断也是有的,只不过没有处理函数,进去中断马上就出来了,现在全局的clocksource有了,全局的clock_event_device也有了,于是它们便开始了各司 其职完成时钟处理。
tsc仅仅是一个计数器,hpet可以产生中断同时有很多计数器,pit可以产生中断也有计数器,可以产生中断的产生中断,有计数器的开始计数,这些在你 按下计算机电源的那一瞬间就开始了,而不是等你在软件里面设置了一些东西才开始的,当然你完全可以用软件控制它们,一个很好的例子就是one-shot模 式,这个就不说了,看代码吧

分享到:
评论

相关推荐

    linux内核的时钟中断详解

    linux内核的时钟中断详解,介绍内核时钟中断知识

    Linux内核采用双频时钟的分析及检验.pdf

    Linux内核采用双频时钟的分析及检验.pdf

    Linux内核源代码情景分析 (上下册 高清非扫描 )

    1.4 Linux内核源代码中的C语言代码 1.5 Linux内核源代码中的汇编语言代码 第2章 存储管理 2.1 Linux内存管理的基本框架 2.2 地址映射的全过程 2.3 几个重要的数据结构和函数 2.4 越界访问 2.5 用户堆栈的扩展 2.6 ...

    深入分析Linux内核源码.chm

    1.3走进Linux内核 1.4 分析Linux内核的意义 1.5 Linux内核结构 1.6 Linux内核源代码 1.7 Linux内核源代码分析工具 第二章 Linux运行的硬件基础 2.1 i386的寄存器 2.2 内存地址 2.3 段机制和描述符 2.4 分页机制 2.5 ...

    Linux内核时钟.doc

    重邮Linux内核时钟的实验报告,仅供参考,切勿照搬!

    linux2.6.1内核源码注释

    包含LINUX内核同步、信号、内存、调度、文件系统、网络系统、时钟等部分的源码注释。前后历时三年,算是干货。

    Linux2.6内核标准教程(共计8-- 第1个)

    《Linux2.6内核标准教程》适合Linux内核爱好者、Linux驱动开发人员、Linux系统工程师参考使用,也可以作为计算机及相关专业学生深入学 习操作系统的参考书。 引用: 目录 第1章 Linux内核学习基础 1 1.1 为什么...

    包含LINUX内核同步、信号、内存、调度、文件系统、网络系统、时钟等部分的源码注释

    包含LINUX内核同步、信号、内存、调度、文件系统、网络系统、时钟等部分的源码注释。包含LINUX内核同步、信号、内存、调度、文件系统、网络系统、时钟等部分的源码注释。包含LINUX内核同步、信号、内存、调度、文件...

    Linux内核源代码导读-陈香兰-时钟和定时测量

    Linux内核源代码导读-陈香兰-中国科学技术大学-时钟和定时测量

    Linux操作系统内核的时钟中断机制.pdf

    Linux操作系统内核的时钟中断机制.pdf

    Linux内核 内容很全

    处理器 115 10.1 X86 115 10.2 ARM 115 10.3 Alpha AXP处理器 115 第11章 Linux内核源代码 117 11.1 怎样得到Linux内核源码 117 11.2 内核源码的编排 117 11.3 从何处看起 118 第12章 Linux...

    Linux操作系统内核的时钟中断机制

    本文主要从内核实现的角度分析了Linux 2.4.0内核的时钟中断、内核对时间的表示等。

    边干边学——LINUX内核指导

    第3章 内核时钟 3. 1 关于时钟和定时器 3. 2 Linux系统时钟 3. 3 Linux系统定时器 3. 4 时钟命令介绍 3. 5 定时器的应用 第4章 内核模块 4. 1 概述 4. 2 模块实现机制 4. 3 实例 第5章 系统调用 5. 1 一个简单的例子...

    Linux2.6内核标准教程(共计8--第6个)

    《Linux2.6内核标准教程》适合Linux内核爱好者、Linux驱动开发人员、Linux系统工程师参考使用,也可以作为计算机及相关专业学生深入学 习操作系统的参考书。 引用: 目录 第1章 Linux内核学习基础 1 1.1 为什么...

    深入分析Linux内核源码

    1.5.1 Linux内核在整个操系统中的位置 1.5.2 Linux内核的作用 1.5.3 Linux内核的抽象结构 1.6 Linux内核源代码 1.6.1 多版本的内核源代码 1.6.2 Linux内核源代码的结构 1.6.3 从何处开始阅读源代码 ...

    Linux 内核 源码完全注释

    包含LINUX内核同步、信号、内存、调度、文件系统、网络系统、时钟等部分的源码注释。前后历时三年,算是干货。

    Linux2.6内核标准教程(共计8--第8个)

    《Linux2.6内核标准教程》适合Linux内核爱好者、Linux驱动开发人员、Linux系统工程师参考使用,也可以作为计算机及相关专业学生深入学 习操作系统的参考书。 引用: 目录 第1章 Linux内核学习基础 1 1.1 为什么...

    LINUX内核同步、信号、内存、调度、文件系统、网络系统

    包含LINUX内核同步、信号、内存、调度、文件系统、网络系统、时钟等部分的源码注释。包含LINUX内核同步、信号、内存、调度、文件系统、网络系统、时钟等部分的源码注释。包含LINUX内核同步、信号、内存、调度、文件...

    Linux2.6内核标准教程(共计8--第3个)

    《Linux2.6内核标准教程》适合Linux内核爱好者、Linux驱动开发人员、Linux系统工程师参考使用,也可以作为计算机及相关专业学生深入学 习操作系统的参考书。 引用: 目录 第1章 Linux内核学习基础 1 1.1 为什么...

    Linux2.6内核标准教程(共计8--第7个)

    《Linux2.6内核标准教程》适合Linux内核爱好者、Linux驱动开发人员、Linux系统工程师参考使用,也可以作为计算机及相关专业学生深入学 习操作系统的参考书。 引用: 目录 第1章 Linux内核学习基础 1 1.1 为什么...

Global site tag (gtag.js) - Google Analytics