diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2012-03-29 20:22:19 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2012-03-29 20:22:19 +0000 |
commit | da68251c5815765c551e0447d833dc59a237da31 (patch) | |
tree | 9d737a4a0fb238ea93c3ebd85285a7e3560191f5 /sys/arch | |
parent | 53b8ad2af2b626f74e43086bb684d1bf93993c87 (diff) |
Put more smarts into the limited bootblocks brain; they will now happily
recognize a kernel bootpath (when not autobooting) even if it does not start
with a /, and will also recognize when this is a full path (e.g.
bootp()mykernel), in which case OSLoadPartition does not need to be
prepended to the constructed path.
This will allow ELF kernels to be booted on ELF-unaware PROM with
bootp()bootecoff bootp()kernel
without doomed-to-fail tomfoolery to convert the 64-bit ELF kernel to a
32-bit ECOFF binary.
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/sgi/stand/boot/Makefile | 4 | ||||
-rw-r--r-- | sys/arch/sgi/stand/boot/boot.c | 87 | ||||
-rw-r--r-- | sys/arch/sgi/stand/boot/version | 20 |
3 files changed, 85 insertions, 26 deletions
diff --git a/sys/arch/sgi/stand/boot/Makefile b/sys/arch/sgi/stand/boot/Makefile index d27ca2d696f..8b7eb7d8384 100644 --- a/sys/arch/sgi/stand/boot/Makefile +++ b/sys/arch/sgi/stand/boot/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.12 2012/03/19 17:38:31 miod Exp $ +# $OpenBSD: Makefile,v 1.13 2012/03/29 20:22:18 miod Exp $ NOMAN= noman @@ -12,7 +12,7 @@ AFLAGS+= ${SAABI} S= ${.CURDIR}/../../../.. SRCS= start.S arcbios.c boot.c conf.c diskio.c filesystem.c \ - netfs.c netio.c strstr.c + netfs.c netio.c strchr.c strstr.c .PATH: ${S}/lib/libsa SRCS+= loadfile.c diff --git a/sys/arch/sgi/stand/boot/boot.c b/sys/arch/sgi/stand/boot/boot.c index 89d99cf33b5..05f3703a7d4 100644 --- a/sys/arch/sgi/stand/boot/boot.c +++ b/sys/arch/sgi/stand/boot/boot.c @@ -1,4 +1,4 @@ -/* $OpenBSD: boot.c,v 1.19 2012/03/19 17:38:31 miod Exp $ */ +/* $OpenBSD: boot.c,v 1.20 2012/03/29 20:22:18 miod Exp $ */ /* * Copyright (c) 2004 Opsycon AB, www.opsycon.se. @@ -49,11 +49,13 @@ enum { AUTO_MINI, AUTO_DEBUG } bootauto = AUTO_NONE; - char *OSLoadPartition = NULL; char *OSLoadFilename = NULL; + int IP; +#include "version" + /* * OpenBSD/sgi Boot Loader. */ @@ -68,20 +70,27 @@ main(int argc, char *argv[]) extern int arcbios_init(void); IP = arcbios_init(); - - printf("\nOpenBSD/sgi-IP%d ARCBios boot\n", IP); - - dobootopts(argc, argv); - if (OSLoadPartition != NULL) { - strlcpy(line, OSLoadPartition, sizeof(line)); - if (OSLoadFilename != NULL) - strlcat(line, OSLoadFilename, sizeof(line)); - } else - strlcpy(line, "invalid argument setup", sizeof(line)); + printf("\nOpenBSD/sgi-IP%d ARCBios boot version %s\n", IP, version); + /* we want to print IP20 but load IP22 */ + if (IP == 20) + IP = 22; for (entry = 0; entry < argc; entry++) printf("arg %d: %s\n", entry, argv[entry]); + dobootopts(argc, argv); + if (OSLoadPartition == NULL) { + /* + * Things are probably horribly wrong, or user has no idea + * what's he's doing. Be nice lads and try to provide + * working defaults, which ought to work on all systems. + */ + OSLoadPartition = "disk(0)part(0)"; + } + strlcpy(line, OSLoadPartition, sizeof(line)); + if (OSLoadFilename != NULL) + strlcat(line, OSLoadFilename, sizeof(line)); + printf("Boot: %s\n", line); /* @@ -124,8 +133,9 @@ dobootopts(int argc, char **argv) { static char filenamebuf[1 + 32]; char *SystemPartition = NULL; - char *cp; + char *cp, *sep; int i; + char *writein = NULL; for (i = 1; i < argc; i++) { cp = argv[i]; @@ -146,13 +156,39 @@ dobootopts(int argc, char **argv) OSLoadFilename = &cp[15]; else if (strncmp(cp, "SystemPartition=", 16) == 0) SystemPartition = &cp[16]; + else { + /* + * Either a boot-related environment variable, or + * a boot write-in (boot path or options to the + * program being loaded). + */ + if (*cp == '-') + continue; /* options */ + if (strchr(cp, '=') != NULL) + continue; /* variable (or bad choice */ + /* of filename) */ + if (writein == NULL) + writein = cp; + } } - /* If "OSLoadOptions=" is missing, see if any arg was given. */ - if (bootauto == AUTO_NONE && *argv[1] == '/') - OSLoadFilename = argv[1]; - - if (bootauto == AUTO_MINI) { + switch (bootauto) { + case AUTO_NONE: + /* If "OSLoadOptions=" is missing, use boot path if given. */ + if (writein != NULL) { + /* check for a possible path component */ + sep = strchr(writein, '('); + if (sep != NULL && strchr(sep, ')') != NULL) { + /* looks like this is a full path */ + OSLoadPartition = ""; + } else { + /* relative path, keep OSLoadPartition */ + } + OSLoadFilename = writein; + } + break; + case AUTO_MINI: + { static char loadpart[64]; char *p; @@ -174,6 +210,10 @@ dobootopts(int argc, char **argv) OSLoadPartition = loadpart; OSLoadFilename = filenamebuf; } + } + break; + default: + break; } } @@ -187,18 +227,17 @@ check_phdr(void *v) uint64_t addr; switch (IP) { - case 20: case 22: - addr = 0xffffffff88000000ULL >> 28; + addr = 0xffffffff88000000ULL >> 24; break; case 27: - addr = 0xa800000000000000ULL >> 28; + addr = 0xa800000000000000ULL >> 24; break; case 30: - addr = 0xa800000020000000ULL >> 28; + addr = 0xa800000020000000ULL >> 24; break; case 32: - addr = 0xffffffff80000000ULL >> 28; + addr = 0xffffffff80000000ULL >> 24; break; default: /* @@ -208,7 +247,7 @@ check_phdr(void *v) return 0; } - if ((phdr->p_vaddr >> 28) != addr) { + if ((phdr->p_vaddr >> 24) != addr) { /* I'm sorry Dave, I can't let you do that. */ printf("This kernel does not seem to be compiled for this" " machine type.\nYou need to boot an IP%d kernel.\n", IP); diff --git a/sys/arch/sgi/stand/boot/version b/sys/arch/sgi/stand/boot/version new file mode 100644 index 00000000000..efd592b4433 --- /dev/null +++ b/sys/arch/sgi/stand/boot/version @@ -0,0 +1,20 @@ +/* $OpenBSD: version,v 1.1 2012/03/29 20:22:18 miod Exp $ */ +/* Public domain. Come on, it can hardly be considered as code. */ + +#if 0 + +No version strings up to 2012 + many changes, but nothing to tell bootblocks about, except perhaps + their size (har, har) + +1.1 + smarter argv[] analysis: the first argument which does neither look + like an environment variable nor dash-prefixed options, is assumed + to be a file path. If there are no signs of it being a full ARC + path, OSLoadPartition is prepended to it. + The old behaviour was to only accept filenames starting with "/", and + thus always relative to OSLoadPartition. + +#endif + +static const char version[] = "1.1"; |