linux reboot flow
来源:互联网 发布:破解qq悄悄话的软件 编辑:程序博客网 时间:2024/06/03 23:39
1, little machine_desc struture
1-1, first eye on arch/arm/include/asm/mach/arch.h
/*
* Machine type table - also only accessible during boot
*/
extern const struct machine_desc __arch_info_begin[], __arch_info_end[];
#define for_each_machine_desc(p) \
for (p = __arch_info_begin; p < __arch_info_end; p++)
#define DT_MACHINE_START(_name, _namestr) \
static const struct machine_desc __mach_desc_##_name \
__used \
__attribute__((__section__(".arch.info.init"))) = { \
.nr = ~0, \
.name = _namestr,
#endif
1-2, put machine_desc variable in arch.info.init section, whose begining is __arch_info_begin and ending is __arch_info_end. they defined at file arch/arm/kernel/vmlinux.lds.S
.init.arch.info : {
__arch_info_begin = .;
*(.arch.info.init)
__arch_info_end = .;
}
1-3, grep "DT_MACHINE_START" will help you find your board's related machine_desc, which will stored at section: arch.info.init, something like:
static const char *xxx_dt_match[] __initconst = {
"xxx,yyyy",
NULL
};
DT_MACHINE_START(xxx_DT, "Generic xxx (Flattened Device Tree)")
.smp = smp_ops(xxx_smp_ops),
.map_io = xxx_map_io,
.init_machine = xxx_init_mach,
.init_late = xxx_init_late,
.dt_compat = xxx_dt_match,
.restart = xxxx_xxx_restart,
MACHINE_END
2, who use the machine_desc variable
arch/arm/kernel/setup.c
start_kernel -> setup_arch -> setup_machine_fdt -> of_flat_dt_match_machine(mdesc_best, arch_get_next_mach)
static const void * __init arch_get_next_mach(const char *const **match)
{
static const struct machine_desc *mdesc = __arch_info_begin;
const struct machine_desc *m = mdesc;
if (m >= __arch_info_end)
return NULL;
mdesc++;
*match = m->dt_compat;
return m;
}
at last setup_machine_fdt will return a machine_desc variable at last which is your board used and assign arm_pm_restart at last by the follow statement:
if (mdesc->restart)
arm_pm_restart = mdesc->restart;
3, what flow reboot will go?
in kernel/reboot.c there is a function:
SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
void __user *, arg)
there is switch case:
switch (cmd) {
case LINUX_REBOOT_CMD_RESTART:
kernel_restart(NULL);
break;
void kernel_restart(char *cmd)
{
kernel_restart_prepare(cmd);
migrate_to_reboot_cpu();
syscore_shutdown();
if (!cmd)
pr_emerg("Restarting system\n");
else
pr_emerg("Restarting system with command '%s'\n", cmd);
kmsg_dump(KMSG_DUMP_RESTART);
machine_restart(cmd);
}
void kernel_restart_prepare(char *cmd)
{
blocking_notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd); //notify event of SYS_RESTART, others like "systemd" will capture it do some process.
system_state = SYSTEM_RESTART;
usermodehelper_disable();
pr_info("%s will call device shutdown\n", __func__);
device_shutdown();// device's shut down will be called
}
/**
* syscore_shutdown - Execute all the registered system core shutdown callbacks.
*/
void syscore_shutdown(void)
{
struct syscore_ops *ops;
mutex_lock(&syscore_ops_lock);
list_for_each_entry_reverse(ops, &syscore_ops_list, node)
if (ops->shutdown) {
if (initcall_debug)
pr_info("PM: Calling %pF\n", ops->shutdown);
ops->shutdown();// registered by register_syscore_ops
pr_info("%s\n", __func__);
}
mutex_unlock(&syscore_ops_lock);
}
/*
* Restart requires that the secondary CPUs stop performing any activity
* while the primary CPU resets the system. Systems with a single CPU can
* use soft_restart() as their machine descriptor's .restart hook, since that
* will cause the only available CPU to reset. Systems with multiple CPUs must
* provide a HW restart implementation, to ensure that all CPUs reset at once.
* This is required so that any code running after reset on the primary CPU
* doesn't have to co-ordinate with other CPUs to ensure they aren't still
* executing pre-reset code, and using RAM that the primary CPU's code wishes
* to use. Implementing such co-ordination would be essentially impossible.
*/
void machine_restart(char *cmd)
{
local_irq_disable();
smp_send_stop();
/* Flush the console to make sure all the relevant messages make it
* out to the console drivers */
arm_machine_flush_console();
if (arm_pm_restart) {
pr_info("%s arm_pm_restart\n", __func__);
arm_pm_restart(reboot_mode, cmd);
} else {
pr_info("%s do_kernel_restart\n", __func__);
do_kernel_restart(cmd);
}
/* Give a grace period for failure to restart of 1s */
mdelay(1000);
/* Whoops - the platform was unable to reboot. Tell the user! */
printk("Reboot failed -- System halted\n");
local_irq_disable();
while (1);
}
4, test result flow
[ 148.550000] systemd-shutdown[1]: All DM devices detached.
[ 148.560000] systemd-shutdown[1]: Rebooting.
[ 148.560000] reboot: SYSC_reboot LINUX_REBOOT_CMD_RESTART //SYSCALL_DEFINE4(reboot
[ 148.570000] reboot: kernel_restart_prepare will call device shutdown //kernel_restart_prepare
[ 148.580000] mmc mmc3:0001: shutdown //device_shutdown
[ 148.580000] mmcblk mmc1:1234: shutdown
[ 148.580000] xxx_tsc 10d80000.adc:tsc: shutdown
[ 148.710000] i2c i2c-2: shutdown
[ 148.710000] i2c i2c-1: shutdown
[ 148.710000] xxx_vdss sirfsoc_vdss.0: shutdown
[ 148.710000] pca954x 0-0070: shutdown
[ 148.720000] i2c 0-0045: shutdown
[ 148.720000] i2c 0-0049: shutdown
[ 148.720000] i2c 0-004b: shutdown
[ 148.730000] i2c 0-0038: shutdown
[ 148.730000] sx150x 0-0020: shutdown
[ 148.730000] i2c i2c-0: shutdown
[ 148.740000] pwm-backlight sirf-backlight: shutdown
[ 148.740000] pvrsrvkm 12000000.graphics: shutdown
[ 148.750000] xxx-wdt 10dc0000.timer: shutdown //device_shutdown
[ 148.750000] syscore_shutdown //syscore_shutdown
[ 148.750000] reboot: Restarting system
[ 148.760000] machine_restart arm_pm_restart // machine_restart
- linux reboot flow
- linux reboot flow
- linux的reboot实现
- linux reboot/复位 函数
- linux reboot/复位 函数
- linux的reboot实现
- linux系统调用reboot
- Linux reboot全过程
- linux reboot流程
- linux reboot 实现流程
- Linux重启命令reboot
- reboot
- Reboot
- reboot
- reboot```
- Linux boot flow
- linux start flow
- [linux]pm autosleep flow
- python aerospike client 实现CAS更新操作
- maven中snapshot快照库和release发布库的区别和作用
- 防外链
- float型数据在内存中的存储方式
- C++经典面试题
- linux reboot flow
- UART裸机驱动设计
- jstl-functions的用法
- JSP入门之自定义标签
- 360加固宝
- sleep和wait有什么区别
- sss
- ThinkPHP 跨控制器页面跳转 官方文档 未讲清楚
- netty5笔记-线程模型3-EventLoop