Module Name: src Committed By: jmcneill Date: Sun Jun 21 23:53:26 UTC 2020
Modified Files: src/sys/stand/efiboot: Makefile.efiboot boot.c efiboot.c version Added Files: src/sys/stand/efiboot: bootmenu.c bootmenu.h Log Message: Add boot.cfg support. To generate a diff of this commit: cvs rdiff -u -r1.14 -r1.15 src/sys/stand/efiboot/Makefile.efiboot cvs rdiff -u -r1.22 -r1.23 src/sys/stand/efiboot/boot.c cvs rdiff -u -r0 -r1.1 src/sys/stand/efiboot/bootmenu.c \ src/sys/stand/efiboot/bootmenu.h cvs rdiff -u -r1.18 -r1.19 src/sys/stand/efiboot/efiboot.c cvs rdiff -u -r1.16 -r1.17 src/sys/stand/efiboot/version Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/stand/efiboot/Makefile.efiboot diff -u src/sys/stand/efiboot/Makefile.efiboot:1.14 src/sys/stand/efiboot/Makefile.efiboot:1.15 --- src/sys/stand/efiboot/Makefile.efiboot:1.14 Sun Jun 21 17:24:26 2020 +++ src/sys/stand/efiboot/Makefile.efiboot Sun Jun 21 23:53:26 2020 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile.efiboot,v 1.14 2020/06/21 17:24:26 jmcneill Exp $ +# $NetBSD: Makefile.efiboot,v 1.15 2020/06/21 23:53:26 jmcneill Exp $ S= ${.CURDIR}/../../.. @@ -21,8 +21,8 @@ AFLAGS.start.S= ${${ACTIVE_CC} == "clang .PATH: ${EFIDIR}/gnuefi SOURCES= crt0-efi-${GNUEFIARCH}.S reloc_${GNUEFIARCH}.c -SOURCES+= boot.c conf.c console.c dev_net.c devopen.c exec.c module.c \ - panic.c prompt.c +SOURCES+= boot.c bootmenu.c conf.c console.c dev_net.c devopen.c exec.c \ + module.c panic.c prompt.c SOURCES+= efiboot.c efichar.c efidev.c efienv.c efigetsecs.c efifdt.c \ efifile.c efiblock.c efinet.c efipxe.c efiacpi.c efirng.c smbios.c Index: src/sys/stand/efiboot/boot.c diff -u src/sys/stand/efiboot/boot.c:1.22 src/sys/stand/efiboot/boot.c:1.23 --- src/sys/stand/efiboot/boot.c:1.22 Sun Jun 21 17:24:26 2020 +++ src/sys/stand/efiboot/boot.c Sun Jun 21 23:53:26 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: boot.c,v 1.22 2020/06/21 17:24:26 jmcneill Exp $ */ +/* $NetBSD: boot.c,v 1.23 2020/06/21 23:53:26 jmcneill Exp $ */ /*- * Copyright (c) 2016 Kimihiro Nonaka <non...@netbsd.org> @@ -34,12 +34,14 @@ #include "efienv.h" #include "efirng.h" #include "module.h" +#include "bootmenu.h" #include <sys/bootblock.h> #include <sys/boot_flag.h> #include <machine/limits.h> #include <loadfile.h> +#include <bootcfg.h> extern const char bootprog_name[], bootprog_rev[], bootprog_kernrev[]; @@ -96,6 +98,7 @@ void command_load(char *); void command_unload(char *); void command_ls(char *); void command_mem(char *); +void command_menu(char *); void command_printenv(char *); void command_setenv(char *); void command_clearenv(char *); @@ -116,6 +119,7 @@ const struct boot_command commands[] = { { "unload", command_unload, "unload <module_name>" }, { "ls", command_ls, "ls [hdNn:/path]" }, { "mem", command_mem, "mem" }, + { "menu", command_menu, "menu" }, { "printenv", command_printenv, "printenv [key]" }, { "setenv", command_setenv, "setenv <key> <value>" }, { "clearenv", command_clearenv, "clearenv <key>" }, @@ -269,6 +273,17 @@ command_mem(char *arg) } void +command_menu(char *arg) +{ + if (bootcfg_info.nummenu == 0) { + printf("No menu defined in boot.cfg\n"); + return; + } + + doboottypemenu(); /* Does not return */ +} + +void command_printenv(char *arg) { char *val; @@ -530,7 +545,20 @@ boot(void) int currname, c; read_env(); + + parsebootconf(BOOTCFG_FILENAME); + + if (bootcfg_info.clear) + uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut); + print_banner(); + + /* Display menu if configured */ + twiddle_toggle = 1; + if (bootcfg_info.nummenu > 0) { + doboottypemenu(); /* No return */ + } + printf("Press return to boot now, any other key for boot prompt\n"); if (netbsd_path[0] != '\0') Index: src/sys/stand/efiboot/efiboot.c diff -u src/sys/stand/efiboot/efiboot.c:1.18 src/sys/stand/efiboot/efiboot.c:1.19 --- src/sys/stand/efiboot/efiboot.c:1.18 Thu May 14 19:20:08 2020 +++ src/sys/stand/efiboot/efiboot.c Sun Jun 21 23:53:26 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: efiboot.c,v 1.18 2020/05/14 19:20:08 riastradh Exp $ */ +/* $NetBSD: efiboot.c,v 1.19 2020/06/21 23:53:26 jmcneill Exp $ */ /*- * Copyright (c) 2018 Jared McNeill <jmcne...@invisible.ca> @@ -72,7 +72,6 @@ efi_main(EFI_HANDLE imageHandle, EFI_SYS uefi_call_wrapper(ST->ConOut->Reset, 2, ST->ConOut, TRUE); uefi_call_wrapper(ST->ConOut->SetMode, 2, ST->ConOut, 0); uefi_call_wrapper(ST->ConOut->EnableCursor, 2, ST->ConOut, TRUE); - uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut); status = uefi_call_wrapper(BS->AllocatePages, 4, AllocateAnyPages, EfiLoaderData, sz, &heap_start); if (EFI_ERROR(status)) Index: src/sys/stand/efiboot/version diff -u src/sys/stand/efiboot/version:1.16 src/sys/stand/efiboot/version:1.17 --- src/sys/stand/efiboot/version:1.16 Sun Jun 21 17:24:26 2020 +++ src/sys/stand/efiboot/version Sun Jun 21 23:53:26 2020 @@ -1,4 +1,4 @@ -$NetBSD: version,v 1.16 2020/06/21 17:24:26 jmcneill Exp $ +$NetBSD: version,v 1.17 2020/06/21 23:53:26 jmcneill Exp $ NOTE ANY CHANGES YOU MAKE TO THE EFI BOOTLOADER HERE. The format of this file is important - make sure the entries are appended on end, last item @@ -20,3 +20,4 @@ is taken as the current. 1.13: Add rndseed support. 1.14: Add EFI RNG support. 1.15: Add module support. +2.0: Add boot.cfg support. Added files: Index: src/sys/stand/efiboot/bootmenu.c diff -u /dev/null src/sys/stand/efiboot/bootmenu.c:1.1 --- /dev/null Sun Jun 21 23:53:26 2020 +++ src/sys/stand/efiboot/bootmenu.c Sun Jun 21 23:53:26 2020 @@ -0,0 +1,215 @@ +/* $NetBSD: bootmenu.c,v 1.1 2020/06/21 23:53:26 jmcneill Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SMALL + +#include <sys/types.h> +#include <sys/reboot.h> +#include <sys/bootblock.h> + +#include <lib/libsa/stand.h> +#include <lib/libsa/bootcfg.h> +#include <lib/libsa/ufs.h> +#include <lib/libkern/libkern.h> + +#include "bootmenu.h" +#include "efiboot.h" +#include "module.h" + +static void docommandchoice(int); + +extern const char bootprog_name[], bootprog_rev[], bootprog_kernrev[]; + +#define MENUFORMAT_AUTO 0 +#define MENUFORMAT_NUMBER 1 +#define MENUFORMAT_LETTER 2 + +/* + * XXX + * if module_add, userconf_add are strictly mi they can be folded back + * into sys/lib/libsa/bootcfg.c:perform_bootcfg(). + */ +static void +do_bootcfg_command(const char *cmd, char *arg) +{ + if (strcmp(cmd, BOOTCFG_CMD_LOAD) == 0) + module_add(arg); +#if notyet + else if (strcmp(cmd, BOOTCFG_CMD_USERCONF) == 0) + userconf_add(arg); +#endif +} + +int +parsebootconf(const char *conf) +{ + return perform_bootcfg(conf, &do_bootcfg_command, 32768); +} + +/* + * doboottypemenu will render the menu and parse any user input + */ +static int +getchoicefrominput(char *input, int def) +{ + int choice, usedef; + + choice = -1; + usedef = 0; + + if (*input == '\0' || *input == '\r' || *input == '\n') { + choice = def; + usedef = 1; + } else if (*input >= 'A' && *input < bootcfg_info.nummenu + 'A') + choice = (*input) - 'A'; + else if (*input >= 'a' && *input < bootcfg_info.nummenu + 'a') + choice = (*input) - 'a'; + else if (isdigit(*input)) { + choice = atoi(input) - 1; + if (choice < 0 || choice >= bootcfg_info.nummenu) + choice = -1; + } + + if (bootcfg_info.menuformat != MENUFORMAT_LETTER && + !isdigit(*input) && !usedef) + choice = -1; + + return choice; +} + +static void +docommandchoice(int choice) +{ + char input[80], *ic, *oc; + + ic = bootcfg_info.command[choice]; + /* Split command string at ; into separate commands */ + do { + oc = input; + /* Look for ; separator */ + for (; *ic && *ic != COMMAND_SEPARATOR; ic++) + *oc++ = *ic; + if (*input == '\0') + continue; + /* Strip out any trailing spaces */ + oc--; + for (; *oc == ' ' && oc > input; oc--); + *++oc = '\0'; + if (*ic == COMMAND_SEPARATOR) + ic++; + /* Stop silly command strings like ;;; */ + if (*input != '\0') + docommand(input); + /* Skip leading spaces */ + for (; *ic == ' '; ic++); + } while (*ic); +} + +void +bootdefault(void) +{ + int choice; + static int entered; + + if (bootcfg_info.nummenu > 0) { + if (entered) { + printf("default boot twice, skipping...\n"); + return; + } + entered = 1; + choice = bootcfg_info.def; + printf("command(s): %s\n", bootcfg_info.command[choice]); + docommandchoice(choice); + } +} + +__dead void +doboottypemenu(void) +{ + int choice; + char input[80]; + + printf("\n"); + /* Display menu */ + if (bootcfg_info.menuformat == MENUFORMAT_LETTER) { + for (choice = 0; choice < bootcfg_info.nummenu; choice++) + printf(" %c. %s\n", choice + 'A', + bootcfg_info.desc[choice]); + } else { + /* Can't use %2d format string with libsa */ + for (choice = 0; choice < bootcfg_info.nummenu; choice++) + printf(" %s%d. %s\n", + (choice < 9) ? " " : "", + choice + 1, + bootcfg_info.desc[choice]); + } + choice = -1; + for (;;) { + input[0] = '\0'; + + if (bootcfg_info.timeout < 0) { + if (bootcfg_info.menuformat == MENUFORMAT_LETTER) + printf("\nOption: [%c]:", + bootcfg_info.def + 'A'); + else + printf("\nOption: [%d]:", + bootcfg_info.def + 1); + + kgets(input, sizeof(input)); + choice = getchoicefrominput(input, bootcfg_info.def); + } else if (bootcfg_info.timeout == 0) + choice = bootcfg_info.def; + else { + printf("\nChoose an option; RETURN for default; " + "SPACE to stop countdown.\n"); + if (bootcfg_info.menuformat == MENUFORMAT_LETTER) + printf("Option %c will be chosen in ", + bootcfg_info.def + 'A'); + else + printf("Option %d will be chosen in ", + bootcfg_info.def + 1); + input[0] = awaitkey(bootcfg_info.timeout, 1); + input[1] = '\0'; + choice = getchoicefrominput(input, bootcfg_info.def); + /* If invalid key pressed, drop to menu */ + if (choice == -1) + bootcfg_info.timeout = -1; + } + if (choice < 0) + continue; + if (!strcmp(bootcfg_info.command[choice], "prompt")) { + printf("type \"?\" or \"help\" for help.\n"); + bootprompt(); /* does not return */ + } else { + docommandchoice(choice); + } + + } +} + +#endif /* !SMALL */ Index: src/sys/stand/efiboot/bootmenu.h diff -u /dev/null src/sys/stand/efiboot/bootmenu.h:1.1 --- /dev/null Sun Jun 21 23:53:26 2020 +++ src/sys/stand/efiboot/bootmenu.h Sun Jun 21 23:53:26 2020 @@ -0,0 +1,38 @@ +/* $NetBSD: bootmenu.h,v 1.1 2020/06/21 23:53:26 jmcneill Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _BOOTMENU_H +#define _BOOTMENU_H + +#define COMMAND_SEPARATOR ';' + +int parsebootconf(const char *); +void doboottypemenu(void); +void bootdefault(void); + +#endif /* !_BOOTMENU_H */