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