Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/stand/efiboot Add boot.cfg support.
details: https://anonhg.NetBSD.org/src/rev/d76575705596
branches: trunk
changeset: 973144:d76575705596
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Sun Jun 21 23:53:26 2020 +0000
description:
Add boot.cfg support.
diffstat:
sys/stand/efiboot/Makefile.efiboot | 6 +-
sys/stand/efiboot/boot.c | 30 ++++-
sys/stand/efiboot/bootmenu.c | 215 +++++++++++++++++++++++++++++++++++++
sys/stand/efiboot/bootmenu.h | 38 ++++++
sys/stand/efiboot/efiboot.c | 3 +-
sys/stand/efiboot/version | 3 +-
6 files changed, 288 insertions(+), 7 deletions(-)
diffs (truncated from 391 to 300 lines):
diff -r ee8a97928477 -r d76575705596 sys/stand/efiboot/Makefile.efiboot
--- a/sys/stand/efiboot/Makefile.efiboot Sun Jun 21 23:08:16 2020 +0000
+++ b/sys/stand/efiboot/Makefile.efiboot Sun Jun 21 23:53:26 2020 +0000
@@ -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 @@
.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
diff -r ee8a97928477 -r d76575705596 sys/stand/efiboot/boot.c
--- a/sys/stand/efiboot/boot.c Sun Jun 21 23:08:16 2020 +0000
+++ b/sys/stand/efiboot/boot.c Sun Jun 21 23:53:26 2020 +0000
@@ -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 <nonaka%netbsd.org@localhost>
@@ -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_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 @@
{ "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 @@
}
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 @@
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')
diff -r ee8a97928477 -r d76575705596 sys/stand/efiboot/bootmenu.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/stand/efiboot/bootmenu.c Sun Jun 21 23:53:26 2020 +0000
@@ -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';
Home |
Main Index |
Thread Index |
Old Index