Module Name: src Committed By: phx Date: Thu Apr 26 19:59:37 UTC 2012
Modified Files: src/sys/arch/sandpoint/stand/altboot: README.altboot dsk.c globals.h main.c Log Message: Multiple boot devices and/or paths may be specified, which are booted one after another until success. When no boot device is specified altboot tries to boot from all disk devices with a valid NetBSD disklabel, starting with unit 0. To generate a diff of this commit: cvs rdiff -u -r1.10 -r1.11 \ src/sys/arch/sandpoint/stand/altboot/README.altboot cvs rdiff -u -r1.15 -r1.16 src/sys/arch/sandpoint/stand/altboot/dsk.c cvs rdiff -u -r1.18 -r1.19 src/sys/arch/sandpoint/stand/altboot/globals.h \ src/sys/arch/sandpoint/stand/altboot/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/altboot/README.altboot diff -u src/sys/arch/sandpoint/stand/altboot/README.altboot:1.10 src/sys/arch/sandpoint/stand/altboot/README.altboot:1.11 --- src/sys/arch/sandpoint/stand/altboot/README.altboot:1.10 Tue Apr 24 14:56:07 2012 +++ src/sys/arch/sandpoint/stand/altboot/README.altboot Thu Apr 26 19:59:36 2012 @@ -1,6 +1,6 @@ /// notes about altboot /// -$NetBSD: README.altboot,v 1.10 2012/04/24 14:56:07 nisimura Exp $ +$NetBSD: README.altboot,v 1.11 2012/04/26 19:59:36 phx Exp $ Altboot is a functional bridge to fill the gap between a NAS product custom bootloader and the NetBSD kernel startup environment. Altboot @@ -61,11 +61,11 @@ that the original U-Boot/PPCboot still r as a functional extension for them. In case the firmware was crippled by the vendor so that it only boots -Linux U-Boot images (D-Link), you can still use altboot by uploading -altboot.img instead of the Linux kernel. +Linux U-Boot images (D-Link, Synology 2007), you can still use altboot by +overwriting the Linux kernel with altboot.img. Altboot passes the following bootinfo records to the NetBSD/sandpoint -kernel. +kernel: - processor clock tick value driving MPC8241/8245. - serial console selection. - booted kernel filename and which device it was fetched from. @@ -104,7 +104,12 @@ restarts itself. Mainly useful for altbo Multiple arguments may be specified at once, although not all combinations make sense. The format of an altboot command line is: - [[<bootargs> ...] <devicename>:[<bootfile>]] + [[<bootargs> ...] <devicename>:[<bootfile>] ...] + +Multiple boot devices and/or paths may be specified, which are booted one +after another until success. When no boot device is specified altboot tries +to boot from all disk devices with a valid NetBSD disklabel, starting with +unit 0. The following device names are supported: - tftp boot from TFTP (address retrieved by DHCP) Index: src/sys/arch/sandpoint/stand/altboot/dsk.c diff -u src/sys/arch/sandpoint/stand/altboot/dsk.c:1.15 src/sys/arch/sandpoint/stand/altboot/dsk.c:1.16 --- src/sys/arch/sandpoint/stand/altboot/dsk.c:1.15 Mon Apr 9 12:40:55 2012 +++ src/sys/arch/sandpoint/stand/altboot/dsk.c Thu Apr 26 19:59:37 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: dsk.c,v 1.15 2012/04/09 12:40:55 nisimura Exp $ */ +/* $NetBSD: dsk.c,v 1.16 2012/04/26 19:59:37 phx Exp $ */ /*- * Copyright (c) 2010 The NetBSD Foundation, Inc. @@ -83,7 +83,6 @@ static void issue48(struct dvata_chan *, static void issue28(struct dvata_chan *, int64_t, int); static struct disk *lookup_disk(int); -#define MAX_UNITS 8 static struct disk ldisk[MAX_UNITS]; int @@ -462,7 +461,18 @@ static struct disk * lookup_disk(int unit) { - return &ldisk[unit]; + return (unit >= 0 && unit < MAX_UNITS) ? &ldisk[unit] : NULL; +} + +int +dlabel_valid(int unit) +{ + struct disk *dsk; + + dsk = lookup_disk(unit); + if (dsk == NULL) + return NULL; + return dsk->dlabel != NULL; } int @@ -487,10 +497,10 @@ dsk_open(struct open_file *f, ...) if ((d = lookup_disk(unit)) == NULL) return ENXIO; - f->f_devdata = d; if ((dlp = d->dlabel) == NULL || part >= dlp->d_npartitions) return ENXIO; d->part = part; + f->f_devdata = d; snprintf(bi_path.bootpath, sizeof(bi_path.bootpath), name); if (dlp->d_partitions[part].p_fstype == FS_BSDFFS) { Index: src/sys/arch/sandpoint/stand/altboot/globals.h diff -u src/sys/arch/sandpoint/stand/altboot/globals.h:1.18 src/sys/arch/sandpoint/stand/altboot/globals.h:1.19 --- src/sys/arch/sandpoint/stand/altboot/globals.h:1.18 Mon Apr 16 16:55:29 2012 +++ src/sys/arch/sandpoint/stand/altboot/globals.h Thu Apr 26 19:59:37 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: globals.h,v 1.18 2012/04/16 16:55:29 phx Exp $ */ +/* $NetBSD: globals.h,v 1.19 2012/04/26 19:59:37 phx Exp $ */ #ifdef DEBUG #define DPRINTF(x) printf x @@ -167,8 +167,23 @@ NIF_DECL(skg); NIF_DECL(stg); /* DSK support */ -int dskdv_init(void *); +#define MAX_UNITS 4 + +struct disk { + char xname[8]; + void *dvops; + unsigned unittag; + uint16_t ident[128]; + uint64_t nsect; + uint64_t first; + void *dlabel; + int part; + void *fsops; + int (*lba_read)(struct disk *, int64_t, int, void *); +}; +int dskdv_init(void *); +int dlabel_valid(int); int dsk_open(struct open_file *, ...); int dsk_close(struct open_file *); int dsk_strategy(void *, int, daddr_t, size_t, void *, size_t *); @@ -230,19 +245,6 @@ struct dkdev_ata { char *iobuf; }; -struct disk { - char xname[8]; - void *dvops; - unsigned unittag; - uint16_t ident[128]; - uint64_t nsect; - uint64_t first; - void *dlabel; - int part; - void *fsops; - int (*lba_read)(struct disk *, int64_t, int, void *); -}; - int spinwait_unbusy(struct dkdev_ata *, int, int, const char **); int perform_atareset(struct dkdev_ata *, int); void wakeup_drive(struct dkdev_ata *, int); Index: src/sys/arch/sandpoint/stand/altboot/main.c diff -u src/sys/arch/sandpoint/stand/altboot/main.c:1.18 src/sys/arch/sandpoint/stand/altboot/main.c:1.19 --- src/sys/arch/sandpoint/stand/altboot/main.c:1.18 Mon Apr 16 16:55:29 2012 +++ src/sys/arch/sandpoint/stand/altboot/main.c Thu Apr 26 19:59:37 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: main.c,v 1.18 2012/04/16 16:55:29 phx Exp $ */ +/* $NetBSD: main.c,v 1.19 2012/04/26 19:59:37 phx Exp $ */ /*- * Copyright (c) 2007 The NetBSD Foundation, Inc. @@ -119,15 +119,14 @@ static void sat_test(void); void main(int argc, char *argv[], char *bootargs_start, char *bootargs_end) { - struct brdprop *brdprop; unsigned long marks[MARK_MAX]; + struct brdprop *brdprop; char *new_argv[MAX_ARGS]; - ssize_t len; - int n, i, fd, howto; char *bname; + ssize_t len; + int err, fd, howto, i, n; - printf("\n"); - printf(">> %s altboot, revision %s\n", bootprog_name, bootprog_rev); + printf("\n>> %s altboot, revision %s\n", bootprog_name, bootprog_rev); brdprop = brd_lookup(brdtype); printf(">> %s, cpu %u MHz, bus %u MHz, %dMB SDRAM\n", brdprop->verbose, @@ -233,7 +232,7 @@ main(int argc, char *argv[], char *boota /* wait 2s for user to enter interactive mode */ for (n = 200; n >= 0; n--) { if (n % 100 == 0) - printf("Hit any key to enter interactive mode: %d\r", + printf("\rHit any key to enter interactive mode: %d", n / 100); if (tstchar()) { #ifdef DEBUG @@ -272,85 +271,112 @@ main(int argc, char *argv[], char *boota if (i >= sizeof(bootargs) / sizeof(bootargs[0])) break; /* break on first unknown string */ } - if (n >= argc) - bname = BNAME_DEFAULT; - else { - bname = argv[n]; + + if (n >= argc) { + /* + * If no device name is given we construct a list of drives + * which have valid disklabels. + */ + n = 0; + argc = 0; + argv = alloc(MAX_UNITS * (sizeof(char *) + sizeof("wdN:"))); + bname = (char *)(argv + MAX_UNITS); + for (i = 0; i < MAX_UNITS; i++) { + if (!dlabel_valid(i)) + continue; + sprintf(bname, "wd%d:", i); + argv[argc++] = bname; + bname += sizeof("wdN:"); + } + /* use default drive if no valid disklabel is found */ + if (argc == 0) { + argc = 1; + argv[0] = BNAME_DEFAULT; + } + } + + while (n < argc) { + bname = argv[n++]; + if (check_bootname(bname) == 0) { printf("%s not a valid bootname\n", bname); - goto loadfail; + continue; } - } - if ((fd = open(bname, 0)) < 0) { - if (errno == ENOENT) - printf("\"%s\" not found\n", bi_path.bootpath); - goto loadfail; - } - printf("loading \"%s\" ", bi_path.bootpath); - marks[MARK_START] = 0; + if ((fd = open(bname, 0)) < 0) { + if (errno == ENOENT) + printf("\"%s\" not found\n", bi_path.bootpath); + continue; + } + printf("loading \"%s\" ", bi_path.bootpath); + marks[MARK_START] = 0; + + if (howto == -1) { + /* load another altboot binary and replace ourselves */ + len = read(fd, (void *)0x100000, 0x1000000 - 0x100000); + if (len == -1) + goto loadfail; + close(fd); + netif_shutdown_all(); - if (howto == -1) { - /* load another altboot binary and replace ourselves */ - len = read(fd, (void *)0x100000, 0x1000000 - 0x100000); - if (len == -1) - goto loadfail; + memcpy((void *)0xf0000, newaltboot, + newaltboot_end - newaltboot); + __syncicache((void *)0xf0000, + newaltboot_end - newaltboot); + printf("Restarting...\n"); + run((void *)1, argv, (void *)0x100000, (void *)len, + (void *)0xf0000); + } + + err = fdloadfile(fd, marks, LOAD_KERNEL); close(fd); - netif_shutdown_all(); + if (err < 0) + continue; - memcpy((void *)0xf0000, newaltboot, - newaltboot_end - newaltboot); - __syncicache((void *)0xf0000, newaltboot_end - newaltboot); - printf("Restarting...\n"); - run((void *)1, argv, (void *)0x100000, (void *)len, - (void *)0xf0000); - } else 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)); - bi_add(&bi_path, BTINFO_BOOTPATH, sizeof(bi_path)); - bi_add(&bi_rdev, BTINFO_ROOTDEVICE, sizeof(bi_rdev)); - bi_add(&bi_fam, BTINFO_PRODFAMILY, sizeof(bi_fam)); - if (brdtype == BRD_SYNOLOGY || brdtype == BRD_DLINKDSM) { - /* need to set this MAC address in kernel driver later */ - bi_add(&bi_net, BTINFO_NET, sizeof(bi_net)); - } - - 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); - } - - launchfixup(); - netif_shutdown_all(); + 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)); + bi_add(&bi_path, BTINFO_BOOTPATH, sizeof(bi_path)); + bi_add(&bi_rdev, BTINFO_ROOTDEVICE, sizeof(bi_rdev)); + bi_add(&bi_fam, BTINFO_PRODFAMILY, sizeof(bi_fam)); + if (brdtype == BRD_SYNOLOGY || brdtype == BRD_DLINKDSM) { + /* need to pass this MAC address to kernel */ + bi_add(&bi_net, BTINFO_NET, sizeof(bi_net)); + } - __syncicache((void *)marks[MARK_ENTRY], - (u_int)marks[MARK_SYM] - (u_int)marks[MARK_ENTRY]); + 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); + } - run((void *)marks[MARK_SYM], (void *)marks[MARK_END], - (void *)howto, bootinfo, (void *)marks[MARK_ENTRY]); + launchfixup(); + netif_shutdown_all(); - /* should never come here */ - printf("exec returned. Restarting...\n"); - _rtt(); + __syncicache((void *)marks[MARK_ENTRY], + (u_int)marks[MARK_SYM] - (u_int)marks[MARK_ENTRY]); + + run((void *)marks[MARK_SYM], (void *)marks[MARK_END], + (void *)howto, bootinfo, (void *)marks[MARK_ENTRY]); + /* should never come here */ + printf("exec returned. Restarting...\n"); + _rtt(); + } loadfail: printf("load failed. Restarting...\n"); _rtt();