Issue
I was looking at this file http://lxr.free-electrons.com/source/kernel/reboot.c
Can anyone tell me what this codes does?
void (*pm_power_off_prepare)(void);
This file is used to reboot the pc right?
But I found another reboot file
http://lxr.free-electrons.com/source/arch/x86/kernel/reboot.c
This one is much larger can anyone tell me the difference between them? Which one of these two are used when you want to reboot the pc.
Solution
kernel/reboot.c
file is architecture-independent part of reboot process.
arch/x86/kernel/reboot.c
and all other arch/*/kernel/reboot.c
are architecture-specific versions of some functions, used by kernel/reboot.c
.
For example, in arch/x86/kernel/reboot.c
there is machine_real_restart()
function (Assuming we booted using BIOS, actual selection is in native_machine_emergency_restart
), which is last kernel function called. It asks BIOS to do actual reboot:
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));
This function is called from native_machine_emergency_restart()
function, which is registered as *emergency_restart
function pointer of machine_ops
structure. This pointer is called by machine_emergency_restart
and this is the entry point from architecture independent part, kernel/reboot.c
into x86 specific part:
emergency_restart()
function from kernel/reboot.c
:
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);
For normal shutdown (not emergency one like ^^^^), similar call chain is built. Let's start from basic kernel/reboot.c
, kernel_restart
function:
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);
We can see that this universal function calls architecture specific machine_restart
to do all needed actions to tell hardware that we are rebooting. In x86 it will do ... yes, it will call restart
function pointer from machine_ops
:
658 void machine_restart(char *cmd)
659 {
660 machine_ops.restart(cmd);
661 }
X86's restart
points to the native_machine_restart
which again calls __machine_emergency_restart
, which will call same machine_real_restart
.
Answered By - osgx Answer Checked By - Robin (WPSolving Admin)