linux时钟机制(二)-时钟初始化


时钟初始化

内核初始化部分( start_kernel 函数)和时钟相关的过程主要有以下几个:

  1. tick_init()
  2. init_timers()
  3. hrtimers_init()
  4. time_init()

 tick_init 函数

函数 tick_init() 很简单,调用 clockevents_register_notifier 函数向 clockevents_chain 通知链注册元素: tick_notifier。这个元素的回调函数指明了当时钟事件设备信息发生变化(例如新加入一个时钟事件设备等等)时,应该执行的操作,该回调函数为 tick_notify 。

/kernel/time/tick-common.c 依赖 CONFIG_GENERIC_CLOCKEVENTS
/**
 * tick_init - initialize the tick control
 *
 * Register the notifier with the clockevents framework
 */
void __init tick_init(void)
{
	clockevents_register_notifier(&tick_notifier);
}

!CONFIG_GENERIC_CLOCKEVENTS 
static inline void tick_init(void) { }
//内核通知链技术
/**
 * clockevents_register_notifier - register a clock events change listener
 */
int clockevents_register_notifier(struct notifier_block *nb)
{
    unsigned long flags;
    int ret;

    raw_spin_lock_irqsave(&clockevents_lock, flags);
    ret = raw_notifier_chain_register(&clockevents_chain, nb);
    raw_spin_unlock_irqrestore(&clockevents_lock, flags);

    return ret;
}


 init_timers 函数

void __init init_timers(void)
{
    int err = timer_cpu_notify(&timers_nb, (unsigned long)CPU_UP_PREPARE, 
                                        (void *)(long)smp_processor_id());
    ……
    register_cpu_notifier(&timers_nb);
    open_softirq(TIMER_SOFTIRQ,run_timer_softirq, NULL);
}

代码解释:

  • 初始化本 CPU 上的软件时钟相关的数据结构,参见3.2节
  • 向 cpu_chain 通知链注册元素 timers_nb ,该元素的回调函数用于初始化指定 CPU 上的软件时钟相关的数据结构
  • 初始化时钟的软中断处理函数

2.3.3 time_init 函数

void __init time_init(void)
{
    ……
    init_tsc_clocksource();
    late_time_init = choose_time_init();
}

函数 init_tsc_clocksource 初始化 tsc 时钟源。choose_time_init 实际是函数 hpet_time_init ,其代码清单2-3

清单2-3 hpet_time_init 函数
void __init hpet_time_init(void)
{
    if (!hpet_enable())
        setup_pit_timer();

    setup_irq(0, &irq0);
}

函数 hpet_enable 检测系统是否可以使用 hpet 时钟,如果可以则初始化 hpet 时钟。否则初始化 pit 时钟。最后设置硬件时钟发生时的处理函数(参见2.4节)。

初始化硬件时钟这个过程主要包括以下两个过程(参见 hpet_enable 的实现):

  1. 初始化时钟源信息( struct clocksource 类型的变量),并将其添加到时钟源链表中,即 clocksource_list 链表(参见图2-1)。
  2. 初始化时钟事件设备信息( struct clock_event_device 类型的变量),并向通知链 clockevents_chain 发布通知:一个时钟事件设备要被添加到系统中。在通知(执行回调函数)结束后,该时钟事件设备被添加到时钟事件设备链表中,即 clockevent_devices 链表(参见图2-1)。有关通知链的内容参见2.2节。

需要注意的是在初始化时钟事件设备时,全局变量 global_clock_event 被赋予了相应的值。该变量保存着系统中当前正在使用的时钟事件设备(保存了系统当前使用的硬件时钟中断发生时,要执行的中断处理函数的指针)。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值