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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 */