Linux内核文件重启

时间:2014-05-11 11:23:45

标签: c linux linux-kernel reboot

我正在查看此文件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

这个更大可以让任何人告诉我它们之间的区别吗? 当您想重新启动电脑时,会使用这两个中的哪一个。

1 个答案:

答案 0 :(得分:4)

kernel/reboot.c文件是与引导无关的重启过程的一部分。

arch/x86/kernel/reboot.c和所有其他arch/*/kernel/reboot.ckernel/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特定部分的入口点:

machine_emergency_restart

 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