----------------------------------------
硬件: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_jiffy,tb_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时钟源。
阅读(3871) | 评论(0) | 转发(1) |