Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/bouyer-socketcan]: src/sys/arch/i386/stand/efiboot 1673328



details:   https://anonhg.NetBSD.org/src/rev/08de3ffb5827
branches:  bouyer-socketcan
changeset: 820848:08de3ffb5827
user:      nonaka <nonaka%NetBSD.org@localhost>
date:      Sun Mar 12 05:33:49 2017 +0000

description:
1673328

diffstat:

 sys/arch/i386/stand/efiboot/boot.c |  646 +++++++++++++++++++++++++++++++++++++
 1 files changed, 646 insertions(+), 0 deletions(-)

diffs (truncated from 650 to 300 lines):

diff -r 1c60e1347120 -r 08de3ffb5827 sys/arch/i386/stand/efiboot/boot.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/i386/stand/efiboot/boot.c        Sun Mar 12 05:33:49 2017 +0000
@@ -0,0 +1,646 @@
+/*     $NetBSD: boot.c,v 1.4.6.2 2017/03/12 05:33:49 nonaka Exp $      */
+
+/*-
+ * Copyright (c) 2016 Kimihiro Nonaka <nonaka%netbsd.org@localhost>
+ * 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 REGENTS 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 REGENTS 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.
+ */
+
+#include "efiboot.h"
+
+#include <sys/bootblock.h>
+#include <sys/boot_flag.h>
+
+#include "bootcfg.h"
+#include "bootmod.h"
+#include "bootmenu.h"
+#include "devopen.h"
+
+int errno;
+int boot_biosdev;
+daddr_t boot_biossector;
+
+extern const char bootprog_name[], bootprog_rev[], bootprog_kernrev[];
+
+extern struct x86_boot_params boot_params;
+extern char twiddle_toggle;
+
+static const char * const names[][2] = {
+       { "netbsd", "netbsd.gz" },
+       { "onetbsd", "onetbsd.gz" },
+       { "netbsd.old", "netbsd.old.gz" },
+};
+
+#define NUMNAMES       __arraycount(names)
+#define DEFFILENAME    names[0][0]
+
+#define        MAXDEVNAME      16
+
+void   command_help(char *);
+void   command_quit(char *);
+void   command_boot(char *);
+void   command_consdev(char *);
+void   command_dev(char *);
+void   command_devpath(char *);
+void   command_efivar(char *);
+void   command_gop(char *);
+#if LIBSA_ENABLE_LS_OP
+void   command_ls(char *);
+#endif
+void   command_memmap(char *);
+#ifndef SMALL
+void   command_menu(char *);
+#endif
+void   command_modules(char *);
+void   command_multiboot(char *);
+void   command_text(char *);
+void   command_version(char *);
+
+const struct bootblk_command commands[] = {
+       { "help",       command_help },
+       { "?",          command_help },
+       { "quit",       command_quit },
+       { "boot",       command_boot },
+       { "consdev",    command_consdev },
+       { "dev",        command_dev },
+       { "devpath",    command_devpath },
+       { "efivar",     command_efivar },
+       { "fs",         fs_add },
+       { "gop",        command_gop },
+       { "load",       module_add },
+#if LIBSA_ENABLE_LS_OP
+       { "ls",         command_ls },
+#endif
+       { "memmap",     command_memmap },
+#ifndef SMALL
+       { "menu",       command_menu },
+#endif
+       { "modules",    command_modules },
+       { "multiboot",  command_multiboot },
+       { "rndseed",    rnd_add },
+       { "splash",     splash_add },
+       { "text",       command_text },
+       { "userconf",   userconf_add },
+       { "version",    command_version },
+       { NULL,         NULL },
+};
+
+static char *default_devname;
+static int default_unit, default_partition;
+static const char *default_filename;
+
+static char *sprint_bootsel(const char *);
+static void bootit(const char *, int);
+
+int
+parsebootfile(const char *fname, char **fsname, char **devname, int *unit,
+    int *partition, const char **file)
+{
+       const char *col;
+
+       *fsname = "ufs";
+       *devname = default_devname;
+       *unit = default_unit;
+       *partition = default_partition;
+       *file = default_filename;
+
+       if (fname == NULL)
+               return 0;
+
+       if ((col = strchr(fname, ':')) != NULL) {       /* device given */
+               static char savedevname[MAXDEVNAME+1];
+               int devlen;
+               int u = 0, p = 0;
+               int i = 0;
+
+               devlen = col - fname;
+               if (devlen > MAXDEVNAME)
+                       return EINVAL;
+
+#define isvalidname(c) ((c) >= 'a' && (c) <= 'z')
+               if (!isvalidname(fname[i]))
+                       return EINVAL;
+               do {
+                       savedevname[i] = fname[i];
+                       i++;
+               } while (isvalidname(fname[i]));
+               savedevname[i] = '\0';
+
+#define isnum(c) ((c) >= '0' && (c) <= '9')
+               if (i < devlen) {
+                       if (!isnum(fname[i]))
+                               return EUNIT;
+                       do {
+                               u *= 10;
+                               u += fname[i++] - '0';
+                       } while (isnum(fname[i]));
+               }
+
+#define isvalidpart(c) ((c) >= 'a' && (c) <= 'z')
+               if (i < devlen) {
+                       if (!isvalidpart(fname[i]))
+                               return EPART;
+                       p = fname[i++] - 'a';
+               }
+
+               if (i != devlen)
+                       return ENXIO;
+
+               *devname = savedevname;
+               *unit = u;
+               *partition = p;
+               fname = col + 1;
+       }
+
+       if (*fname)
+               *file = fname;
+
+       return 0;
+}
+
+static char *
+sprint_bootsel(const char *filename)
+{
+       char *fsname, *devname;
+       int unit, partition;
+       const char *file;
+       static char buf[80];
+
+       if (parsebootfile(filename, &fsname, &devname, &unit,
+                         &partition, &file) == 0) {
+               snprintf(buf, sizeof(buf), "%s%d%c:%s", devname, unit,
+                   'a' + partition, file);
+               return buf;
+       }
+       return "(invalid)";
+}
+
+void
+clearit(void)
+{
+
+       if (bootcfg_info.clear)
+               clear_pc_screen();
+}
+
+static void
+bootit(const char *filename, int howto)
+{
+       EFI_STATUS status;
+       EFI_PHYSICAL_ADDRESS bouncebuf;
+       UINTN npages;
+       u_long allocsz;
+
+       if (howto & AB_VERBOSE)
+               printf("booting %s (howto 0x%x)\n", sprint_bootsel(filename),
+                   howto);
+
+       if (count_netbsd(filename, &allocsz) < 0) {
+               printf("boot: %s: %s\n", sprint_bootsel(filename),
+                      strerror(errno));
+               return;
+       }
+
+       bouncebuf = EFI_ALLOCATE_MAX_ADDRESS;
+       npages = EFI_SIZE_TO_PAGES(allocsz);
+       status = uefi_call_wrapper(BS->AllocatePages, 4, AllocateMaxAddress,
+           EfiLoaderData, npages, &bouncebuf);
+       if (EFI_ERROR(status)) {
+               printf("boot: %s: %s\n", sprint_bootsel(filename),
+                      strerror(ENOMEM));
+               return;
+       }
+
+       efi_loadaddr = bouncebuf;
+       if (exec_netbsd(filename, bouncebuf, howto, 0, efi_cleanup) < 0)
+               printf("boot: %s: %s\n", sprint_bootsel(filename),
+                      strerror(errno));
+       else
+               printf("boot returned\n");
+
+       (void) uefi_call_wrapper(BS->FreePages, 2, bouncebuf, npages);
+       efi_loadaddr = 0;
+}
+
+void
+print_banner(void)
+{
+       int n;
+
+       clearit();
+       if (bootcfg_info.banner[0]) {
+               for (n = 0; n < BOOTCFG_MAXBANNER && bootcfg_info.banner[n];
+                   n++)
+                       printf("%s\n", bootcfg_info.banner[n]);
+       } else
+               command_version("short");
+}
+
+void
+boot(void)
+{
+       int currname;
+       int c;
+
+       boot_modules_enabled = !(boot_params.bp_flags & X86_BP_FLAGS_NOMODULES);
+
+       /* try to set default device to what BIOS tells us */
+       bios2dev(boot_biosdev, boot_biossector, &default_devname, &default_unit,
+           &default_partition);
+
+       /* if the user types "boot" without filename */
+       default_filename = DEFFILENAME;
+
+       if (!(boot_params.bp_flags & X86_BP_FLAGS_NOBOOTCONF)) {
+               parsebootconf(BOOTCFG_FILENAME);
+       } else {
+               bootcfg_info.timeout = boot_params.bp_timeout;
+       }
+
+       /*
+        * If console set in boot.cfg, switch to it.
+        * This will print the banner, so we don't need to explicitly do it
+        */
+       if (bootcfg_info.consdev)
+               command_consdev(bootcfg_info.consdev);
+       else
+               print_banner();
+
+       /* Display the menu, if applicable */
+       twiddle_toggle = 0;
+       if (bootcfg_info.nummenu > 0) {
+               /* Does not return */
+               doboottypemenu();
+       }
+
+       printf("Press return to boot now, any other key for boot menu\n");



Home | Main Index | Thread Index | Old Index