Module Name: src Committed By: jmcneill Date: Sun Sep 13 18:13:37 UTC 2009
Modified Files: src/sys/arch/i386/stand/lib: exec.c Log Message: kmod improvements - unless otherwise specified, modules are now loaded from the same device as the kernel ('load miniroot' now implies 'load tftp:miniroot' if the boot command is 'boot tftp:netbsd') - the module name -> path expansion now works when a device prefix: is specified ('load tftp:miniroot' now works) - if the module name has been expanded to a path, print that path when loading the module rather than the symbolic name - only print an error in module_open if both the expanded path and the raw path fail to open To generate a diff of this commit: cvs rdiff -u -r1.40 -r1.41 src/sys/arch/i386/stand/lib/exec.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/i386/stand/lib/exec.c diff -u src/sys/arch/i386/stand/lib/exec.c:1.40 src/sys/arch/i386/stand/lib/exec.c:1.41 --- src/sys/arch/i386/stand/lib/exec.c:1.40 Sat Mar 21 15:01:56 2009 +++ src/sys/arch/i386/stand/lib/exec.c Sun Sep 13 18:13:37 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: exec.c,v 1.40 2009/03/21 15:01:56 ad Exp $ */ +/* $NetBSD: exec.c,v 1.41 2009/09/13 18:13:37 jmcneill Exp $ */ /*- * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. @@ -124,6 +124,8 @@ #define PAGE_SIZE 4096 #endif +#define MODULE_WARNING_DELAY 5000000 + extern struct btinfo_console btinfo_console; boot_module_t *boot_modules; @@ -138,7 +140,7 @@ static char module_base[64] = "/"; static int howto; -static void module_init(void); +static void module_init(const char *); void framebuffer_configure(struct btinfo_framebuffer *fb) @@ -304,7 +306,7 @@ /* pull in any modules if necessary */ if (boot_modules_enabled) { - module_init(); + module_init(file); if (btinfo_modulelist) { BI_ADD(btinfo_modulelist, BTINFO_MODULELIST, btinfo_modulelist_size); @@ -333,12 +335,26 @@ return -1; } +static void +extract_device(const char *path, char *buf, size_t buflen) +{ + int i; + + if (strchr(path, ':') != NULL) { + for (i = 0; i < buflen - 2 && path[i] != ':'; i++) + buf[i] = path[i]; + buf[i++] = ':'; + buf[i] = '\0'; + } else + buf[0] = '\0'; +} + static const char * -module_path(boot_module_t *bm) +module_path(boot_module_t *bm, const char *kdev) { static char buf[256]; - char name_buf[256]; - const char *name, *name2; + char name_buf[256], dev_buf[64]; + const char *name, *name2, *p; name = bm->bm_path; for (name2 = name; *name2; ++name2) { @@ -350,45 +366,69 @@ break; } } - if (name[0] == '/') - snprintf(buf, sizeof(buf), "%s", name); - else - snprintf(buf, sizeof(buf), "%s/%s/%s.kmod", - module_base, name, name); + if ((p = strchr(name, ':')) != NULL) { + /* device specified, use it */ + if (p[1] == '/') + snprintf(buf, sizeof(buf), "%s", name); + else { + p++; + extract_device(name, dev_buf, sizeof(dev_buf)); + snprintf(buf, sizeof(buf), "%s%s/%s/%s.kmod", + dev_buf, module_base, p, p); + } + } else { + /* device not specified; load from kernel device if known */ + if (name[0] == '/') + snprintf(buf, sizeof(buf), "%s%s", kdev, name); + else + snprintf(buf, sizeof(buf), "%s%s/%s/%s.kmod", + kdev, module_base, name, name); + } return buf; } static int -module_open(boot_module_t *bm, int mode) +module_open(boot_module_t *bm, int mode, const char *kdev, bool doload) { int fd; const char *path; /* check the expanded path first */ - path = module_path(bm); + path = module_path(bm, kdev); fd = open(path, mode); - if (fd == -1) { - printf("WARNING: couldn't open %s\n", path); + if (fd != -1) { + if ((howto & AB_SILENT) == 0 && doload) + printf("Loading %s ", path); + } else { /* now attempt the raw path provided */ fd = open(bm->bm_path, mode); - if (fd == -1) - printf("WARNING: couldn't open %s\n", bm->bm_path); + if (fd != -1 && (howto & AB_SILENT) == 0 && doload) + printf("Loading %s ", bm->bm_path); + } + if (!doload && fd == -1) { + printf("WARNING: couldn't open %s", bm->bm_path); + if (strcmp(bm->bm_path, path) != 0) + printf(" (%s)", path); + printf("\n"); } return fd; } static void -module_init(void) +module_init(const char *kernel_path) { struct bi_modulelist_entry *bi; struct stat st; const char *machine; + char kdev[64]; char *buf; boot_module_t *bm; size_t len; off_t off; - int err, fd; + int err, fd, nfail = 0; + + extract_device(kernel_path, kdev, sizeof(kdev)); switch (netbsd_elf_class) { case ELFCLASS32: @@ -419,9 +459,10 @@ /* First, see which modules are valid and calculate btinfo size */ len = sizeof(struct btinfo_modulelist); for (bm = boot_modules; bm; bm = bm->bm_next) { - fd = module_open(bm, 0); + fd = module_open(bm, 0, kdev, false); if (fd == -1) { bm->bm_len = -1; + ++nfail; continue; } err = fstat(fd, &st); @@ -429,6 +470,7 @@ printf("WARNING: couldn't stat %s\n", bm->bm_path); close(fd); bm->bm_len = -1; + ++nfail; continue; } bm->bm_len = st.st_size; @@ -440,6 +482,7 @@ btinfo_modulelist = alloc(len); if (btinfo_modulelist == NULL) { printf("WARNING: couldn't allocate module list\n"); + delay(MODULE_WARNING_DELAY); return; } memset(btinfo_modulelist, 0, len); @@ -453,13 +496,9 @@ for (bm = boot_modules; bm; bm = bm->bm_next) { if (bm->bm_len == -1) continue; - if ((howto & AB_SILENT) == 0) - printf("Loading %s ", bm->bm_path); - fd = module_open(bm, 0); - if (fd == -1) { - printf("ERROR: couldn't open %s\n", bm->bm_path); + fd = module_open(bm, 0, kdev, true); + if (fd == -1) continue; - } image_end = (image_end + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); len = pread(fd, (void *)image_end, SSIZE_MAX); if (len < bm->bm_len) { @@ -482,6 +521,14 @@ close(fd); } btinfo_modulelist->endpa = image_end; + + if (nfail > 0) { + printf("WARNING: %d module%s failed to load\n", + nfail, nfail == 1 ? "" : "s"); +#if notyet + delay(MODULE_WARNING_DELAY); +#endif + } } int @@ -515,7 +562,7 @@ /* pull in any modules if necessary */ if (boot_modules_enabled) { - module_init(); + module_init(file); if (btinfo_modulelist) { mbm = alloc(sizeof(struct multiboot_module) * btinfo_modulelist->num);