Chinaunix首页 | 论坛 | 博客
  • 博客访问: 84308
  • 博文数量: 29
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 90
  • 用 户 组: 普通用户
  • 注册时间: 2013-08-07 19:35
文章分类
文章存档

2015年(11)

2014年(18)

我的朋友

分类: LINUX

2015-01-29 16:21:13

原文地址:时间管理的初始化 作者:crazytyt

----------------------------------------
硬件:PowerPC P1020MBG-PC,linux版本:2.6.35
----------------------------------------

1. PowerPC的时钟来自于TimeBase(TB)寄存器,此寄存器是64位,在uboot时被初始化,之后开始一直单调增加,增加的频率为CCB时钟/8, P1020的TB时钟为50M。可以通过函数get_cycles得到此计数值
2. Decrementer寄存器用来产生时间中断,驱动频率与TB相同,该寄存器与TB相反,是递减型计数器,到减到0时将产生中断,linux在中断处理函数中对此寄存器重新赋值。这是PowerPC的时间中断源。



3. linux存在两种时间系统:低精度与高精度,同时存在两种方式,即:连续与one-shot型。。one-shot可以停止周期性时钟,这是节能的必须条件,现在大多高端系统都支持高精度模式。
4. linux时钟初始化步骤:


tick_init: 注册一个内核通知链,处理函数为:tick_notify。当内核有新的tick设备变动时会处理一些通知消息,以告诉内核tick设备的变化。主要的消息有:
 29 /* Clock event notification values */
 30 enum clock_event_nofitiers {
 31     CLOCK_EVT_NOTIFY_ADD,
 32     CLOCK_EVT_NOTIFY_BROADCAST_ON,
 33     CLOCK_EVT_NOTIFY_BROADCAST_OFF,
 34     CLOCK_EVT_NOTIFY_BROADCAST_FORCE,
 35     CLOCK_EVT_NOTIFY_BROADCAST_ENTER,
 36     CLOCK_EVT_NOTIFY_BROADCAST_EXIT,
 37     CLOCK_EVT_NOTIFY_SUSPEND,
 38     CLOCK_EVT_NOTIFY_RESUME,
 39     CLOCK_EVT_NOTIFY_CPU_DYING,
 40     CLOCK_EVT_NOTIFY_CPU_DEAD,
 41 };
其中broadcast消息在PowerPC中不使用,只有X86和AMD使用。

init_timers: 该函数注册一个内核通知链,处理函数为:timer_cpu_notify。该通知链用来处理cpu状态变化信息。该函数还用函数:open_softirq(TIMER_SOFTIRQ, run_timer_softirq);开户了低精度模式的计时器软中断,该软中断的处理函数为:run_timer_softirq。

hrtimer_init:该函数注册一个内核通知链hrtimers_nb。作用与低精度类似,并通过open_softirq(HRTIMER_SOFTIRQ, run_hrtimer_softirq);打开高精度模式的软中断。
注意:如果CONFIG_HIGH_RES_TIMERS选项没打开,则此软中断不会打开,但无论此选项是否打开,高精度代码都存在于内核,只是不具有高精度的功能,而且有的函数实现为空。当CONFIG_HIGH_RES_TIMERS打开时,自动会选择one-shot模式。当为动态tick时也会自动选择one-shot模式。即:高精度模式以及动态tick的
实现都必须依赖于one-shot模式,而不能在period tick模式下工作。

timekeeping_init:


A read_persistent_clock.读取当前系统时钟,这是架构相关的函数,PPC没有实现此类函数,此结果为0
B
init_read_boot_clock:初始化启动时钟为0.
C
ntp_init:初始化与时间协议有关的变量。
D
clocksource_default_clock: 把初始时钟设为jiffies时钟。
E:
设置时钟源内部使用的一些常量
F
:设置xtime变量初值
G:
设置wall_to_monotonic初值。

time_init: 此函数被启动处理器调用,其它处理器直接使用些函数初始化的一些值。



A
ppc_md.calibrate_decr调用函数generic_calibrate_decr,获取TB时钟频率和处理器频率。此数据是从Uboot中设置到DTS中的,有了这两个值就可以进行其它的一些常设置了。
B
一些常量值设置,如:tb_ticks_per_jiffytb_ticks_per_sec等。
C
start_cpu_decrementer:使能时钟中断,此时系统总中断开关并没有打开,所以不会产生时钟中断。时钟源是jiffies.
D: clocksource_init:
注册TB时钟源,把TB时钟源加入到时钟源列表中,选择最优时钟源。选择时钟源时会对finished_booting变量进行判断,以避免每次加时钟源时都进行时钟选择。
E: init_decrementer_clockevent: 初始化并注册时钟事件设备。注册时会发出CLOCK_EVT_NOTIFY_ADD消息。tick_notify函数会处理此消息。对此消息的处理函数为:tick_check_new_device。该函数的流程图为:



init_jiffies_clocksource: 注册jiffies时钟设备源。

系统启动的最后在clocksource_done_booting函数中把finished_booting变量置为1,并进行最优时钟源的选择,在这里选择了TB,并替换了当前正在使用的jiffies时钟源。




阅读(1096) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~