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();

Reply via email to