Question

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.

Was it helpful?

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top