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