Linux时钟与时间初始流程
触发其他CPU启动
clocksource发生切换后
tick_periodic()函数中会感知
start_kernel
timekeeping_init()
rest_init()
time_init()
late_time_init()
实际上调用x86_late_time_init()
kernel_init()
if (!hpet_enable())
setup_pit_timer();
late_time_init = x86_late_time_init
从persistent_clock设备读取时间,初始化timekeeper
时钟源指向clocksource_jiffies,基于从persistent_clock所读取的
时间设置墙上时间
tsc_init()
会通过cpuid指令获取cpu freq和tsc freq
setup_default_timer_irq()
kernel_init_freeable()
smp_prepare_cpus()
clockevents_config_and_register(&i8253_clocevent)
x86_init.timers.setup_percpu_clockdev()
实际上调用setup_boot_APIC_clock()
clockevents_register_device(lapic_devents)
smp_init()
for_each_present_cpu(cpu)
cpu_up(cpu)
__cpu_up()
实际上调用native_cpu_up()
do_boot_cpu(cpu)
start_secondary()
x86_cpuinit.setup_percpu_clockev();
实际为 setup_secondary_APIC_clock
setup_APIC_timer()
clockevents_register_device(lapic_devents)
do_basic_setup()
do_initcalls()
for (level = 0; level < ARRAY_SIZE(initcall_levels) - 1; level++)
do_initcall_level(level);
init_tsc_clocksource()
若tsc为reliable(即cpu进入C3 state时不会停止)
则直接注册(clock_source_register(tsc_clocksource))
否则在delay work中进行修正,修正后再注册
对于CONTINUOUS的clocksource,可以用作HRES时间,
timekeeping机制选用此类clocksource后,tick device可以
切换为NOHZ模式(根据需要切换为LOWRES或者HIRES)
setup_arch(&command_line)
kvmclock_init()
tick_periodic()
由periodic模式切换为ONESHOT模式
Created With
MindMaster