From 7ab6f41450faf0a434b2a2afbfa2ec60e2ff6ba5 Mon Sep 17 00:00:00 2001 From: rumble Date: Thu, 10 May 2007 21:24:37 +0000 Subject: [PATCH] A few changes to allow booting to multi-user with IP12 kernels squished into oversized volume headers: Query ARCBIOS for OSLoadFilename and OSLoadOptions first, rather than only using the environment variables passed since we want to go through arcemu. Add an ugly hack to arcemu that munges the nvram 'bootfile' variable. We need this because bootfile will point to the volume header, which then translates into a bogus root device of 'sd0i', or similar. --- sys/arch/sgimips/sgimips/arcemu.c | 39 ++++++++++++++++++++++++++--- sys/arch/sgimips/sgimips/autoconf.c | 6 ++--- sys/arch/sgimips/sgimips/machdep.c | 20 ++++++++++++--- 3 files changed, 54 insertions(+), 11 deletions(-) diff --git a/sys/arch/sgimips/sgimips/arcemu.c b/sys/arch/sgimips/sgimips/arcemu.c index c455cca9c53b..dc84131fd0fa 100644 --- a/sys/arch/sgimips/sgimips/arcemu.c +++ b/sys/arch/sgimips/sgimips/arcemu.c @@ -1,4 +1,4 @@ -/* $NetBSD: arcemu.c,v 1.15 2007/05/10 17:45:58 rumble Exp $ */ +/* $NetBSD: arcemu.c,v 1.16 2007/05/10 21:24:37 rumble Exp $ */ /* * Copyright (c) 2004 Steve Rumble @@ -29,7 +29,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: arcemu.c,v 1.15 2007/05/10 17:45:58 rumble Exp $"); +__KERNEL_RCSID(0, "$NetBSD: arcemu.c,v 1.16 2007/05/10 21:24:37 rumble Exp $"); #include #include @@ -200,6 +200,7 @@ static struct arcemu_ip12env { char gfx[32]; char netaddr[32]; char dlserver[32]; + char osloadoptions[32]; } ip12env; static void @@ -290,6 +291,8 @@ arcemu_ip12_init(const char **env) extractenv(env, "gfx", ip12env.gfx, sizeof(ip12env.gfx)); extractenv(env, "netaddr", ip12env.netaddr, sizeof(ip12env.netaddr)); extractenv(env, "dlserver", ip12env.dlserver, sizeof(ip12env.dlserver)); + extractenv(env, "osloadoptions", ip12env.osloadoptions, + sizeof(ip12env.osloadoptions)); strcpy(arcbios_system_identifier, "SGI-IP12"); strcpy(arcbios_sysid_vendor, "SGI"); @@ -372,9 +375,24 @@ arcemu_ip12_GetEnvironmentVariable(const char *var) return (ip12env.gfx); } - /* makebootdev() can handle "dksc(a,b,c)/netbsd", etc already */ - if (strcasecmp("OSLoadPartition", var) == 0) + /* + * Ugly Kludge Alert! + * + * Since we don't yet have an ip12 bootloader, we can only squish + * a kernel into the volume header. However, this makes the bootfile + * something like 'dksc(0,1,8)', which translates into 'sd0i'. Ick. + * Munge what we return to always map to 'sd0a'. Lord have mercy. + * + * makebootdev() can handle "dksc(a,b,c)/netbsd", etc already + */ + if (strcasecmp("OSLoadPartition", var) == 0) { + char *hack; + + hack = strstr(ip12nvram.bootfile, ",8)"); + if (hack != NULL) + hack[1] = '0'; return (ip12nvram.bootfile); + } /* pull filename from e.g.: "dksc(0,1,0)netbsd" */ if (strcasecmp("OSLoadFilename", var) == 0) { @@ -386,6 +404,19 @@ arcemu_ip12_GetEnvironmentVariable(const char *var) return (NULL); } + /* + * As far as I can tell, old systems had no analogue of OSLoadOptions. + * So, to allow forcing of single user mode, we accomodate the + * user setting the ARCBIOSy environment variable "OSLoadOptions" to + * something other than "auto". + */ + if (strcasecmp("OSLoadOptions", var) == 0) { + if (ip12env.osloadoptions[0] == '\0') + return ("auto"); + else + return (ip12env.osloadoptions); + } + return (NULL); } diff --git a/sys/arch/sgimips/sgimips/autoconf.c b/sys/arch/sgimips/sgimips/autoconf.c index 2a0bba3cd355..076a43ed3017 100644 --- a/sys/arch/sgimips/sgimips/autoconf.c +++ b/sys/arch/sgimips/sgimips/autoconf.c @@ -1,4 +1,4 @@ -/* $NetBSD: autoconf.c,v 1.35 2007/02/22 16:54:26 thorpej Exp $ */ +/* $NetBSD: autoconf.c,v 1.36 2007/05/10 21:24:37 rumble Exp $ */ /* * Copyright (c) 2000 Soren S. Jorvang @@ -33,7 +33,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.35 2007/02/22 16:54:26 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.36 2007/05/10 21:24:37 rumble Exp $"); #include "opt_ddb.h" @@ -96,7 +96,7 @@ cpu_configure() * 'dksc(0,1,0)netbsd' */ void -makebootdev(char *cp) +makebootdev(const char *cp) { if (booted_protocol != NULL) return; diff --git a/sys/arch/sgimips/sgimips/machdep.c b/sys/arch/sgimips/sgimips/machdep.c index 20c4852bdaaa..6e51f7d5d6a0 100644 --- a/sys/arch/sgimips/sgimips/machdep.c +++ b/sys/arch/sgimips/sgimips/machdep.c @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.111 2007/05/10 17:27:06 rumble Exp $ */ +/* $NetBSD: machdep.c,v 1.112 2007/05/10 21:24:37 rumble Exp $ */ /* * Copyright (c) 2000 Soren S. Jorvang @@ -34,7 +34,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.111 2007/05/10 17:27:06 rumble Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.112 2007/05/10 21:24:37 rumble Exp $"); #include "opt_ddb.h" #include "opt_kgdb.h" @@ -258,7 +258,7 @@ mach_init(int argc, char **argv, int magic, struct btinfo_common *btinfo) void *v; vsize_t size; struct arcbios_mem *mem; - const char *cpufreq; + const char *cpufreq, *osload; struct btinfo_symtab *bi_syms; void *ssym; vaddr_t kernend; @@ -323,6 +323,9 @@ mach_init(int argc, char **argv, int magic, struct btinfo_common *btinfo) curcpu()->ci_cpu_freq = strtoul(cpufreq, NULL, 10) * 1000000; /* + * Try to get the boot device information from ARCBIOS. If we fail, + * attempt to use the environment variables passed as follows: + * * argv[0] can be either the bootloader loaded by the PROM, or a * kernel loaded directly by the PROM. * @@ -332,14 +335,23 @@ mach_init(int argc, char **argv, int magic, struct btinfo_common *btinfo) * If argv[1] isn't an environment string, try to use it to set the * boot device. */ - if (argc > 1 && strchr(argv[1], '=') != 0) + osload = ARCBIOS->GetEnvironmentVariable("OSLoadPartition"); + if (osload != NULL) + makebootdev(osload); + else if (argc > 1 && strchr(argv[1], '=') != 0) makebootdev(argv[1]); boothowto = RB_SINGLE; /* * Single- or multi-user ('auto' in SGI terms). + * + * Query ARCBIOS first, then default to environment variables. */ + osload = ARCBIOS->GetEnvironmentVariable("OSLoadOptions"); + if (osload != NULL && strcmp(osload, "auto") == 0) + boothowto &= ~RB_SINGLE; + for (i = 0; i < argc; i++) { if (strcmp(argv[i], "OSLoadOptions=auto") == 0) boothowto &= ~RB_SINGLE;