Module Name: src Committed By: jmcneill Date: Sun Sep 9 13:37:54 UTC 2018
Modified Files: src/sys/stand/efiboot: boot.c efiboot.h efifdt.c efifdt.h exec.c Log Message: Add "dtb" command for loading a custom .dtb file. To generate a diff of this commit: cvs rdiff -u -r1.6 -r1.7 src/sys/stand/efiboot/boot.c cvs rdiff -u -r1.4 -r1.5 src/sys/stand/efiboot/efiboot.h \ src/sys/stand/efiboot/exec.c cvs rdiff -u -r1.8 -r1.9 src/sys/stand/efiboot/efifdt.c cvs rdiff -u -r1.3 -r1.4 src/sys/stand/efiboot/efifdt.h 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/boot.c diff -u src/sys/stand/efiboot/boot.c:1.6 src/sys/stand/efiboot/boot.c:1.7 --- src/sys/stand/efiboot/boot.c:1.6 Fri Sep 7 17:30:58 2018 +++ src/sys/stand/efiboot/boot.c Sun Sep 9 13:37:54 2018 @@ -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 <non...@netbsd.org> @@ -54,9 +54,11 @@ static const char * const names[][2] = { 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 @@ void command_quit(char *); 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 @@ command_dev(char *arg) } void +command_dtb(char *arg) +{ + set_dtb_path(arg); +} + +void command_initrd(char *arg) { set_initrd_path(arg); @@ -181,6 +190,21 @@ get_initrd_path(void) 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) { Index: src/sys/stand/efiboot/efiboot.h diff -u src/sys/stand/efiboot/efiboot.h:1.4 src/sys/stand/efiboot/efiboot.h:1.5 --- src/sys/stand/efiboot/efiboot.h:1.4 Fri Sep 7 17:30:58 2018 +++ src/sys/stand/efiboot/efiboot.h Sun Sep 9 13:37:54 2018 @@ -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 <non...@netbsd.org> @@ -54,6 +54,8 @@ int set_default_device(char *); 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); Index: src/sys/stand/efiboot/exec.c diff -u src/sys/stand/efiboot/exec.c:1.4 src/sys/stand/efiboot/exec.c:1.5 --- src/sys/stand/efiboot/exec.c:1.4 Fri Sep 7 17:30:58 2018 +++ src/sys/stand/efiboot/exec.c Sun Sep 9 13:37:54 2018 @@ -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 <jmcne...@invisible.ca> @@ -36,19 +36,17 @@ u_long load_offset = 0; #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 @@ load_initrd(void) 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 @@ exec_netbsd(const char *fname, const cha 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 @@ exec_netbsd(const char *fname, const cha 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 @@ cleanup: 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; } Index: src/sys/stand/efiboot/efifdt.c diff -u src/sys/stand/efiboot/efifdt.c:1.8 src/sys/stand/efiboot/efifdt.c:1.9 --- src/sys/stand/efiboot/efifdt.c:1.8 Fri Sep 7 17:30:58 2018 +++ src/sys/stand/efiboot/efifdt.c Sun Sep 9 13:37:54 2018 @@ -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 <jmcne...@invisible.ca> @@ -65,6 +65,16 @@ efi_fdt_probe(void) 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) { Index: src/sys/stand/efiboot/efifdt.h diff -u src/sys/stand/efiboot/efifdt.h:1.3 src/sys/stand/efiboot/efifdt.h:1.4 --- src/sys/stand/efiboot/efifdt.h:1.3 Fri Sep 7 17:30:58 2018 +++ src/sys/stand/efiboot/efifdt.h Sun Sep 9 13:37:54 2018 @@ -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 <jmcne...@invisible.ca> @@ -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);