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 support for booting kernels from FFS p...



details:   https://anonhg.NetBSD.org/src/rev/c9fb92e95bde
branches:  trunk
changeset: 834743:c9fb92e95bde
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Sun Aug 26 21:28:18 2018 +0000

description:
Add support for booting kernels from FFS partitions.

diffstat:

 sys/stand/efiboot/Makefile.efiboot |    8 +-
 sys/stand/efiboot/boot.c           |   51 ++++-
 sys/stand/efiboot/conf.c           |   11 +-
 sys/stand/efiboot/devopen.c        |    7 +-
 sys/stand/efiboot/efiblock.c       |  350 +++++++++++++++++++++++++++++++++++++
 sys/stand/efiboot/efiblock.h       |   71 +++++++
 sys/stand/efiboot/efiboot.c        |    4 +-
 sys/stand/efiboot/efiboot.h        |    8 +-
 sys/stand/efiboot/efidev.c         |   59 ++++++
 sys/stand/efiboot/efifile.c        |   34 +--
 10 files changed, 567 insertions(+), 36 deletions(-)

diffs (truncated from 824 to 300 lines):

diff -r 59a3301a7fae -r c9fb92e95bde sys/stand/efiboot/Makefile.efiboot
--- a/sys/stand/efiboot/Makefile.efiboot        Sun Aug 26 21:06:46 2018 +0000
+++ b/sys/stand/efiboot/Makefile.efiboot        Sun Aug 26 21:28:18 2018 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile.efiboot,v 1.1 2018/08/24 02:01:06 jmcneill Exp $
+# $NetBSD: Makefile.efiboot,v 1.2 2018/08/26 21:28:18 jmcneill Exp $
 
 S=             ${.CURDIR}/../../..
 
@@ -22,7 +22,7 @@
 .PATH: ${EFIDIR}/gnuefi
 SOURCES=       crt0-efi-${GNUEFIARCH}.S reloc_${GNUEFIARCH}.c
 SOURCES+=      boot.c conf.c console.c devopen.c exec.c panic.c prompt.c
-SOURCES+=      efiboot.c efichar.c efifdt.c efifile.c
+SOURCES+=      efiboot.c efichar.c efidev.c efifdt.c efifile.c efiblock.c
 
 .PATH: ${S}/external/bsd/libfdt/dist
 CPPFLAGS+=     -I${S}/external/bsd/libfdt/dist
@@ -74,7 +74,7 @@
 #CPPFLAGS+= -DSUPPORT_DHCP
 #CPPFLAGS+= -DSUPPORT_NFS
 #CPPFLAGS+= -DSUPPORT_TFTP
-#CPPFLAGS+= -DLIBSA_ENABLE_LS_OP
+CPPFLAGS+= -DLIBSA_ENABLE_LS_OP
 
 #CPPFLAGS+= -DARP_DEBUG
 #CPPFLAGS+= -DBOOTP_DEBUG
@@ -93,7 +93,7 @@
 SAMISCMAKEFLAGS+="SA_USE_LOADFILE=yes"
 SAMISCMAKEFLAGS+="SA_USE_CREAD=yes"
 #SAMISCMAKEFLAGS+="SA_INCLUDE_NET=yes"
-#SAMISCMAKEFLAGS+="SA_ENABLE_LS_OP=yes"
+SAMISCMAKEFLAGS+="SA_ENABLE_LS_OP=yes"
 .include "${S}/lib/libsa/Makefile.inc"
 LIBSA= ${SALIB}
 
diff -r 59a3301a7fae -r c9fb92e95bde sys/stand/efiboot/boot.c
--- a/sys/stand/efiboot/boot.c  Sun Aug 26 21:06:46 2018 +0000
+++ b/sys/stand/efiboot/boot.c  Sun Aug 26 21:28:18 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: boot.c,v 1.2 2018/08/24 23:22:10 jmcneill Exp $        */
+/*     $NetBSD: boot.c,v 1.3 2018/08/26 21:28:18 jmcneill Exp $        */
 
 /*-
  * Copyright (c) 2016 Kimihiro Nonaka <nonaka%netbsd.org@localhost>
@@ -28,6 +28,7 @@
  */
 
 #include "efiboot.h"
+#include "efiblock.h"
 
 #include <sys/bootblock.h>
 #include <sys/boot_flag.h>
@@ -40,9 +41,9 @@
 extern char twiddle_toggle;
 
 static const char * const names[][2] = {
-       { "\\netbsd", "\\netbsd.gz" },
-       { "\\onetbsd", "\\onetbsd.gz" },
-       { "\\netbsd.old", "\\netbsd.old.gz" },
+       { "netbsd", "netbsd.gz" },
+       { "onetbsd", "onetbsd.gz" },
+       { "netbsd.old", "netbsd.old.gz" },
 };
 
 #define NUMNAMES       __arraycount(names)
@@ -50,13 +51,19 @@
 
 #define        DEFTIMEOUT      5
 
+static char default_device[32];
+
 void   command_boot(char *);
+void   command_dev(char *);
+void   command_ls(char *);
 void   command_reset(char *);
 void   command_version(char *);
 void   command_quit(char *);
 
 const struct boot_command commands[] = {
        { "boot",       command_boot,           "boot [fsN:][filename] [args]\n     (ex. \"fs0:\\netbsd.old -s\"" },
+       { "dev",        command_dev,            "dev" },
+       { "ls",         command_ls,             "ls [hdNn:/path]\n" },
        { "version",    command_version,        "version" },
        { "help",       command_help,           "help|?" },
        { "?",          command_help,           NULL },
@@ -86,6 +93,27 @@
 }
 
 void
+command_dev(char *arg)
+{
+       if (arg && *arg) {
+               set_default_device(arg);
+       } else {
+               efi_block_show();
+       }
+
+       if (strlen(default_device) > 0) {
+               printf("\n");
+               printf("default: %s\n", default_device);
+       }
+}
+
+void
+command_ls(char *arg)
+{
+       ls(arg);
+}
+
+void
 command_version(char *arg)
 {
        char *ufirmware;
@@ -109,6 +137,21 @@
        efi_exit();
 }
 
+int
+set_default_device(char *arg)
+{
+       if (strlen(arg) + 1 > sizeof(default_device))
+               return ERANGE;
+       strcpy(default_device, arg);
+       return 0;
+}
+
+char *
+get_default_device(void)
+{
+       return default_device;
+}
+
 void
 print_banner(void)
 {
diff -r 59a3301a7fae -r c9fb92e95bde sys/stand/efiboot/conf.c
--- a/sys/stand/efiboot/conf.c  Sun Aug 26 21:06:46 2018 +0000
+++ b/sys/stand/efiboot/conf.c  Sun Aug 26 21:28:18 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: conf.c,v 1.1 2018/08/24 02:01:06 jmcneill Exp $ */
+/* $NetBSD: conf.c,v 1.2 2018/08/26 21:28:18 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2018 Jared McNeill <jmcneill%invisible.ca@localhost>
@@ -28,9 +28,15 @@
 
 #include "efiboot.h"
 #include "efifile.h"
+#include "efiblock.h"
+
+#include <lib/libsa/stand.h>
+#include <lib/libsa/ufs.h>
+#include <lib/libsa/dosfs.h>
 
 struct devsw devsw[] = {
        { "efifile", efi_file_strategy, efi_file_open, efi_file_close, noioctl },
+       { "efiblock", efi_block_strategy, efi_block_open, efi_block_close, noioctl },
 };
 int ndevs = __arraycount(devsw);
 
@@ -39,5 +45,8 @@
 int n_netif_drivers = __arraycount(netif_drivers);
 
 struct fs_ops file_system[] = {
+       FS_OPS(ffsv1),
+       FS_OPS(ffsv2),
+       FS_OPS(dosfs),
 };
 int nfsys = __arraycount(file_system);
diff -r 59a3301a7fae -r c9fb92e95bde sys/stand/efiboot/devopen.c
--- a/sys/stand/efiboot/devopen.c       Sun Aug 26 21:06:46 2018 +0000
+++ b/sys/stand/efiboot/devopen.c       Sun Aug 26 21:28:18 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: devopen.c,v 1.1 2018/08/24 02:01:06 jmcneill Exp $ */
+/* $NetBSD: devopen.c,v 1.2 2018/08/26 21:28:18 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2018 Jared McNeill <jmcneill%invisible.ca@localhost>
@@ -28,13 +28,16 @@
 
 #include "efiboot.h"
 #include "efifile.h"
+#include "efiblock.h"
 
 int
 devopen(struct open_file *f, const char *fname, char **file)
 {
        int error;
 
-       error = efi_file_open(f, fname);
+       error = efi_block_open(f, fname, file);
+       if (error)
+               error = efi_file_open(f, fname);
 
        return error;
 }
diff -r 59a3301a7fae -r c9fb92e95bde sys/stand/efiboot/efiblock.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/stand/efiboot/efiblock.c      Sun Aug 26 21:28:18 2018 +0000
@@ -0,0 +1,350 @@
+/* $NetBSD: efiblock.c,v 1.1 2018/08/26 21:28:18 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2016 Kimihiro Nonaka <nonaka%netbsd.org@localhost>
+ * Copyright (c) 2018 Jared McNeill <jmcneill%invisible.ca@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.
+ */
+
+#define FSTYPENAMES
+
+#include <sys/param.h>
+
+#include "efiboot.h"
+#include "efiblock.h"
+
+static EFI_HANDLE *efi_block;
+static UINTN efi_nblock;
+
+static TAILQ_HEAD(, efi_block_dev) efi_block_devs = TAILQ_HEAD_INITIALIZER(efi_block_devs);
+
+static int
+efi_block_parse(const char *fname, struct efi_block_part **pbpart, char **pfile)
+{
+       struct efi_block_dev *bdev;
+       struct efi_block_part *bpart;
+       char pathbuf[PATH_MAX], *default_device, *ep = NULL;
+       const char *full_path;
+       intmax_t dev;
+       int part;
+
+       default_device = get_default_device();
+       if (strchr(fname, ':') == NULL) {
+               if (strlen(default_device) > 0) {
+                       snprintf(pathbuf, sizeof(pathbuf), "%s:%s", default_device, fname);
+                       full_path = pathbuf;
+                       *pfile = __UNCONST(fname);
+               } else {
+                       return EINVAL;
+               }
+       } else {
+               full_path = fname;
+               *pfile = strchr(fname, ':') + 1;
+       }
+
+       if (strncasecmp(full_path, "hd", 2) != 0)
+               return EINVAL;
+       dev = strtoimax(full_path + 2, &ep, 10);
+       if (dev < 0 || dev >= efi_nblock)
+               return ENXIO;
+       if (ep[0] < 'a' || ep[0] >= 'a' + MAXPARTITIONS || ep[1] != ':')
+               return EINVAL;
+       part = ep[0] - 'a';
+       TAILQ_FOREACH(bdev, &efi_block_devs, entries) {
+               if (bdev->index == dev) {
+                       TAILQ_FOREACH(bpart, &bdev->partitions, entries) {
+                               if (bpart->index == part) {
+                                       *pbpart = bpart;
+                                       return 0;
+                               }
+                       }
+               }
+       }
+
+       return ENOENT;
+}
+
+static int
+efi_block_find_partitions_disklabel(struct efi_block_dev *bdev, uint32_t start, uint32_t size)
+{
+       struct efi_block_part *bpart;
+       struct disklabel d;
+       struct partition *p;
+       EFI_STATUS status;
+       EFI_LBA lba;
+       uint8_t *buf;
+       UINT32 sz;
+       int n;
+



Home | Main Index | Thread Index | Old Index