Module Name: src Committed By: nisimura Date: Tue Jan 11 08:04:15 UTC 2011
Modified Files: src/sys/arch/sandpoint/stand/netboot: main.c Log Message: add MODULAR loading facility. Disabled for now 'til it gets ready to use. To generate a diff of this commit: cvs rdiff -u -r1.37 -r1.38 src/sys/arch/sandpoint/stand/netboot/main.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/sandpoint/stand/netboot/main.c diff -u src/sys/arch/sandpoint/stand/netboot/main.c:1.37 src/sys/arch/sandpoint/stand/netboot/main.c:1.38 --- src/sys/arch/sandpoint/stand/netboot/main.c:1.37 Mon Jan 10 20:16:42 2011 +++ src/sys/arch/sandpoint/stand/netboot/main.c Tue Jan 11 08:04:14 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: main.c,v 1.37 2011/01/10 20:16:42 phx Exp $ */ +/* $NetBSD: main.c,v 1.38 2011/01/11 08:04:14 nisimura Exp $ */ /*- * Copyright (c) 2007 The NetBSD Foundation, Inc. @@ -71,6 +71,22 @@ struct btinfo_bootpath bi_path; struct btinfo_rootdevice bi_rdev; struct btinfo_net bi_net; +struct btinfo_modulelist *btinfo_modulelist; +size_t btinfo_modulelist_size; + +struct boot_module { + char *bm_kmod; + ssize_t bm_len; + struct boot_module *bm_next; +}; +struct boot_module *boot_modules; +char module_base[80]; +uint32_t kmodloadp; +int modules_enabled = 0; + +void module_add(char *); +void module_load(char *); +int module_open(struct boot_module *); void main(int, char **); extern char bootprog_rev[], bootprog_maker[], bootprog_date[]; @@ -171,10 +187,15 @@ marks[MARK_START] = 0; if (fdloadfile(fd, marks, LOAD_KERNEL) < 0) goto loadfail; + close(fd); + + printf("entry=%p, ssym=%p, esym=%p\n", + (void *)marks[MARK_ENTRY], + (void *)marks[MARK_SYM], + (void *)marks[MARK_END]); bootinfo = (void *)0x4000; bi_init(bootinfo); - bi_add(&bi_cons, BTINFO_CONSOLE, sizeof(bi_cons)); bi_add(&bi_mem, BTINFO_MEMORY, sizeof(bi_mem)); bi_add(&bi_clk, BTINFO_CLOCK, sizeof(bi_clk)); @@ -186,10 +207,17 @@ bi_add(&bi_net, BTINFO_NET, sizeof(bi_net)); } - printf("entry=%p, ssym=%p, esym=%p\n", - (void *)marks[MARK_ENTRY], - (void *)marks[MARK_SYM], - (void *)marks[MARK_END]); + if (modules_enabled) { + module_add(fsmod); + if (fsmod2 != NULL && strcmp(fsmod, fsmod2) != 0) + module_add(fsmod2); + kmodloadp = marks[MARK_END]; + btinfo_modulelist = NULL; + module_load(bname); + if (btinfo_modulelist != NULL && btinfo_modulelist->num > 0) + bi_add(btinfo_modulelist, BTINFO_MODULELIST, + btinfo_modulelist_size); + } __syncicache((void *)marks[MARK_ENTRY], (u_int)marks[MARK_SYM] - (u_int)marks[MARK_ENTRY]); @@ -234,6 +262,137 @@ bi_next += size; } +void +module_add(char *name) +{ + struct boot_module *bm, *bmp; + + while (*name == ' ' || *name == '\t') + ++name; + + bm = alloc(sizeof(struct boot_module) + strlen(name) + 1); + if (bm == NULL) { + printf("couldn't allocate module %s\n", name); + return; + } + + bm->bm_kmod = (char *)(bm + 1); + bm->bm_len = -1; + bm->bm_next = NULL; + strcpy(bm->bm_kmod, name); + if ((bmp = boot_modules) == NULL) + boot_modules = bm; + else { + while (bmp->bm_next != NULL) + bmp = bmp->bm_next; + bmp->bm_next = bm; + } +} + +#define PAGE_SIZE 4096 +#define alignpg(x) (((x)+PAGE_SIZE-1) & ~(PAGE_SIZE-1)) + +void +module_load(char *kernel_path) +{ + struct boot_module *bm; + struct bi_modulelist_entry *bi; + struct stat st; + char *p; + int size, fd; + + strcpy(module_base, kernel_path); + if ((p = strchr(module_base, ':')) == NULL) + return; /* eeh?! */ + p += 1; + size = sizeof(module_base) - (p - module_base); + + if (netbsd_version / 1000000 % 100 == 99) { + /* -current */ + snprintf(p, size, + "/stand/sandpoint/%d.%d.%d/modules", + netbsd_version / 100000000, + netbsd_version / 1000000 % 100, + netbsd_version / 100 % 100); + } + else if (netbsd_version != 0) { + /* release */ + snprintf(p, size, + "/stand/sandpoint/%d.%d/modules", + netbsd_version / 100000000, + netbsd_version / 1000000 % 100); + } + + /* + * 1st pass; determine module existence + */ + size = 0; + for (bm = boot_modules; bm != NULL; bm = bm->bm_next) { + fd = module_open(bm); + if (fd == -1) + continue; + if (fstat(fd, &st) == -1 || st.st_size == -1) { + printf("WARNING: couldn't stat %s\n", bm->bm_kmod); + close(fd); + continue; + } + bm->bm_len = (int)st.st_size; + close(fd); + size += sizeof(struct bi_modulelist_entry); + } + if (size == 0) + return; + + size += sizeof(struct btinfo_modulelist); + btinfo_modulelist = alloc(size); + if (btinfo_modulelist == NULL) { + printf("WARNING: couldn't allocate module list\n"); + return; + } + btinfo_modulelist_size = size; + btinfo_modulelist->num = 0; + + /* + * 2nd pass; load modules into memory + */ + kmodloadp = alignpg(kmodloadp); + bi = (struct bi_modulelist_entry *)(btinfo_modulelist + 1); + for (bm = boot_modules; bm != NULL; bm = bm->bm_next) { + if (bm->bm_len == -1) + continue; /* already found unavailable */ + fd = module_open(bm); + printf("module \"%s\" ", bm->bm_kmod); + size = read(fd, (char *)kmodloadp, SSIZE_MAX); + if (size < bm->bm_len) + printf("WARNING: couldn't load"); + else { + snprintf(bi->kmod, sizeof(bi->kmod), bm->bm_kmod); + bi->type = BI_MODULE_ELF; + bi->len = size; + bi->base = kmodloadp; + btinfo_modulelist->num += 1; + kmodloadp += alignpg(size); + bi += 1; + printf("loaded at 0x%08x size 0x%x", kmodloadp, size); + } + printf("\n"); + close(fd); + } + btinfo_modulelist->endpa = kmodloadp; +} + +int +module_open(struct boot_module *bm) +{ + char path[80]; + int fd; + + snprintf(path, sizeof(path), + "%s/%s/%s.kmod", module_base, bm->bm_kmod, bm->bm_kmod); + fd = open(path, 0); + return fd; +} + #if 0 static const char *cmdln[] = { "console=ttyS0,115200 root=/dev/sda1 rw initrd=0x200000,2M",