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 "dtb" command for loading a custom .dt...



details:   https://anonhg.NetBSD.org/src/rev/831939d40c04
branches:  trunk
changeset: 433353:831939d40c04
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Sun Sep 09 13:37:54 2018 +0000

description:
Add "dtb" command for loading a custom .dtb file.

diffstat:

 sys/stand/efiboot/boot.c    |  26 +++++++++++++++++++++++-
 sys/stand/efiboot/efiboot.h |   4 ++-
 sys/stand/efiboot/efifdt.c  |  12 ++++++++++-
 sys/stand/efiboot/efifdt.h  |   3 +-
 sys/stand/efiboot/exec.c    |  47 ++++++++++++++++++++++++++------------------
 5 files changed, 69 insertions(+), 23 deletions(-)

diffs (247 lines):

diff -r 3a29446f2d2c -r 831939d40c04 sys/stand/efiboot/boot.c
--- a/sys/stand/efiboot/boot.c  Sun Sep 09 13:32:26 2018 +0000
+++ b/sys/stand/efiboot/boot.c  Sun Sep 09 13:37:54 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: boot.c,v 1.6 2018/09/07 17:30:58 jmcneill Exp $        */
+/*     $NetBSD: boot.c,v 1.7 2018/09/09 13:37:54 jmcneill Exp $        */
 
 /*-
  * Copyright (c) 2016 Kimihiro Nonaka <nonaka%netbsd.org@localhost>
@@ -54,9 +54,11 @@
 
 static char default_device[32];
 static char initrd_path[255];
+static char dtb_path[255];
 
 void   command_boot(char *);
 void   command_dev(char *);
+void   command_dtb(char *);
 void   command_initrd(char *);
 void   command_ls(char *);
 void   command_reset(char *);
@@ -66,6 +68,7 @@
 const struct boot_command commands[] = {
        { "boot",       command_boot,           "boot [dev:][filename] [args]\n     (ex. \"hd0a:\\netbsd.old -s\"" },
        { "dev",        command_dev,            "dev" },
+       { "dtb",        command_dtb,            "dtb [dev:][filename]" },
        { "initrd",     command_initrd,         "initrd [dev:][filename]" },
        { "ls",         command_ls,             "ls [hdNn:/path]" },
        { "version",    command_version,        "version" },
@@ -114,6 +117,12 @@
 }
 
 void
+command_dtb(char *arg)
+{
+       set_dtb_path(arg);
+}
+
+void
 command_initrd(char *arg)
 {
        set_initrd_path(arg);
@@ -181,6 +190,21 @@
        return initrd_path;
 }
 
+int
+set_dtb_path(char *arg)
+{
+       if (strlen(arg) + 1 > sizeof(dtb_path))
+               return ERANGE;
+       strcpy(dtb_path, arg);
+       return 0;
+}
+
+char *
+get_dtb_path(void)
+{
+       return dtb_path;
+}
+
 void
 print_banner(void)
 {
diff -r 3a29446f2d2c -r 831939d40c04 sys/stand/efiboot/efiboot.h
--- a/sys/stand/efiboot/efiboot.h       Sun Sep 09 13:32:26 2018 +0000
+++ b/sys/stand/efiboot/efiboot.h       Sun Sep 09 13:37:54 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: efiboot.h,v 1.4 2018/09/07 17:30:58 jmcneill Exp $     */
+/*     $NetBSD: efiboot.h,v 1.5 2018/09/09 13:37:54 jmcneill Exp $     */
 
 /*-
  * Copyright (c) 2016 Kimihiro Nonaka <nonaka%netbsd.org@localhost>
@@ -54,6 +54,8 @@
 char *get_default_device(void);
 int set_initrd_path(char *);
 char *get_initrd_path(void);
+int set_dtb_path(char *);
+char *get_dtb_path(void);
 
 /* console.c */
 int ischar(void);
diff -r 3a29446f2d2c -r 831939d40c04 sys/stand/efiboot/efifdt.c
--- a/sys/stand/efiboot/efifdt.c        Sun Sep 09 13:32:26 2018 +0000
+++ b/sys/stand/efiboot/efifdt.c        Sun Sep 09 13:37:54 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: efifdt.c,v 1.8 2018/09/07 17:30:58 jmcneill Exp $ */
+/* $NetBSD: efifdt.c,v 1.9 2018/09/09 13:37:54 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2018 Jared McNeill <jmcneill%invisible.ca@localhost>
@@ -65,6 +65,16 @@
        return 0;
 }
 
+int
+efi_fdt_set_data(void *data)
+{
+       if (fdt_check_header(data) != 0)
+               return EINVAL;
+
+       fdt_data = data;
+       return 0;
+}
+
 void *
 efi_fdt_data(void)
 {
diff -r 3a29446f2d2c -r 831939d40c04 sys/stand/efiboot/efifdt.h
--- a/sys/stand/efiboot/efifdt.h        Sun Sep 09 13:32:26 2018 +0000
+++ b/sys/stand/efiboot/efifdt.h        Sun Sep 09 13:37:54 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: efifdt.h,v 1.3 2018/09/07 17:30:58 jmcneill Exp $ */
+/* $NetBSD: efifdt.h,v 1.4 2018/09/09 13:37:54 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2018 Jared McNeill <jmcneill%invisible.ca@localhost>
@@ -28,6 +28,7 @@
 
 int efi_fdt_probe(void);
 void efi_fdt_memory_map(void);
+int efi_fdt_set_data(void *);
 void *efi_fdt_data(void);
 int efi_fdt_size(void);
 void efi_fdt_show(void);
diff -r 3a29446f2d2c -r 831939d40c04 sys/stand/efiboot/exec.c
--- a/sys/stand/efiboot/exec.c  Sun Sep 09 13:32:26 2018 +0000
+++ b/sys/stand/efiboot/exec.c  Sun Sep 09 13:37:54 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: exec.c,v 1.4 2018/09/07 17:30:58 jmcneill Exp $ */
+/* $NetBSD: exec.c,v 1.5 2018/09/09 13:37:54 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2018 Jared McNeill <jmcneill%invisible.ca@localhost>
@@ -36,19 +36,17 @@
 #define        FDT_SPACE       (4 * 1024 * 1024)
 #define        FDT_ALIGN       ((2 * 1024 * 1024) - 1)
 
-static EFI_PHYSICAL_ADDRESS initrd_addr;
-static u_long initrd_size = 0;
+static EFI_PHYSICAL_ADDRESS initrd_addr, dtb_addr;
+static u_long initrd_size = 0, dtb_size = 0;
 
 static int
-load_initrd(void)
+load_file(char *path, EFI_PHYSICAL_ADDRESS *paddr, u_long *psize)
 {
        EFI_STATUS status;
        struct stat st;
        ssize_t len;
-       char *path;
        int fd;
 
-       path = get_initrd_path();
        if (strlen(path) == 0)
                return 0;
 
@@ -63,44 +61,44 @@
                return errno;
        }
        if (st.st_size == 0) {
-               printf("boot: empty initrd %s\n", path);
+               printf("boot: empty file %s\n", path);
                close(fd);
                return EINVAL;
        }
 
-       initrd_size = st.st_size;
+       *psize = st.st_size;
 
 #ifdef EFIBOOT_ALLOCATE_MAX_ADDRESS
-       initrd_addr = EFIBOOT_ALLOCATE_MAX_ADDRESS;
+       *paddr = EFIBOOT_ALLOCATE_MAX_ADDRESS;
        status = uefi_call_wrapper(BS->AllocatePages, 4, AllocateMaxAddress, EfiLoaderData,
-           EFI_SIZE_TO_PAGES(initrd_size), &initrd_addr);
+           EFI_SIZE_TO_PAGES(*psize), paddr);
 #else
-       initrd_addr = 0;
+       *paddr = 0;
        status = uefi_call_wrapper(BS->AllocatePages, 4, AllocateAnyPages, EfiLoaderData,
-           EFI_SIZE_TO_PAGES(initrd_size), &initrd_addr);
+           EFI_SIZE_TO_PAGES(*psize), paddr);
 #endif
        if (EFI_ERROR(status)) {
-               printf("Failed to allocate %lu bytes for initrd image (error %lu)\n",
-                   initrd_size, status);
+               printf("Failed to allocate %lu bytes for %s (error %lu)\n",
+                   *psize, path, status);
                close(fd);
                return ENOMEM;
        }
 
        printf("boot: loading %s ", path);
-       len = read(fd, (void *)initrd_addr, initrd_size);
+       len = read(fd, (void *)*paddr, *psize);
        close(fd);
 
-       if (len != initrd_size) {
+       if (len != *psize) {
                if (len < 0)
                        printf(": %s\n", strerror(errno));
                else
-                       printf(": returned %ld (expected %ld)\n", len, initrd_size);
+                       printf(": returned %ld (expected %ld)\n", len, *psize);
                return EIO;
        }
 
        printf("done.\n");
 
-       efi_dcache_flush(initrd_addr, initrd_size);
+       efi_dcache_flush(*paddr, *psize);
 
        return 0;
 }
@@ -113,7 +111,8 @@
        EFI_STATUS status;
        int fd;
 
-       load_initrd();
+       load_file(get_initrd_path(), &initrd_addr, &initrd_size);
+       load_file(get_dtb_path(), &dtb_addr, &dtb_size);
 
        memset(marks, 0, sizeof(marks));
        fd = loadfile(fname, marks, COUNT_KERNEL | LOAD_NOTE);
@@ -150,6 +149,11 @@
        close(fd);
        load_offset = 0;
 
+       if (dtb_addr && efi_fdt_set_data((void *)dtb_addr) != 0) {
+               printf("boot: invalid DTB data\n");
+               goto cleanup;
+       }
+
        if (efi_fdt_size() > 0) {
                efi_fdt_init((marks[MARK_END] + FDT_ALIGN) & ~FDT_ALIGN, FDT_ALIGN + 1);
                efi_fdt_initrd(initrd_addr, initrd_size);
@@ -171,5 +175,10 @@
                initrd_addr = 0;
                initrd_size = 0;
        }
+       if (dtb_addr) {
+               uefi_call_wrapper(BS->FreePages, 2, dtb_addr, EFI_SIZE_TO_PAGES(dtb_size));
+               dtb_addr = 0;
+               dtb_size = 0;
+       }
        return EIO;
 }



Home | Main Index | Thread Index | Old Index