* Stopping web server apache2 * Stop in my script and clean net.rules .... * Asking all remaining proc[ OK ]to terminate... [ OK ] * All processes ended within 1 seconds... rpcbind: rpcbind terminating on signal. Restart with "rpcbind -w" [ OK ]ctivating swap... [ OK ] * Unmounting local filesystems... * Will now restart [ 847.054796] reboot: Restarting system
message = "\nThe system is going down NOW !!"; syslog(pri, "%s", message); printf(bb_shutdown_format, message);
sync();
/* Send signals to every process _except_ pid 1 */ message = "Sending SIGTERM to all processes."; syslog(pri, "%s", message); printf(bb_shutdown_format, message);
kill(-1, SIGTERM); sleep(1); sync();
message = "Sending SIGKILL to all processes."; syslog(pri, "%s", message); printf(bb_shutdown_format, message);
kill(-1, SIGKILL); sleep(1);
sync();
reboot(magic); return 0; /* Shrug */ }
两者处理过程类似,首先调用kill发送信号,最后调用reboot函数。
reboot是一个系统调用,man手册说明如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/* For libc4 and libc5 the library call and the system call are identical, and since kernel version 2.1.30 there are symbolic names LINUX_REBOOT_* for the constants and a fourth argument to the call: */
#include <unistd.h> #include <linux/reboot.h>
int reboot(int magic, int magic2, int cmd, void *arg);
/* Under glibc some of the constants involved have gotten symbolic names RB_*, and the library call is a 1-argument wrapper around the 3-argument system call: */
static void native_machine_emergency_restart(void) { for (;;) { /* Could also try the reset bit in the Hammer NB */ switch (reboot_type) { // 重启标志:reboot_type。 case BOOT_ACPI: acpi_reboot(); reboot_type = BOOT_KBD; // BOOT_ACPI不成功再到BOOT_KBD break;
case BOOT_KBD: mach_reboot_fixups(); /* For board specific fixups */
for (i = 0; i < 10; i++) { kb_wait(); udelay(50); outb(0xfe, 0x64); /* Pulse reset low */ outb(0x0e, 0xcf9); /* for byatrail e3800 SOC by Late Lee*/ udelay(50); } if (attempt == 0 && orig_reboot_type == BOOT_ACPI) { attempt = 1; reboot_type = BOOT_ACPI; } else { reboot_type = BOOT_EFI; // BOOT_KBD不成功再到BOOT_EFI } break;
case BOOT_EFI: efi_reboot(reboot_mode, NULL); reboot_type = BOOT_BIOS; // BOOT_EFI不成功再到BOOT_BIOS break;
case BOOT_BIOS: machine_real_restart(MRR_BIOS);
/* We're probably dead after this, but... */ reboot_type = BOOT_CF9_SAFE;// BOOT_BIOS不成功再到BOOT_CF9_SAFE break;
case BOOT_CF9_FORCE: port_cf9_safe = true; /* Fall through */
case BOOT_CF9_SAFE: if (port_cf9_safe) { u8 reboot_code = reboot_mode == REBOOT_WARM ? 0x06 : 0x0E; u8 cf9 = inb(0xcf9) & ~reboot_code; outb(cf9|2, 0xcf9); /* Request hard reset */ udelay(50); /* Actually do the reset */ outb(cf9|reboot_code, 0xcf9); udelay(50); } reboot_type = BOOT_TRIPLE; // BOOT_CF9_SAFE不成功再到BOOT_TRIPLE break;
case BOOT_TRIPLE: load_idt(&no_idt); __asm__ __volatile__("int3");
/* We're probably dead after this, but... */ reboot_type = BOOT_KBD; break; } } }
int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { printf("resetting ...\n");
/* wait 50 ms */ udelay(50000); disable_interrupts(); reset_cpu(0);
/*NOTREACHED*/ return 0; }
__weak void reset_cpu(ulong addr) { /* Do a hard reset through the chipset's reset control register */ outb(SYS_RST | RST_CPU, IO_PORT_RESET); for (;;) cpu_hlt(); }
/* * This register is documented in (for example) the Intel Atom Processor E3800 * Product Family Datasheet in "PCU - Power Management Controller (PMC)". * * RST_CNT: Reset Control Register (RST_CNT) Offset cf9. * * The naming follows Intel's naming. */ #define IO_PORT_RESET 0xcf9
enum { SYS_RST = 1 << 1, /* 0 for soft reset, 1 for hard reset */ RST_CPU = 1 << 2, /* initiate reset */ FULL_RST = 1 << 3, /* full power cycle */ };