Module Name: src Committed By: jmcneill Date: Sun Jun 21 17:24:26 UTC 2020
Modified Files: src/sys/stand/efiboot: Makefile.efiboot boot.c efifdt.c efifdt.h exec.c version src/sys/stand/efiboot/bootaa64: Makefile src/sys/stand/efiboot/bootarm: Makefile Added Files: src/sys/stand/efiboot: module.c module.h Log Message: Add module support. To generate a diff of this commit: cvs rdiff -u -r1.13 -r1.14 src/sys/stand/efiboot/Makefile.efiboot cvs rdiff -u -r1.21 -r1.22 src/sys/stand/efiboot/boot.c cvs rdiff -u -r1.23 -r1.24 src/sys/stand/efiboot/efifdt.c cvs rdiff -u -r1.8 -r1.9 src/sys/stand/efiboot/efifdt.h cvs rdiff -u -r1.15 -r1.16 src/sys/stand/efiboot/exec.c \ src/sys/stand/efiboot/version cvs rdiff -u -r0 -r1.1 src/sys/stand/efiboot/module.c \ src/sys/stand/efiboot/module.h cvs rdiff -u -r1.7 -r1.8 src/sys/stand/efiboot/bootaa64/Makefile cvs rdiff -u -r1.4 -r1.5 src/sys/stand/efiboot/bootarm/Makefile 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/Makefile.efiboot diff -u src/sys/stand/efiboot/Makefile.efiboot:1.13 src/sys/stand/efiboot/Makefile.efiboot:1.14 --- src/sys/stand/efiboot/Makefile.efiboot:1.13 Thu May 14 19:19:08 2020 +++ src/sys/stand/efiboot/Makefile.efiboot Sun Jun 21 17:24:26 2020 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile.efiboot,v 1.13 2020/05/14 19:19:08 riastradh Exp $ +# $NetBSD: Makefile.efiboot,v 1.14 2020/06/21 17:24:26 jmcneill Exp $ S= ${.CURDIR}/../../.. @@ -21,8 +21,10 @@ AFLAGS.start.S= ${${ACTIVE_CC} == "clang .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 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 +SOURCES+= boot.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 .PATH: ${S}/external/bsd/libfdt/dist CPPFLAGS+= -I${S}/external/bsd/libfdt/dist Index: src/sys/stand/efiboot/boot.c diff -u src/sys/stand/efiboot/boot.c:1.21 src/sys/stand/efiboot/boot.c:1.22 --- src/sys/stand/efiboot/boot.c:1.21 Thu May 14 19:19:08 2020 +++ src/sys/stand/efiboot/boot.c Sun Jun 21 17:24:26 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: boot.c,v 1.21 2020/05/14 19:19:08 riastradh Exp $ */ +/* $NetBSD: boot.c,v 1.22 2020/06/21 17:24:26 jmcneill Exp $ */ /*- * Copyright (c) 2016 Kimihiro Nonaka <non...@netbsd.org> @@ -33,6 +33,7 @@ #include "efiacpi.h" #include "efienv.h" #include "efirng.h" +#include "module.h" #include <sys/bootblock.h> #include <sys/boot_flag.h> @@ -90,6 +91,9 @@ void command_dtb(char *); void command_plist(char *); void command_initrd(char *); void command_rndseed(char *); +void command_modules(char *); +void command_load(char *); +void command_unload(char *); void command_ls(char *); void command_mem(char *); void command_printenv(char *); @@ -107,6 +111,9 @@ const struct boot_command commands[] = { { "plist", command_plist, "plist [dev:][filename]" }, { "initrd", command_initrd, "initrd [dev:][filename]" }, { "rndseed", command_rndseed, "rndseed [dev:][filename]" }, + { "modules", command_modules, "modules [{on|off|reset}]" }, + { "load", command_load, "load <module_name>" }, + { "unload", command_unload, "unload <module_name>" }, { "ls", command_ls, "ls [hdNn:/path]" }, { "mem", command_mem, "mem" }, { "printenv", command_printenv, "printenv [key]" }, @@ -193,6 +200,47 @@ command_rndseed(char *arg) } void +command_modules(char *arg) +{ + if (arg && *arg) { + if (strcmp(arg, "on") == 0) + module_enable(1); + else if (strcmp(arg, "off") == 0) + module_enable(0); + else if (strcmp(arg, "reset") == 0) + module_remove_all(); + else { + command_help(""); + return; + } + } else { + printf("modules are %sabled\n", module_enabled ? "en" : "dis"); + } +} + +void +command_load(char *arg) +{ + if (!arg || !*arg) { + command_help(""); + return; + } + + module_add(arg); +} + +void +command_unload(char *arg) +{ + if (!arg || !*arg) { + command_help(""); + return; + } + + module_remove(arg); +} + +void command_ls(char *arg) { ls(arg); Index: src/sys/stand/efiboot/efifdt.c diff -u src/sys/stand/efiboot/efifdt.c:1.23 src/sys/stand/efiboot/efifdt.c:1.24 --- src/sys/stand/efiboot/efifdt.c:1.23 Thu May 14 19:21:53 2020 +++ src/sys/stand/efiboot/efifdt.c Sun Jun 21 17:24:26 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: efifdt.c,v 1.23 2020/05/14 19:21:53 riastradh Exp $ */ +/* $NetBSD: efifdt.c,v 1.24 2020/06/21 17:24:26 jmcneill Exp $ */ /*- * Copyright (c) 2019 Jason R. Thorpe @@ -425,3 +425,18 @@ efi_fdt_efirng(u_long efirng_addr, u_lon fdt_setprop_u64(fdt_data, chosen, "netbsd,efirng-end", efirng_addr + efirng_size); } + +/* pass in module information */ +void +efi_fdt_module(const char *module_name, u_long module_addr, u_long module_size) +{ + int chosen; + + if (module_size == 0) + return; + + chosen = efi_fdt_chosen(); + fdt_appendprop_string(fdt_data, chosen, "netbsd,module-names", module_name); + fdt_appendprop_u64(fdt_data, chosen, "netbsd,modules", module_addr); + fdt_appendprop_u64(fdt_data, chosen, "netbsd,modules", module_size); +} Index: src/sys/stand/efiboot/efifdt.h diff -u src/sys/stand/efiboot/efifdt.h:1.8 src/sys/stand/efiboot/efifdt.h:1.9 --- src/sys/stand/efiboot/efifdt.h:1.8 Thu May 14 19:20:08 2020 +++ src/sys/stand/efiboot/efifdt.h Sun Jun 21 17:24:26 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: efifdt.h,v 1.8 2020/05/14 19:20:08 riastradh Exp $ */ +/* $NetBSD: efifdt.h,v 1.9 2020/06/21 17:24:26 jmcneill Exp $ */ /*- * Copyright (c) 2018 Jared McNeill <jmcne...@invisible.ca> @@ -39,5 +39,6 @@ void efi_fdt_bootargs(const char *); void efi_fdt_initrd(u_long, u_long); void efi_fdt_rndseed(u_long, u_long); void efi_fdt_efirng(u_long, u_long); +void efi_fdt_module(const char *, u_long, u_long); void efi_fdt_init(u_long, u_long); void efi_fdt_fini(void); Index: src/sys/stand/efiboot/exec.c diff -u src/sys/stand/efiboot/exec.c:1.15 src/sys/stand/efiboot/exec.c:1.16 --- src/sys/stand/efiboot/exec.c:1.15 Sat May 23 16:40:41 2020 +++ src/sys/stand/efiboot/exec.c Sun Jun 21 17:24:26 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: exec.c,v 1.15 2020/05/23 16:40:41 thorpej Exp $ */ +/* $NetBSD: exec.c,v 1.16 2020/06/21 17:24:26 jmcneill Exp $ */ /*- * Copyright (c) 2019 Jason R. Thorpe @@ -32,7 +32,9 @@ #include "efifdt.h" #include "efiacpi.h" #include "efirng.h" +#include "module.h" +#include <sys/param.h> #include <sys/reboot.h> extern char twiddle_toggle; @@ -276,6 +278,32 @@ load_fdt_overlays(void) } static void +load_module(const char *module_name) +{ + EFI_PHYSICAL_ADDRESS addr; + u_long size; + char path[PATH_MAX]; + + snprintf(path, sizeof(path), "%s/%s/%s.kmod", module_prefix, + module_name, module_name); + + if (load_file(path, 0, false, &addr, &size) != 0 || addr == 0 || size == 0) + return; + + efi_fdt_module(module_name, (u_long)addr, size); +} + +static void +load_modules(const char *kernel_name) +{ + if (!module_enabled) + return; + + module_init(kernel_name); + module_foreach(load_module); +} + +static void generate_efirng(void) { EFI_PHYSICAL_ADDRESS addr; @@ -387,6 +415,7 @@ exec_netbsd(const char *fname, const cha &rndseed_addr, &rndseed_size); efi_fdt_init((marks[MARK_END] + FDT_ALIGN) & ~FDT_ALIGN, FDT_ALIGN + 1); + load_modules(fname); load_fdt_overlays(); efi_fdt_initrd(initrd_addr, initrd_size); efi_fdt_rndseed(rndseed_addr, rndseed_size); Index: src/sys/stand/efiboot/version diff -u src/sys/stand/efiboot/version:1.15 src/sys/stand/efiboot/version:1.16 --- src/sys/stand/efiboot/version:1.15 Thu May 14 19:25:16 2020 +++ src/sys/stand/efiboot/version Sun Jun 21 17:24:26 2020 @@ -1,4 +1,4 @@ -$NetBSD: version,v 1.15 2020/05/14 19:25:16 riastradh Exp $ +$NetBSD: version,v 1.16 2020/06/21 17:24:26 jmcneill Exp $ NOTE ANY CHANGES YOU MAKE TO THE EFI BOOTLOADER HERE. The format of this file is important - make sure the entries are appended on end, last item @@ -19,3 +19,4 @@ is taken as the current. 1.12: Derive ACPI model string from SMBIOS. 1.13: Add rndseed support. 1.14: Add EFI RNG support. +1.15: Add module support. Index: src/sys/stand/efiboot/bootaa64/Makefile diff -u src/sys/stand/efiboot/bootaa64/Makefile:1.7 src/sys/stand/efiboot/bootaa64/Makefile:1.8 --- src/sys/stand/efiboot/bootaa64/Makefile:1.7 Sat Jan 25 11:24:20 2020 +++ src/sys/stand/efiboot/bootaa64/Makefile Sun Jun 21 17:24:26 2020 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.7 2020/01/25 11:24:20 jmcneill Exp $ +# $NetBSD: Makefile,v 1.8 2020/06/21 17:24:26 jmcneill Exp $ PROG= bootaa64.efi OBJFMT= binary @@ -12,6 +12,7 @@ CFLAGS+= -DEFIBOOT_ALIGN=0x200000 CFLAGS+= -DEFIBOOT_RUNTIME_ADDRESS=0xffff800000000000L CFLAGS+= -DEFIBOOT_RUNTIME_SIZE=0x40000000UL CFLAGS+= -DEFIBOOT_ACPI +CFLAGS+= -DEFIBOOT_MODULE_MACHINE=\"evbarm\" .include "${.CURDIR}/../Makefile.efiboot" Index: src/sys/stand/efiboot/bootarm/Makefile diff -u src/sys/stand/efiboot/bootarm/Makefile:1.4 src/sys/stand/efiboot/bootarm/Makefile:1.5 --- src/sys/stand/efiboot/bootarm/Makefile:1.4 Sat Jan 25 11:24:20 2020 +++ src/sys/stand/efiboot/bootarm/Makefile Sun Jun 21 17:24:26 2020 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.4 2020/01/25 11:24:20 jmcneill Exp $ +# $NetBSD: Makefile,v 1.5 2020/06/21 17:24:26 jmcneill Exp $ PROG= bootarm.efi OBJFMT= binary @@ -11,6 +11,7 @@ EXTRA_SOURCES+= cache.S COPTS+= -mfloat-abi=soft -mno-unaligned-access -ffreestanding -fno-unwind-tables CFLAGS+= -DEFIBOOT_ALIGN=0x1000000 +CFLAGS+= -DEFIBOOT_MODULE_MACHINE=\"evbarm\" LDFLAGS+= -N .include "${.CURDIR}/../Makefile.efiboot" Added files: Index: src/sys/stand/efiboot/module.c diff -u /dev/null src/sys/stand/efiboot/module.c:1.1 --- /dev/null Sun Jun 21 17:24:26 2020 +++ src/sys/stand/efiboot/module.c Sun Jun 21 17:24:26 2020 @@ -0,0 +1,153 @@ +/* $NetBSD: module.c,v 1.1 2020/06/21 17:24:26 jmcneill Exp $ */ + +/*- + * Copyright (c) 2020 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jared McNeill <jmcne...@invisible.ca>. + * + * 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. + */ + +#include "efiboot.h" +#include "module.h" + +#include <sys/queue.h> + +int module_enabled = 1; +char module_prefix[128]; + +struct boot_module { + char *module_name; + TAILQ_ENTRY(boot_module) entries; +}; +TAILQ_HEAD(, boot_module) boot_modules = TAILQ_HEAD_INITIALIZER(boot_modules); + +static const char * +module_machine(void) +{ + return EFIBOOT_MODULE_MACHINE; +} + +static void +module_set_prefix(const char *kernel_path) +{ +#ifdef KERNEL_DIR + char *ptr = strrchr(kernel_path, '/'); + if (ptr) + *ptr = '\0'; + snprintf(module_prefix, sizeof(module_prefix), "%s/modules", kernel_path); + if (ptr) + *ptr = '/'; +#else + const u_int vmajor = netbsd_version / 100000000; + const u_int vminor = netbsd_version / 1000000 % 100; + const u_int vpatch = netbsd_version / 100 % 100; + + if (vminor == 99) { + snprintf(module_prefix, sizeof(module_prefix), + "/stand/%s/%u.%u.%u/modules", module_machine(), + vmajor, vminor, vpatch); + } else if (vmajor != 0) { + snprintf(module_prefix, sizeof(module_prefix), + "/stand/%s/%u.%u/modules", module_machine(), + vmajor, vminor); + } +#endif +} + +void +module_init(const char *kernel_path) +{ + module_set_prefix(kernel_path); +} + +void +module_foreach(void (*fn)(const char *)) +{ + struct boot_module *bm; + + TAILQ_FOREACH(bm, &boot_modules, entries) { + fn(bm->module_name); + } +} + +void +module_add(const char *module_name) +{ + struct boot_module *bm; + + /* Trim leading whitespace */ + while (*module_name == ' ' || *module_name == '\t') + ++module_name; + + /* Duplicate check */ + TAILQ_FOREACH(bm, &boot_modules, entries) { + if (strcmp(bm->module_name, module_name) == 0) + return; + } + + /* Add to list of modules */ + bm = alloc(sizeof(*bm)); + const int slen = strlen(module_name) + 1; + bm->module_name = alloc(slen); + memcpy(bm->module_name, module_name, slen); + TAILQ_INSERT_TAIL(&boot_modules, bm, entries); +} + +void +module_remove(const char *module_name) +{ + struct boot_module *bm; + + /* Trim leading whitespace */ + while (*module_name == ' ' || *module_name == '\t') + ++module_name; + + TAILQ_FOREACH(bm, &boot_modules, entries) { + if (strcmp(bm->module_name, module_name) == 0) { + TAILQ_REMOVE(&boot_modules, bm, entries); + dealloc(bm->module_name, strlen(bm->module_name) + 1); + dealloc(bm, sizeof(*bm)); + return; + } + } +} + +void +module_remove_all(void) +{ + struct boot_module *bm; + + while ((bm = TAILQ_FIRST(&boot_modules)) != NULL) { + TAILQ_REMOVE(&boot_modules, bm, entries); + dealloc(bm->module_name, strlen(bm->module_name) + 1); + dealloc(bm, sizeof(*bm)); + } +} + +void +module_enable(int onoff) +{ + module_enabled = onoff; +} Index: src/sys/stand/efiboot/module.h diff -u /dev/null src/sys/stand/efiboot/module.h:1.1 --- /dev/null Sun Jun 21 17:24:26 2020 +++ src/sys/stand/efiboot/module.h Sun Jun 21 17:24:26 2020 @@ -0,0 +1,37 @@ +/* $NetBSD: module.h,v 1.1 2020/06/21 17:24:26 jmcneill Exp $ */ + +/*- + * Copyright (c) 2020 Jared McNeill <jmcne...@invisible.ca> + * 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. + */ + +/* module.c */ +extern int module_enabled; +extern char module_prefix[]; +void module_init(const char *); +void module_foreach(void (*)(const char *)); +void module_enable(int); +void module_add(const char *); +void module_remove(const char *); +void module_remove_all(void);