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/e60957b11f1b
branches:  trunk
changeset: 934994:e60957b11f1b
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 897a4c8d7ac5 -r e60957b11f1b 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 897a4c8d7ac5 -r e60957b11f1b 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 897a4c8d7ac5 -r e60957b11f1b 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