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.
This commit is contained in:
rumble 2007-05-10 21:24:37 +00:00
parent c1079eace9
commit 7ab6f41450
3 changed files with 54 additions and 11 deletions

View File

@ -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 <sys/cdefs.h>
__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 <sys/param.h>
#include <sys/systm.h>
@ -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);
}

View File

@ -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 <sys/cdefs.h>
__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;

View File

@ -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 <sys/cdefs.h>
__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;