hum*_*ace 35 shutdown linux-kernel
我对用户空间和初始化系统(无论是经典的 init sysV /upstart/systemd)如何在系统关闭时工作有一个粗略的想法。(本质上有“停止!”、“请真正停止”、“过程我需要杀死你才能停止”和等待......事情正在进行中的顺序)。
无论如何,我非常不知道系统关闭在内核中是如何工作的(肯定还有很多事情要做)?
我试图查看内核文档https://www.kernel.org/doc/htmldocs/,甚至使用NSA 的 pal 搜索工具让我先了解它是如何工作的。
我还搜索了 SE U+L 并没有发现任何东西(我是否忽略了它?)
无论如何,这个问题虽然可能有点挑战性,但值得在这个问答网络中得到答案,因为我认为更多的人有兴趣了解关闭时 linux 内核中发生的情况。
可能还有更改以链接到一些更详细的解释。
答案可能包括使用了哪些系统调用和哪些内核信号?
https://github.com/torvalds/linux/blob/b3a3a9c441e2c8f6b6760de9331023a7906a4ac6/arch/x86/kernel/reboot.c 似乎是与重启相关的 x86 使用文件(已经接近关闭,嗯?)
也许在这里找到的片段http://lxr.free-electrons.com/source/kernel/reboot.c#L176 可以用来解释
第176话 177 { 第178话 第179话 第180话 第181话 第182话 183 pr_emerg(“断电\n”); 184 kmsg_dump(KMSG_DUMP_POWEROFF); 第185话 第186话 第187话
Gil*_*il' 34
了解 Linux 内核如何工作的主要资源是:
在这种情况下,我在文档或 LWN 上找不到任何与中心相关的内容,所以是 LXR。
用户态代码所做的最后一件事是调用reboot
系统调用。它需要 4 个参数,因此SYSCALL_DEFINE4(reboot
在 LXR 上搜索,这会导致kernel/reboot.c
. 检查调用者的特权和参数后,系统调用入口点调用的几个功能之一:kernel_restart
重新启动,kernel_halt
要在紧密的循环停止,kernel_poweroff
以关闭系统电源,kernel_kexec
以通过更换一个新的内核(如编译),或hibernate
断电前将内存保存到磁盘。
kernel_restart
,kernel_halt
并且
kernel_power_off
非常相似:
reboot_notifier_list
,这是内核组件可以注册以在掉电时执行代码的钩子列表。在这个阶段只有少数驱动程序需要执行代码,主要是看门狗。system_state
变量。device_shutdown
以释放或关闭系统上的所有设备。许多司机都进入了这个阶段。migrate_to_reboot_cpu
注意切换到一个特定的 CPU 并防止调度程序在其他 CPU 上分派代码。在此之后,只有一个 CPU 正在运行。syscore_shutdown
调用已注册的 syscore 操作的shutdown
方法。我认为这主要是关于禁用中断;很少有钩子有方法。shutdown
machine_restart
,machine_halt
或以某种依赖机器的方式休息machine_power_off
。该冬眠代码经过以下步骤:
kernel_restart
、kernel_halt
或kernel_power_off
或某些特定于平台的休眠方法。关闭系统的另一种方法是machine_emergency_restart
。这是由神奇的 SysRq键B调用的。在O关键的工作方式不同:它调用kernel_power_off
。
系统也可能因恐慌而关闭,即出现不可恢复的错误。恐慌尝试记录一条消息,然后重新启动系统(通过硬件看门狗或紧急重启)。
这只是部分答案,我肯定会邀请其他答案,这可能会更详尽和清晰。
这个答案的内容取自3.13 linux内核的kernel/reboot.c
文件(这可能不是第一个猜测,因为名称不是shutdown.c而是reboot.c)
无论如何,我们基本上有三个函数来描绘关闭系统的过程
void kernel_halt(void)
// 以系统处于停止状态结束void kernel_power_off(void)
// 以系统关闭结束void kernel_restart(char *cmd)
// 结束系统并重新启动它这些函数非常简短,因此可以完整地粘贴到此处。他们的代码最好地展示了内核关闭过程中所采取的步骤。(这些评论是我写的,可能不是100%理想和正确,请自己检查一下是否确定。这很简单,尝试一下。
void kernel_halt(void)
无效内核停止(无效) { // 第一步: // a) 调用函数/回调注册为在重新启动/关闭时运行 // b) 将 system_sate 设置为 SYSTEM_HALT // c) 停止 userspacetool 交互 // d) 调用 device_shutdown() 函数 kernel_shutdown_prepare(SYSTEM_HALT); // 第二步:我认为这对于多CPU系统来说是必需的 migrate_to_reboot_cpu(); // 第三步: // syscore_shutdown - 执行所有已注册的系统核心关闭回调 syscore_shutdown(); // 第四条消息 pr_emerg("系统停止\n"); kmsg_dump(KMSG_DUMP_HALT); // 第 5 个调用架构特定的 cpu-halt-code machine_halt(); }
整个事情是通过sys_reboot
系统调用启动的,考虑到它不仅会重新启动而且还会关闭,无论如何都不是与关闭过程连接的直接事情。