Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/sandpoint/stand/netboot add MODULAR loading facilit...
details: https://anonhg.NetBSD.org/src/rev/03605cea1812
branches: trunk
changeset: 760692:03605cea1812
user: nisimura <nisimura%NetBSD.org@localhost>
date: Tue Jan 11 08:04:14 2011 +0000
description:
add MODULAR loading facility. Disabled for now 'til it gets ready to use.
diffstat:
sys/arch/sandpoint/stand/netboot/main.c | 171 ++++++++++++++++++++++++++++++-
1 files changed, 165 insertions(+), 6 deletions(-)
diffs (209 lines):
diff -r dfd3561501d5 -r 03605cea1812 sys/arch/sandpoint/stand/netboot/main.c
--- a/sys/arch/sandpoint/stand/netboot/main.c Tue Jan 11 07:01:21 2011 +0000
+++ b/sys/arch/sandpoint/stand/netboot/main.c Tue Jan 11 08:04:14 2011 +0000
@@ -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",
Home |
Main Index |
Thread Index |
Old Index