summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2012-03-29 20:22:19 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2012-03-29 20:22:19 +0000
commitda68251c5815765c551e0447d833dc59a237da31 (patch)
tree9d737a4a0fb238ea93c3ebd85285a7e3560191f5 /sys/arch
parent53b8ad2af2b626f74e43086bb684d1bf93993c87 (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/Makefile4
-rw-r--r--sys/arch/sgi/stand/boot/boot.c87
-rw-r--r--sys/arch/sgi/stand/boot/version20
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";