我正在查看此文件http://lxr.free-electrons.com/source/kernel/reboot.c
有人能告诉我这些代码的作用吗?
void (*pm_power_off_prepare)(void);
此文件用于重新启动电脑吗?
但我找到了另一个重启文件
http://lxr.free-electrons.com/source/arch/x86/kernel/reboot.c
这个更大可以让任何人告诉我它们之间的区别吗? 当您想重新启动电脑时,会使用这两个中的哪一个。
答案 0 :(得分:4)
kernel/reboot.c
文件是与引导无关的重启过程的一部分。
arch/x86/kernel/reboot.c
和所有其他arch/*/kernel/reboot.c
是kernel/reboot.c
使用的某些功能的体系结构特定版本。
例如,在arch/x86/kernel/reboot.c
中有machine_real_restart()
function(假设我们使用BIOS启动,实际选择在native_machine_emergency_restart
),这是最后调用的内核函数。它要求BIOS进行实际重启:
69 void __noreturn machine_real_restart(unsigned int type)
73 /*
74 * Write zero to CMOS register number 0x0f, which the BIOS POST
75 * routine will recognize as telling it to do a proper reboot. (Well
76 * that's what this book in front of me says -- it may only apply to
77 * the Phoenix BIOS though, it's not clear). At the same time,
78 * disable NMIs by setting the top bit in the CMOS address register,
79 * as we're about to do peculiar things to the CPU. I'm not sure if
80 * `outb_p' is needed instead of just `outb'. Use it to be on the
81 * safe side. (Yes, CMOS_WRITE does outb_p's. - Paul G.)
82 */
84 CMOS_WRITE(0x00, 0x8f);
96 /* Jump to the identity-mapped low memory code */
97 #ifdef CONFIG_X86_32
98 asm volatile("jmpl *%0" : :
99 "rm" (real_mode_header->machine_real_restart_asm),
100 "a" (type));
此函数从native_machine_emergency_restart()
function调用,registered作为*emergency_restart
的{{1}}函数指针。这个指针由machine_ops
structure调用,这是从独立于架构的部分kernel/reboot.c
到x86特定部分的入口点:
53 /**
54 * emergency_restart - reboot the system
55 *
56 * Without shutting down any hardware or taking any locks
57 * reboot the system. This is called when we know we are in
58 * trouble so this is our best effort to reboot. This is
59 * safe to call in interrupt context.
60 */
61 void emergency_restart(void)
62 {
63 kmsg_dump(KMSG_DUMP_EMERG);
64 machine_emergency_restart();
65 }
66 EXPORT_SYMBOL_GPL(emergency_restart);
对于正常关机(不是像^^^^那样的紧急事件),建立了类似的呼叫链。我们从emergency_restart()
function from kernel/reboot.c
开始:
125 /**
126 * kernel_restart - reboot the system
130 * Shutdown everything and perform a clean reboot.
131 * This is not safe to call in interrupt context.
132 */
133 void kernel_restart(char *cmd)
134 {
135 kernel_restart_prepare(cmd);
...
143 machine_restart(cmd);
144 }
145 EXPORT_SYMBOL_GPL(kernel_restart);
我们可以看到这个通用函数调用特定于架构的machine_restart
来执行所有需要的操作来告诉硬件我们正在重新启动。在x86中它会...但是,它会调用basic kernel/reboot.c
, kernel_restart
function:
658 void machine_restart(char *cmd)
659 {
660 machine_ops.restart(cmd);
661 }
X86的restart
function pointer from machine_ops
native_machine_restart
再次调用__machine_emergency_restart
,它将调用相同的machine_real_restart
。