reboot指令
//kernel\sys.c
magic1、magic2,两个int类型的“法力数”,用于避免误操作。详细在“include/uapi/linux/reboot.h”中界说。
cmd,reboot方法。
//include\linux\reboot.h
#define LINUX_REBOOT_CMD_RESTART 0x01234567
#define LINUX_REBOOT_CMD_HALT 0xCDEF0123
#define LINUX_REBOOT_CMD_CAD_ON 0x89ABCDEF
#define LINUX_REBOOT_CMD_CAD_OFF 0x00000000
#define LINUX_REBOOT_CMD_POWER_OFF 0x4321FEDC
#define LINUX_REBOOT_CMD_RESTART2 0xA1B2C3D4
#define LINUX_REBOOT_CMD_SW_SUSPEND 0xD000FCE2
#define LINUX_REBOOT_CMD_KEXEC 0x45584543
arg,其它的额定参数。
SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd, void __user *, arg)
{
…
switch (cmd)
{
case LINUX_REBOOT_CMD_RESTART:
kernel_restart(NULL);
break;
case LINUX_REBOOT_CMD_CAD_ON:
C_A_D = 1;
break;
case LINUX_REBOOT_CMD_CAD_OFF:
C_A_D = 0;
break;
case LINUX_REBOOT_CMD_HALT:
kernel_halt();
do_exit(0);
panic(“cannot halt”);
case LINUX_REBOOT_CMD_POWER_OFF:
kernel_power_off();
do_exit(0);
break;
case LINUX_REBOOT_CMD_RESTART2:
if (strncpy_from_user(&buffer[0], arg, sizeof(buffer) – 1) < 0)
{
ret = -EFAULT;
break;
}
buffer[sizeof(buffer) – 1] = '\0';
kernel_restart(buffer);
break;
#ifdef CONFIG_KEXEC
case LINUX_REBOOT_CMD_KEXEC:
ret = kernel_kexec();
break;
#endif
#ifdef CONFIG_HIBERNATION
case LINUX_REBOOT_CMD_SW_SUSPEND:
ret = hibernate();
break;
#endif
default:
ret = -EINVAL;
break;
…
}
//kernel\sys.c
void kernel_restart(char *cmd)
{
…
machine_restart(cmd);
}
//arch\arm\kernel\process.c
void machine_restart(char *cmd)
{
…
arm_pm_restart(reboot_mode, cmd);
…
}
//arch\arm\kernel\setup.c
void __init setup_arch(char **cmdline_p)
{
struct machine_desc *mdesc;
…
mdesc = setup_machine_fdt(__atags_pointer);
…
if (mdesc->restart)
arm_pm_restart = mdesc->restart;
…
}
//arch\arm\mach-hi3516a\core.c
MACHINE_START(HI3516A, “hi3516a”)
.atag_offset = 0x100,
.map_io = hi3516a_map_io,
.init_early = hi3516a_init_early,
.init_irq = hi3516a_gic_init_irq,
.handle_irq = gic_handle_irq,
.TImer = &hi3516a_sys_TImer,
.init_machine = hi3516a_init,
.reserve = hi3516a_reserve,
.restart = hi3516a_restart,
MACHINE_END
//arch\arm\mach-hi3516a\core.c
void hi3516a_restart(char mode, const char *cmd)
{
__raw_writel(~0, IO_ADDRESS(SYS_CTRL_BASE) + REG_SC_SYSRES);
}
//drivers\mtd\devices\hisfc350\hisfc350_hi3516a.c
#define SYS_CTRL_BASE (0x20050000)
//arch\arm\mach-hi3535\include\mach\platform.h
#define REG_SC_SYSRES 0x4