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 */

Reply via email to