9

我想确认内核的panic()功能和其他功能一样kernel_halt()machine_halt()一旦触发,保证机器完全冻结。

那么,所有内核和用户进程都被冻结了吗?是否panic()可以被调度程序中断?中断处理程序仍然可以执行吗?

用例:如果出现严重错误,我需要确保硬件看门狗重置机器。为此,我需要确保没有其他线程/进程使看门狗保持活动状态。我需要触发系统完全停止。目前,在我的内核模块中,我只是调用panic()来冻结所有内容。

另外,用户空间halt命令可以保证冻结系统吗?

谢谢。

编辑:根据: http: //linux.die.net/man/2/reboot,我认为最好的方法是使用reboot(LINUX_REBOOT_CMD_HALT):“控制权交给 ROM 监视器,如果有的话”

4

1 回答 1

10

感谢您的上述评论。经过一番研究,我准备给自己一个更完整的答案,如下:

至少对于 x86 架构,这reboot(LINUX_REBOOT_CMD_HALT)是要走的路。这反过来又调用了系统调用reboot()(参见: http: //lxr.linux.no/linux+v3.6.6/kernel/sys.c#L433)。然后,对于LINUX_REBOOT_CMD_HALT标志(参见: http: //lxr.linux.no/linux+v3.6.6/kernel/sys.c#L480),系统调用调用kernel_halt()(在此处定义:http: //lxr.linux.no/ linux+v3.6.6/kernel/sys.c#L394)。该函数调用 syscore_shutdown() 来执行所有注册的系统核心关闭回调,显示“系统停止”消息,然后转储内核,最后,它调用machine_halt(),这是一个包装器native_machine_halt()(参见:http://lxr .linux.no/linux+v3.6.6/arch/x86/kernel/reboot.c#L680)。正是这个函数停止了其他 CPU(通过machine_shutdown()),然后调用stop_this_cpu()以禁用最后一个剩余的工作处理器。该函数所做的第一件事是禁用当前处理器上的中断,即调度程序不再能够控制。

我不知道为什么系统调用reboot()仍然调用do_exit(0),调用后kernel_halt()。我是这样解释的:现在,所有处理器都标记为禁用,系统调用会自行reboot()调用do_exit(0)并结束。即使调度程序被唤醒,也没有更多启用的处理器可以在其上调度某些任务,也不会中断:系统已停止。我不确定这个解释,因为stop_this_cpu()似乎没有返回(它进入无限循环)。Maybe 只是一个保障,对于stop_this_cpu()失败(并返回)的情况:在这种情况下,do_exit()将干净地结束当前任务,然后panic()调用该函数。

至于panic()代码(在这里定义:http: //lxr.linux.no/linux+v3.6.6/kernel/panic.c#L69),该函数首先禁用本地中断,然后禁用所有其他处理器,除了当前一个通过调用smp_send_stop(). 最后,作为在当前处理器(这是唯一还活着的处理器)上执行的唯一任务,所有本地中断都被禁用(也就是说,可抢占式调度程序——毕竟是一个定时器中断——没有机会......) ,然后panic()函数循环一段时间或它调用emergency_restart(),这应该重新启动处理器。

如果您有更好的见解,请贡献。

于 2012-11-16T08:43:15.607 回答