From 1f2054c89cf49ca9883fe39d5ce80fb969bac6dd Mon Sep 17 00:00:00 2001 From: Erik van der Kouwe Date: Mon, 30 Aug 2010 19:01:58 +0000 Subject: [PATCH] Shutdown changes for multiboot: CTRL-ALT-DEL resets, panic halts --- commands/reboot/halt.c | 3 +- commands/reboot/shutdown.c | 5 ++- drivers/tty/keyboard.c | 2 +- include/unistd.h | 3 +- kernel/arch/i386/arch_system.c | 61 ++++++++++++++++++++++++++-------- man/man8/shutdown.8 | 6 +++- servers/init/init.c | 2 +- 7 files changed, 62 insertions(+), 20 deletions(-) diff --git a/commands/reboot/halt.c b/commands/reboot/halt.c index e7bd7808b..5c627a64d 100644 --- a/commands/reboot/halt.c +++ b/commands/reboot/halt.c @@ -32,7 +32,7 @@ char *reboot_code = "delay; boot"; void usage() { - fprintf(stderr, "Usage: %s [-hrRf] [-x reboot-code]\n", prog); + fprintf(stderr, "Usage: %s [-hrRfd] [-x reboot-code]\n", prog); exit(1); } @@ -63,6 +63,7 @@ char **argv; case 'h': flag = RBT_HALT; break; case 'r': flag = RBT_REBOOT; break; case 'R': flag = RBT_RESET; break; + case 'd': flag = RBT_DEFAULT; break; case 'f': fast = 1; break; case 'x': flag = RBT_MONITOR; diff --git a/commands/reboot/shutdown.c b/commands/reboot/shutdown.c index bfa4f6b88..11a725680 100644 --- a/commands/reboot/shutdown.c +++ b/commands/reboot/shutdown.c @@ -20,6 +20,7 @@ -C: crash check, i.e. is the last wtmp entry a shutdown entry? -x: let the monitor execute the given code -R: reset the system + -d: default CTRL-ALT-DEL shutdown for current bootloader */ #define _POSIX_SOURCE 1 @@ -148,6 +149,7 @@ char *argv[]; case 'h': case 'r': case 'x': + case 'd': reboot_flag = *opt; if (reboot_flag == 'x') { if (*++opt == 0) { @@ -271,11 +273,12 @@ char *argv[]; void usage() { - fputs("Usage: shutdown [-hrRmk] [-x code] [time [message]]\n", stderr); + fputs("Usage: shutdown [-hrRmkd] [-x code] [time [message]]\n", stderr); fputs(" -h -> halt system after shutdown\n", stderr); fputs(" -r -> reboot system after shutdown\n", stderr); fputs(" -R -> reset system after shutdown\n", stderr); fputs(" -x -> return to the monitor doing...\n", stderr); + fputs(" -d -> default CTRL-ALT-DEL shutdown for current bootloader\n", stderr); fputs(" -m -> read a shutdown message from standard input\n", stderr); fputs(" -k -> stop an already running shutdown\n", stderr); fputs(" code -> boot monitor code to be executed\n", stderr); diff --git a/drivers/tty/keyboard.c b/drivers/tty/keyboard.c index 6938e4a91..5c039203a 100644 --- a/drivers/tty/keyboard.c +++ b/drivers/tty/keyboard.c @@ -735,7 +735,7 @@ int scode; /* scan code of key just struck or released */ { if (++CAD_count == 3) { cons_stop(); - sys_abort(RBT_HALT); + sys_abort(RBT_DEFAULT); } sys_kill(INIT_PROC_NR, SIGABRT); rebooting = 1; diff --git a/include/unistd.h b/include/unistd.h index 230df6e5c..24ff7e0a5 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -35,7 +35,8 @@ #define RBT_PANIC 2 /* a server panics */ #define RBT_MONITOR 3 /* let the monitor do this */ #define RBT_RESET 4 /* hard reset the system */ -#define RBT_INVALID 5 /* first invalid reboot flag */ +#define RBT_DEFAULT 5 /* return to monitor, reset if not possible */ +#define RBT_INVALID 6 /* first invalid reboot flag */ #define _PM_SEG_FLAG (1L << 30) /* for read() and write() to FS by PM */ #endif diff --git a/kernel/arch/i386/arch_system.c b/kernel/arch/i386/arch_system.c index 8b33e0629..26c6ee3fb 100644 --- a/kernel/arch/i386/arch_system.c +++ b/kernel/arch/i386/arch_system.c @@ -66,9 +66,10 @@ PRIVATE __dead void arch_bios_poweroff(void) PUBLIC int cpu_has_tsc; -PUBLIC __dead void arch_shutdown(const int how) +PUBLIC __dead void arch_shutdown(int how) { static char mybuffer[sizeof(params_buffer)]; + u16_t magic; vm_stop(); /* Mask all interrupts, including the clock. */ @@ -85,6 +86,10 @@ PUBLIC __dead void arch_shutdown(const int how) } } + if (how == RBT_DEFAULT) { + how = mon_return ? RBT_HALT : RBT_RESET; + } + if(how != RBT_RESET) { /* return to boot monitor */ @@ -129,24 +134,52 @@ PUBLIC __dead void arch_shutdown(const int how) } if (mon_return) arch_monitor(); - else { + + /* monitor command with no monitor: reset or poweroff + * depending on the parameters + */ + if (how == RBT_MONITOR) { mybuffer[0] = '\0'; - arch_get_params(mybuffer,sizeof(mybuffer)); + arch_get_params(mybuffer, sizeof(mybuffer)); if (strstr(mybuffer, "boot") || strstr(mybuffer, "menu") || strstr(mybuffer, "reset")) - reset(); - else - arch_bios_poweroff(); + how = RBT_RESET; + else + how = RBT_HALT; } - } else { - /* Reset the system by forcing a processor shutdown. First stop - * the BIOS memory test by setting a soft reset flag. - */ - u16_t magic = STOP_MEM_CHECK; - phys_copy(vir2phys(&magic), SOFT_RESET_FLAG_ADDR, - SOFT_RESET_FLAG_SIZE); - reset(); + } + + switch (how) { + case RBT_REBOOT: + case RBT_RESET: + /* Reset the system by forcing a processor shutdown. + * First stop the BIOS memory test by setting a soft + * reset flag. + */ + magic = STOP_MEM_CHECK; + phys_copy(vir2phys(&magic), SOFT_RESET_FLAG_ADDR, + SOFT_RESET_FLAG_SIZE); + reset(); + NOT_REACHABLE; + + case RBT_HALT: + /* Poweroff without boot monitor */ + arch_bios_poweroff(); + NOT_REACHABLE; + + case RBT_PANIC: + /* Allow user to read panic message */ + for (; ; ) halt_cpu(); + NOT_REACHABLE; + + default: + /* Not possible! trigger panic */ + assert(how != RBT_MONITOR); + assert(how != RBT_DEFAULT); + assert(how < RBT_INVALID); + panic("unexpected value for how: %d", how); + NOT_REACHABLE; } NOT_REACHABLE; diff --git a/man/man8/shutdown.8 b/man/man8/shutdown.8 index 6dadf1439..691e2bfbe 100644 --- a/man/man8/shutdown.8 +++ b/man/man8/shutdown.8 @@ -3,7 +3,7 @@ shutdown \- graciously close the system down .SH SYNOPSIS .B shutdown -.RB [ \-hrRmk ] +.RB [ \-hrRmkd ] .RB [ \-x .IR code ] .RI [ time-specification @@ -60,6 +60,10 @@ to the Boot Monitor. With .B \-R the system will receive a hardware reset. .TP +.B \-d +Default CTRL-ALT-DEL shutdown for current bootloader; drops to the boot +monitor is possible and resets otherwise. +.TP .BI \-x " code" Halt the system and let the Monitor execute the given code as if typed at the monitor prompt. You can for instance use diff --git a/servers/init/init.c b/servers/init/init.c index b2bb3bd69..6a5654efd 100644 --- a/servers/init/init.c +++ b/servers/init/init.c @@ -30,7 +30,7 @@ #include /* Command to execute as a response to the three finger salute. */ -char *REBOOT_CMD[] = { "shutdown", "now", "CTRL-ALT-DEL", NULL }; +char *REBOOT_CMD[] = { "shutdown", "-d", "now", "CTRL-ALT-DEL", NULL }; /* Associated fake ttytab entry. */ struct ttyent TT_REBOOT = { "console", "-", REBOOT_CMD, NULL }; -- 2.44.0