Linux内核状态 system_state
基于msm-5.4
一、定义
/* 用于 system_state 的值,状态的顺序不得更改,代码检查时会用 <、<=、>、>= STATE */ extern enum system_states { //include/linux/kernel.h SYSTEM_BOOTING, //0, 最初没有赋值的时候的默认值 SYSTEM_SCHEDULING, SYSTEM_RUNNING, SYSTEM_HALT, SYSTEM_POWER_OFF, SYSTEM_RESTART, SYSTEM_SUSPEND, } system_state; enum system_states system_state __read_mostly; //init/main.c
二、赋值路径
1. 内核启动
rest_init //init/main.c kernel_thread(kernel_init, NULL, CLONE_FS); kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES); system_state = SYSTEM_SCHEDULING; complete(&kthreadd_done); //唤醒init进程 kernel_init //init/main.c system_state = SYSTEM_RUNNING;
在唤醒init进程时,将系统状态 system_state 设置为 SYSTEM_SCHEDULING.
这里做这个设置原文有个注释:启用 might_sleep() 和 smp_processor_id() 检查。它们不能提前启用,因为使用 CONFIG_PREEMPTION=y kernel_thread() 会触发 might_sleep()。
init线程创建后将 system_state 设置为 SYSTEM_RUNNING。
2. reboot系统重启
reboot(cmd) //reboot.c 系统调用 cmd=CMD_RESTART 等 deferred_cad //reboot.c 传参NULL __orderly_reboot //reboot.c 传参NULL power_down //若hibernation_mode=HIBERNATION_REBOOT,则调用,传参NULL, 默认没使能CONFIG_HIBERNATION不执行 kernel_restart(cmd) //reboot.c cmd=edl/recovery/bootloader/soc等 kernel_kexec //kexec_core.c kernel_restart_prepare //reboot.c blocking_notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd); system_state = SYSTEM_RESTART; reboot() //reboot.c 系统调用 cmd=CMD_HALT 时调用 kernel_halt //reboot.c 传参 SYSTEM_HALT reboot() //reboot.c 系统调用 cmd=POWER_OFF 时调用 kernel_power_off //reboot.c 传参 SYSTEM_POWER_OFF kernel_shutdown_prepare(enum system_states state) //reboot.c blocking_notifier_call_chain(&reboot_notifier_list, state, NULL); system_state = state;
在系统重启,发出通知后,将 system_state 赋值为 SYSTEM_RESTART。在系统shutdown,发出通知后,将 system_state 赋值为设置的 state 值。
3. tick的freeze/unfreeze
tick_freeze //tick-common.c system_state = SYSTEM_SUSPEND; tick_unfreeze system_state = SYSTEM_RUNNING;
4. 系统休眠唤醒
suspend_enter system_state = SYSTEM_SUSPEND; syscore_suspend system_state = SYSTEM_RUNNING;
三、使用案例
1. 内存初始化时判断是内核启动路径还是hotplug路径
void __ref build_all_zonelists(pg_data_t *pgdat) //page_alloc.c { if (system_state == SYSTEM_BOOTING) { build_all_zonelists_init(); } else { __build_all_zonelists(pgdat); //memory_hotplug.c 中应该会走这个路径 } }
posted on 2024-08-17 14:52 Hello-World3 阅读(37) 评论(0) 编辑 收藏 举报