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/altboot Multiple boot devices and/o...



details:   https://anonhg.NetBSD.org/src/rev/37d525c0ef5b
branches:  trunk
changeset: 779029:37d525c0ef5b
user:      phx <phx%NetBSD.org@localhost>
date:      Thu Apr 26 19:59:36 2012 +0000

description:
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.

diffstat:

 sys/arch/sandpoint/stand/altboot/README.altboot |   15 +-
 sys/arch/sandpoint/stand/altboot/dsk.c          |   18 +-
 sys/arch/sandpoint/stand/altboot/globals.h      |   32 ++--
 sys/arch/sandpoint/stand/altboot/main.c         |  178 +++++++++++++----------
 4 files changed, 143 insertions(+), 100 deletions(-)

diffs (truncated from 363 to 300 lines):

diff -r 199e2a9c73b7 -r 37d525c0ef5b sys/arch/sandpoint/stand/altboot/README.altboot
--- a/sys/arch/sandpoint/stand/altboot/README.altboot   Thu Apr 26 17:43:02 2012 +0000
+++ b/sys/arch/sandpoint/stand/altboot/README.altboot   Thu Apr 26 19:59:36 2012 +0000
@@ -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 @@
 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 @@
 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)
diff -r 199e2a9c73b7 -r 37d525c0ef5b sys/arch/sandpoint/stand/altboot/dsk.c
--- a/sys/arch/sandpoint/stand/altboot/dsk.c    Thu Apr 26 17:43:02 2012 +0000
+++ b/sys/arch/sandpoint/stand/altboot/dsk.c    Thu Apr 26 19:59:36 2012 +0000
@@ -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 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 @@
 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 @@
 
        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) {
diff -r 199e2a9c73b7 -r 37d525c0ef5b sys/arch/sandpoint/stand/altboot/globals.h
--- a/sys/arch/sandpoint/stand/altboot/globals.h        Thu Apr 26 17:43:02 2012 +0000
+++ b/sys/arch/sandpoint/stand/altboot/globals.h        Thu Apr 26 19:59:36 2012 +0000
@@ -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(stg);
 
 /* DSK support */
+#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 @@
        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);
diff -r 199e2a9c73b7 -r 37d525c0ef5b sys/arch/sandpoint/stand/altboot/main.c
--- a/sys/arch/sandpoint/stand/altboot/main.c   Thu Apr 26 17:43:02 2012 +0000
+++ b/sys/arch/sandpoint/stand/altboot/main.c   Thu Apr 26 19:59:36 2012 +0000
@@ -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 @@
 void
 main(int argc, char *argv[], char *bootargs_start, char *bootargs_end)
 {
+       unsigned long marks[MARK_MAX];
        struct brdprop *brdprop;
-       unsigned long marks[MARK_MAX];
        char *new_argv[MAX_ARGS];
+       char *bname;
        ssize_t len;
-       int n, i, fd, howto;
-       char *bname;
+       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 @@
        /* 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 @@
                if (i >= sizeof(bootargs) / sizeof(bootargs[0]))
                        break;  /* break on first unknown string */
        }
-       if (n >= argc)
-               bname = BNAME_DEFAULT;
-       else {
-               bname = argv[n];
-               if (check_bootname(bname) == 0) {
-                       printf("%s not a valid bootname\n", bname);
-                       goto loadfail;
+
+       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;
                }
        }
 
-       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;
+       while (n < argc) {
+               bname = argv[n++];
+
+               if (check_bootname(bname) == 0) {
+                       printf("%s not a valid bootname\n", bname);
+                       continue;
+               }
+
+               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();
+
+                       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);
+               }
 
-       if (howto == -1) {
-               /* load another altboot binary and replace ourselves */
-               len = read(fd, (void *)0x100000, 0x1000000 - 0x100000);
-               if (len == -1)
-                       goto loadfail;
+               err = fdloadfile(fd, marks, LOAD_KERNEL);
                close(fd);
+               if (err < 0)
+                       continue;
+
+               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));
+               }
+
+               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();
 



Home | Main Index | Thread Index | Old Index