Completely revamp setroot() and friends. Since Chris' version of this code
is close to how I reworked it, I pulled in the (essentially MI) NetBSD/alpha and added the appropriate support around it. - No need for the GENERIC kernel config option. - NFS-mounted root and swap are supported. - If we can't figure out where the root filesystem is from what the Booter tells us, ask the user. - Split the mainbus autoconfig code to a separate file. Also, update/add copyrights as appropriate.
This commit is contained in:
parent
37472fd212
commit
758ea43e99
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: files.mac68k,v 1.48 1996/05/19 22:29:10 scottr Exp $
|
||||
# $NetBSD: files.mac68k,v 1.49 1996/06/19 03:21:08 scottr Exp $
|
||||
|
||||
# mac68k-specific configuration info
|
||||
|
||||
|
@ -94,6 +94,7 @@ file arch/mac68k/mac68k/disksubr.c disk
|
|||
file arch/mac68k/mac68k/machdep.c
|
||||
file arch/mac68k/mac68k/macrom.c
|
||||
file arch/mac68k/mac68k/macromasm.s
|
||||
file arch/mac68k/mac68k/mainbus.c
|
||||
file arch/mac68k/mac68k/mem.c
|
||||
file arch/mac68k/mac68k/pmap.c
|
||||
file arch/mac68k/mac68k/pmap_bootstrap.c
|
||||
|
|
|
@ -1,13 +1,17 @@
|
|||
/* $NetBSD: autoconf.c,v 1.30 1996/06/19 02:19:13 briggs Exp $ */
|
||||
/* $NetBSD: autoconf.c,v 1.31 1996/06/19 03:21:03 scottr Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 University of Utah.
|
||||
* Copyright (c) 1982, 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* the Systems Programming Group of the University of Utah Computer
|
||||
* Science Department.
|
||||
* This software was developed by the Computer Systems Engineering group
|
||||
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||
* contributed to Berkeley.
|
||||
*
|
||||
* All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Lawrence Berkeley Laboratory.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
|
@ -36,11 +40,8 @@
|
|||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
* from: Utah $Hdr: autoconf.c 1.31 91/01/21$
|
||||
*
|
||||
* @(#)autoconf.c 7.5 (Berkeley) 5/7/91
|
||||
* @(#)autoconf.c 8.4 (Berkeley) 10/1/93
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -52,96 +53,71 @@
|
|||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/dkstat.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/dmap.h>
|
||||
#include <sys/reboot.h>
|
||||
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/disk.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_kern.h>
|
||||
#include <vm/vm_map.h>
|
||||
#include <dev/cons.h>
|
||||
|
||||
#include <machine/adbsys.h>
|
||||
#include <machine/autoconf.h>
|
||||
#include <machine/vmparam.h>
|
||||
#include <machine/param.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/pte.h>
|
||||
#include <machine/adbsys.h>
|
||||
#include <machine/viareg.h>
|
||||
|
||||
#include <scsi/scsi_all.h>
|
||||
#include <scsi/scsiconf.h>
|
||||
|
||||
/*
|
||||
* The following several variables are related to
|
||||
* the configuration process, and are used in initializing
|
||||
* the machine.
|
||||
*/
|
||||
int cold; /* if 1 (locore.s), still working on cold-start */
|
||||
|
||||
#ifdef DEBUG
|
||||
int acdebug = 0;
|
||||
#endif
|
||||
struct device *booted_device;
|
||||
int booted_partition;
|
||||
|
||||
static void findbootdev __P((void));
|
||||
static int mainbus_match __P((struct device *, void *, void *));
|
||||
static void mainbus_attach __P((struct device *parent,
|
||||
struct device *self, void *aux));
|
||||
static void setroot __P((void));
|
||||
static void swapconf __P((void));
|
||||
struct device *parsedisk __P((char *, int, int, dev_t *));
|
||||
static struct device *getdisk __P((char *, int, int, dev_t *));
|
||||
static int findblkmajor __P((struct device *));
|
||||
static int getstr __P((char *, int));
|
||||
static void findbootdev __P((void));
|
||||
static int target_to_unit __P((u_long, u_long, u_long));
|
||||
|
||||
void setroot __P((void));
|
||||
void swapconf __P((void));
|
||||
|
||||
/*
|
||||
* Determine mass storage and memory configuration for a machine.
|
||||
* configure:
|
||||
* called at boot time, configure all devices on the system
|
||||
*/
|
||||
void
|
||||
configure(void)
|
||||
configure()
|
||||
{
|
||||
VIA_initialize();
|
||||
extern int cold;
|
||||
|
||||
VIA_initialize(); /* Init VIA hardware */
|
||||
mrg_init(); /* Init Mac ROM Glue */
|
||||
|
||||
startrtclock(); /* start before adb_init() */
|
||||
|
||||
adb_init(); /* ADB device subsystem & driver */
|
||||
|
||||
if (config_rootfound("mainbus", "mainbus") == NULL)
|
||||
panic("No main device!");
|
||||
panic("No mainbus found!");
|
||||
|
||||
#if GENERIC
|
||||
if ((boothowto & RB_ASKNAME) == 0)
|
||||
setroot();
|
||||
setconf();
|
||||
#else
|
||||
findbootdev();
|
||||
setroot();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Configure swap area and related system
|
||||
* parameter based on device(s) used.
|
||||
*/
|
||||
swapconf();
|
||||
dumpconf();
|
||||
cold = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Configure swap space and related parameters.
|
||||
*/
|
||||
static void
|
||||
swapconf(void)
|
||||
void
|
||||
swapconf()
|
||||
{
|
||||
register struct swdevt *swp;
|
||||
register int nblks;
|
||||
struct swdevt *swp;
|
||||
int nblks, maj;
|
||||
|
||||
for (swp = swdevt; swp->sw_dev != NODEV ; swp++) {
|
||||
int maj = major(swp->sw_dev);
|
||||
|
||||
maj = major(swp->sw_dev);
|
||||
if (maj > nblkdev)
|
||||
break;
|
||||
if (bdevsw[maj].d_psize) {
|
||||
|
@ -152,13 +128,382 @@ swapconf(void)
|
|||
swp->sw_nblks = ctod(dtoc(swp->sw_nblks));
|
||||
}
|
||||
}
|
||||
dumpconf();
|
||||
}
|
||||
|
||||
u_long bootdev; /* should be dev_t, but not until 32 bits */
|
||||
struct device *bootdv = NULL;
|
||||
struct nam2blk {
|
||||
char *name;
|
||||
int maj;
|
||||
} nam2blk[] = {
|
||||
{ "sd", 4 },
|
||||
{ "cd", 6 },
|
||||
};
|
||||
|
||||
#define PARTITIONMASK 0x7
|
||||
#define UNITSHIFT 3
|
||||
static int
|
||||
findblkmajor(dv)
|
||||
struct device *dv;
|
||||
{
|
||||
char *name = dv->dv_xname;
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < sizeof(nam2blk)/sizeof(nam2blk[0]); ++i)
|
||||
if (!strncmp(name, nam2blk[i].name, strlen(nam2blk[0].name)))
|
||||
return (nam2blk[i].maj);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static struct device *
|
||||
getdisk(str, len, defpart, devp)
|
||||
char *str;
|
||||
int len, defpart;
|
||||
dev_t *devp;
|
||||
{
|
||||
register struct device *dv;
|
||||
|
||||
if ((dv = parsedisk(str, len, defpart, devp)) == NULL) {
|
||||
printf("use one of:");
|
||||
for (dv = alldevs.tqh_first; dv != NULL;
|
||||
dv = dv->dv_list.tqe_next) {
|
||||
if (dv->dv_class == DV_DISK)
|
||||
printf(" %s[a-h]", dv->dv_xname);
|
||||
#ifdef NFSCLIENT
|
||||
if (dv->dv_class == DV_IFNET)
|
||||
printf(" %s", dv->dv_xname);
|
||||
#endif
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
return (dv);
|
||||
}
|
||||
|
||||
struct device *
|
||||
parsedisk(str, len, defpart, devp)
|
||||
char *str;
|
||||
int len, defpart;
|
||||
dev_t *devp;
|
||||
{
|
||||
register struct device *dv;
|
||||
register char *cp, c;
|
||||
int majdev, part;
|
||||
|
||||
if (len == 0)
|
||||
return (NULL);
|
||||
cp = str + len - 1;
|
||||
c = *cp;
|
||||
if (c >= 'a' && c <= ('a' + MAXPARTITIONS - 1)) {
|
||||
part = c - 'a';
|
||||
*cp = '\0';
|
||||
} else
|
||||
part = defpart;
|
||||
|
||||
for (dv = alldevs.tqh_first; dv != NULL; dv = dv->dv_list.tqe_next) {
|
||||
if (dv->dv_class == DV_DISK &&
|
||||
strcmp(str, dv->dv_xname) == 0) {
|
||||
majdev = findblkmajor(dv);
|
||||
if (majdev < 0)
|
||||
panic("parsedisk");
|
||||
*devp = MAKEDISKDEV(majdev, dv->dv_unit, part);
|
||||
break;
|
||||
}
|
||||
#ifdef NFSCLIENT
|
||||
if (dv->dv_class == DV_IFNET &&
|
||||
strcmp(str, dv->dv_xname) == 0) {
|
||||
*devp = NODEV;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
*cp = c;
|
||||
return (dv);
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to find the device from which we were booted.
|
||||
* If we can do so, and not instructed not to do so,
|
||||
* change rootdev to correspond to the load device.
|
||||
*
|
||||
* XXX Actually, swap and root must be on the same type of device,
|
||||
* (ie. DV_DISK or DV_IFNET) because of how (*mountroot) is written.
|
||||
* That should be fixed.
|
||||
*/
|
||||
void
|
||||
setroot(void)
|
||||
{
|
||||
register struct swdevt *swp;
|
||||
register struct device *dv;
|
||||
register int len;
|
||||
dev_t nrootdev, nswapdev = NODEV;
|
||||
char buf[128];
|
||||
extern int (*mountroot) __P((void *));
|
||||
dev_t temp;
|
||||
struct device *bootdv, *rootdv, *swapdv;
|
||||
int bootpartition;
|
||||
#if defined(NFSCLIENT)
|
||||
extern char *nfsbootdevname;
|
||||
extern int nfs_mountroot __P((void *));
|
||||
#endif
|
||||
#if defined(FFS)
|
||||
extern int ffs_mountroot __P((void *));
|
||||
#endif
|
||||
|
||||
bootdv = booted_device;
|
||||
bootpartition = booted_partition;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("boot device: %s\n",
|
||||
(bootdv) ? bootdv->dv_xname : "<unknown>");
|
||||
#endif
|
||||
/*
|
||||
* If `swap generic' and we couldn't determine boot device,
|
||||
* ask the user.
|
||||
*/
|
||||
if (mountroot == NULL && bootdv == NULL)
|
||||
boothowto |= RB_ASKNAME;
|
||||
|
||||
if (boothowto & RB_ASKNAME) {
|
||||
for (;;) {
|
||||
printf("root device");
|
||||
if (bootdv != NULL)
|
||||
printf(" (default %s%c)", bootdv->dv_xname,
|
||||
bootdv->dv_class == DV_DISK ? 'a' : ' ');
|
||||
printf(": ");
|
||||
len = getstr(buf, sizeof(buf));
|
||||
if (len == 0 && bootdv != NULL) {
|
||||
strcpy(buf, bootdv->dv_xname);
|
||||
len = strlen(buf);
|
||||
}
|
||||
if (len == 4 && !strcmp(buf, "halt"))
|
||||
boot(RB_HALT);
|
||||
if (len > 0 && buf[len - 1] == '*') {
|
||||
buf[--len] = '\0';
|
||||
dv = getdisk(buf, len, 1, &nrootdev);
|
||||
if (dv != NULL) {
|
||||
rootdv = dv;
|
||||
nswapdev = nrootdev;
|
||||
goto gotswap;
|
||||
}
|
||||
}
|
||||
dv = getdisk(buf, len, bootpartition, &nrootdev);
|
||||
if (dv != NULL) {
|
||||
rootdv = dv;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* because swap must be on same device as root, for
|
||||
* network devices this is easy.
|
||||
*/
|
||||
if (rootdv->dv_class == DV_IFNET) {
|
||||
swapdv = NULL;
|
||||
goto gotswap;
|
||||
}
|
||||
for (;;) {
|
||||
printf("swap device");
|
||||
if (rootdv != NULL)
|
||||
printf(" (default %s%c)", rootdv->dv_xname,
|
||||
rootdv->dv_class == DV_DISK ? 'b' : ' ');
|
||||
printf(": ");
|
||||
len = getstr(buf, sizeof(buf));
|
||||
if (len == 0) {
|
||||
switch (rootdv->dv_class) {
|
||||
case DV_IFNET:
|
||||
nswapdev = NODEV;
|
||||
break;
|
||||
case DV_DISK:
|
||||
nswapdev = MAKEDISKDEV(major(nrootdev),
|
||||
DISKUNIT(minor(nrootdev)), 1);
|
||||
break;
|
||||
case DV_TAPE:
|
||||
case DV_TTY:
|
||||
case DV_DULL:
|
||||
case DV_CPU:
|
||||
break;
|
||||
}
|
||||
swapdv = rootdv;
|
||||
break;
|
||||
}
|
||||
if (len == 4 && !strcmp(buf, "halt"))
|
||||
boot(RB_HALT);
|
||||
dv = getdisk(buf, len, 1, &nswapdev);
|
||||
if (dv) {
|
||||
if (dv->dv_class == DV_IFNET)
|
||||
nswapdev = NODEV;
|
||||
swapdv = dv;
|
||||
break;
|
||||
}
|
||||
}
|
||||
gotswap:
|
||||
rootdev = nrootdev;
|
||||
dumpdev = nswapdev;
|
||||
swdevt[0].sw_dev = nswapdev;
|
||||
swdevt[1].sw_dev = NODEV;
|
||||
|
||||
} else if (mountroot == NULL) {
|
||||
int majdev;
|
||||
|
||||
/*
|
||||
* "swap generic"
|
||||
*/
|
||||
majdev = findblkmajor(bootdv);
|
||||
if (majdev >= 0) {
|
||||
/*
|
||||
* Root and swap are on a disk.
|
||||
*/
|
||||
rootdv = swapdv = bootdv;
|
||||
rootdev =
|
||||
MAKEDISKDEV(majdev, bootdv->dv_unit, bootpartition);
|
||||
nswapdev = dumpdev =
|
||||
MAKEDISKDEV(majdev, bootdv->dv_unit, 1);
|
||||
} else {
|
||||
/*
|
||||
* Root and swap are on a net.
|
||||
*/
|
||||
rootdv = swapdv = bootdv;
|
||||
nswapdev = dumpdev = NODEV;
|
||||
}
|
||||
swdevt[0].sw_dev = nswapdev;
|
||||
swdevt[1].sw_dev = NODEV;
|
||||
|
||||
} else {
|
||||
|
||||
/*
|
||||
* `root DEV swap DEV': honour rootdev/swdevt.
|
||||
* rootdev/swdevt/mountroot already properly set.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
switch (rootdv->dv_class) {
|
||||
#if defined(NFSCLIENT)
|
||||
case DV_IFNET:
|
||||
mountroot = nfs_mountroot;
|
||||
nfsbootdevname = rootdv->dv_xname;
|
||||
return;
|
||||
#endif
|
||||
#if defined(FFS)
|
||||
case DV_DISK:
|
||||
mountroot = ffs_mountroot;
|
||||
printf("root on %s%c", rootdv->dv_xname,
|
||||
DISKPART(rootdev) + 'a');
|
||||
if (nswapdev != NODEV)
|
||||
printf(" swap on %s%c", swapdv->dv_xname,
|
||||
DISKPART(nswapdev) + 'a');
|
||||
printf("\n");
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
printf("can't figure root, hope your kernel is right\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make the swap partition on the root drive the primary swap.
|
||||
*/
|
||||
temp = NODEV;
|
||||
for (swp = swdevt; swp->sw_dev != NODEV; swp++) {
|
||||
if (major(rootdev) == major(swp->sw_dev) &&
|
||||
DISKUNIT(rootdev) == DISKUNIT(minor(swp->sw_dev))) {
|
||||
temp = swdevt[0].sw_dev;
|
||||
swdevt[0].sw_dev = swp->sw_dev;
|
||||
swp->sw_dev = temp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (swp->sw_dev == NODEV)
|
||||
return;
|
||||
|
||||
/*
|
||||
* If dumpdev was the same as the old primary swap device, move
|
||||
* it to the new primary swap device.
|
||||
*/
|
||||
if (temp == dumpdev)
|
||||
dumpdev = swdevt[0].sw_dev;
|
||||
}
|
||||
|
||||
static int
|
||||
getstr(cp, size)
|
||||
register char *cp;
|
||||
register int size;
|
||||
{
|
||||
register char *lp;
|
||||
register int c;
|
||||
register int len;
|
||||
|
||||
lp = cp;
|
||||
len = 0;
|
||||
for (;;) {
|
||||
c = cngetc();
|
||||
switch (c) {
|
||||
case '\n':
|
||||
case '\r':
|
||||
printf("\n");
|
||||
*lp++ = '\0';
|
||||
return (len);
|
||||
case '\b':
|
||||
case '\177':
|
||||
case '#':
|
||||
if (len) {
|
||||
--len;
|
||||
--lp;
|
||||
printf("\b \b");
|
||||
}
|
||||
continue;
|
||||
case '@':
|
||||
case 'u'&037:
|
||||
len = 0;
|
||||
lp = cp;
|
||||
printf("\n");
|
||||
continue;
|
||||
default:
|
||||
if (len + 1 >= size || c < ' ') {
|
||||
printf("\007");
|
||||
continue;
|
||||
}
|
||||
printf("%c", c);
|
||||
++len;
|
||||
*lp++ = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
u_long bootdev; /* should be dev_t, but not until 32 bits */
|
||||
|
||||
/*
|
||||
* Yanked from i386/i386/autoconf.c (and tweaked a bit)
|
||||
*/
|
||||
static void
|
||||
findbootdev()
|
||||
{
|
||||
struct device *dv;
|
||||
int major, unit;
|
||||
|
||||
booted_device = NULL;
|
||||
booted_partition = 0; /* Assume root is on partition a */
|
||||
|
||||
major = B_TYPE(bootdev);
|
||||
if (major < 0 || major >= nblkdev)
|
||||
return;
|
||||
|
||||
unit = B_UNIT(bootdev);
|
||||
|
||||
bootdev &= ~(B_UNITMASK << B_UNITSHIFT);
|
||||
unit = target_to_unit(-1, unit, 0);
|
||||
bootdev |= (unit << B_UNITSHIFT);
|
||||
|
||||
if (disk_count <= 0)
|
||||
return;
|
||||
|
||||
for (dv = alldevs.tqh_first; dv != NULL; dv = dv->dv_list.tqe_next) {
|
||||
if (dv->dv_class == DV_DISK && major == findblkmajor(dv) &&
|
||||
unit == dv->dv_unit) {
|
||||
booted_device = dv;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Map a SCSI bus, target, lun to a device number.
|
||||
|
@ -166,7 +511,8 @@ struct device *bootdv = NULL;
|
|||
* assumes DISK. It would be nice to allow CD, too...
|
||||
*/
|
||||
static int
|
||||
target_to_unit(u_long bus, u_long target, u_long lun)
|
||||
target_to_unit(bus, target, lun)
|
||||
u_long bus, target, lun;
|
||||
{
|
||||
struct scsibus_softc *scsi;
|
||||
struct scsi_link *sc_link;
|
||||
|
@ -208,319 +554,3 @@ extern struct cfdriver scsibus_cd;
|
|||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* swiped from sparc/sparc/autoconf.c */
|
||||
static int
|
||||
findblkmajor(register struct disk *dv)
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i=0 ; i<nblkdev ; i++) {
|
||||
if ((void (*)(struct buf *))bdevsw[i].d_strategy ==
|
||||
dv->dk_driver->d_strategy)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Yanked from i386/i386/autoconf.c
|
||||
*/
|
||||
static void
|
||||
findbootdev(void)
|
||||
{
|
||||
register struct device *dv;
|
||||
register struct disk *diskp;
|
||||
register int unit;
|
||||
int major;
|
||||
|
||||
major = B_TYPE(bootdev);
|
||||
if (major < 0 || major >= nblkdev)
|
||||
return;
|
||||
|
||||
unit = B_UNIT(bootdev);
|
||||
|
||||
bootdev &= ~(B_UNITMASK << B_UNITSHIFT);
|
||||
unit = target_to_unit(-1, unit, 0);
|
||||
bootdev |= (unit << B_UNITSHIFT);
|
||||
|
||||
if (disk_count <= 0)
|
||||
return;
|
||||
|
||||
for (dv = alldevs.tqh_first; dv != NULL; dv = dv->dv_list.tqe_next) {
|
||||
if ((dv->dv_class == DV_DISK) && (unit == dv->dv_unit)) {
|
||||
/*
|
||||
* Find the disk corresponding to the current
|
||||
* device.
|
||||
*/
|
||||
if ((diskp = disk_find(dv->dv_xname)) == NULL)
|
||||
continue;
|
||||
|
||||
if (major == findblkmajor(diskp)) {
|
||||
bootdv = dv;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to find the device from which we were booted.
|
||||
* If we can do so, and not instructed not to do so,
|
||||
* change rootdev to correspond to the load device.
|
||||
*/
|
||||
static void
|
||||
setroot(void)
|
||||
{
|
||||
register struct swdevt *swp;
|
||||
register int majdev, mindev, part;
|
||||
dev_t nrootdev, temp;
|
||||
|
||||
if (boothowto & RB_DFLTROOT)
|
||||
return;
|
||||
findbootdev();
|
||||
if (bootdv == NULL) {
|
||||
printf("ARGH!! No boot device????");
|
||||
delay(10000000);
|
||||
/* panic("ARGH!! No boot device????"); */
|
||||
}
|
||||
nrootdev = 0;
|
||||
switch (bootdv->dv_class) {
|
||||
case DV_DISK:
|
||||
nrootdev = makedev(B_TYPE(bootdev),
|
||||
(B_UNIT(bootdev) << UNITSHIFT)
|
||||
+ B_PARTITION(bootdev));
|
||||
break;
|
||||
default:
|
||||
printf("Only supports DISK device for booting.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (rootdev == nrootdev)
|
||||
return;
|
||||
|
||||
majdev = major(nrootdev);
|
||||
mindev = minor(nrootdev);
|
||||
part = mindev & PARTITIONMASK;
|
||||
mindev -= part;
|
||||
|
||||
rootdev = nrootdev;
|
||||
printf("Changing root device to %s%c.\n", bootdv->dv_xname, part+'a');
|
||||
|
||||
temp = NODEV;
|
||||
for (swp = swdevt ; swp->sw_dev != NODEV ; swp++) {
|
||||
if (majdev == major(swp->sw_dev) &&
|
||||
mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) {
|
||||
temp = swdevt[0].sw_dev;
|
||||
swdevt[0].sw_dev = swp->sw_dev;
|
||||
swp->sw_dev = temp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (swp->sw_dev == NODEV)
|
||||
return;
|
||||
|
||||
if (temp == dumpdev)
|
||||
dumpdev = swdevt[0].sw_dev;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generic "bus" support functions. From NetBSD/sun3.
|
||||
*
|
||||
* bus_scan:
|
||||
* This function is passed to config_search() by the attach function
|
||||
* for each of the "bus" drivers (obio, nubus).
|
||||
* The purpose of this function is to copy the "locators" into our
|
||||
* confargs structure, so child drivers may use the confargs both
|
||||
* as match parameters and as temporary storage for the defaulted
|
||||
* locator values determined in the child_match and preserved for
|
||||
* the child_attach function. If the bus attach functions just
|
||||
* used config_found, then we would not have an opportunity to
|
||||
* setup the confargs for each child match and attach call.
|
||||
*
|
||||
* bus_print:
|
||||
* Just prints out the final (non-default) locators.
|
||||
*/
|
||||
int
|
||||
bus_scan(parent, child, aux)
|
||||
struct device *parent;
|
||||
void *child, *aux;
|
||||
{
|
||||
struct cfdata *cf = child;
|
||||
struct confargs *ca = aux;
|
||||
cfmatch_t mf;
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
if (parent->dv_cfdata->cf_driver->cd_indirect)
|
||||
panic("bus_scan: indirect?");
|
||||
if (cf->cf_fstate == FSTATE_STAR)
|
||||
panic("bus_scan: FSTATE_STAR");
|
||||
#endif
|
||||
|
||||
/* ca->ca_bustype set by parent */
|
||||
|
||||
/*
|
||||
* Note that this allows the match function to save
|
||||
* defaulted locators in the confargs that will be
|
||||
* preserved for the related attach call.
|
||||
*/
|
||||
mf = cf->cf_attach->ca_match;
|
||||
if ((*mf)(parent, cf, ca) > 0) {
|
||||
config_attach(parent, cf, ca, bus_print);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* From NetBSD/sun3.
|
||||
* Print out the confargs. The parent name is non-NULL
|
||||
* when there was no match found by config_found().
|
||||
*/
|
||||
int
|
||||
bus_print(args, name)
|
||||
void *args;
|
||||
char *name;
|
||||
{
|
||||
/* struct confargs *ca = args; */
|
||||
|
||||
if (name)
|
||||
printf("%s:", name);
|
||||
|
||||
return(UNCONF);
|
||||
}
|
||||
|
||||
vm_offset_t tmp_vpages[1];
|
||||
|
||||
/*
|
||||
* Read addr with size len (1,2,4) into val.
|
||||
* If this generates a bus error, return -1
|
||||
*
|
||||
* Create a temporary mapping,
|
||||
* Try the access using peek_*
|
||||
* Clean up temp. mapping
|
||||
*/
|
||||
int
|
||||
bus_peek(bustype, paddr, sz)
|
||||
int bustype;
|
||||
vm_offset_t paddr;
|
||||
int sz;
|
||||
{
|
||||
int off, pte, rv;
|
||||
vm_offset_t pgva;
|
||||
caddr_t va;
|
||||
|
||||
if (bustype != BUS_NUBUS)
|
||||
return -1;
|
||||
|
||||
off = paddr & PGOFSET;
|
||||
paddr -= off;
|
||||
pte = (paddr & PG_FRAME) | (PG_V | PG_W | PG_CI);
|
||||
|
||||
pgva = tmp_vpages[0];
|
||||
va = (caddr_t)pgva + off;
|
||||
|
||||
mac68k_set_pte(pgva, pte);
|
||||
TBIS(pgva);
|
||||
|
||||
/*
|
||||
* OK, try the access using one of the assembly routines
|
||||
* that will set pcb_onfault and catch any bus errors.
|
||||
*/
|
||||
rv = -1;
|
||||
switch (sz) {
|
||||
case 1:
|
||||
if (!badbaddr(va))
|
||||
rv = *((u_char *) va);
|
||||
break;
|
||||
case 2:
|
||||
if (!badwaddr(va))
|
||||
rv = *((u_int16_t *) va);
|
||||
break;
|
||||
case 4:
|
||||
if (!badladdr(va))
|
||||
rv = *((u_int32_t *) va);
|
||||
break;
|
||||
default:
|
||||
printf("bus_peek: invalid size=%d\n", sz);
|
||||
rv = -1;
|
||||
}
|
||||
|
||||
mac68k_set_pte(pgva, PG_NV);
|
||||
TBIS(pgva);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
char *
|
||||
bus_mapin(bustype, paddr, sz)
|
||||
int bustype, paddr, sz;
|
||||
{
|
||||
int off, pa, pmt;
|
||||
vm_offset_t va, retval;
|
||||
|
||||
if (bustype != BUS_NUBUS)
|
||||
return (NULL);
|
||||
|
||||
off = paddr & PGOFSET;
|
||||
pa = paddr - off;
|
||||
sz += off;
|
||||
sz = mac68k_round_page(sz);
|
||||
|
||||
/* Get some kernel virtual address space. */
|
||||
va = kmem_alloc_wait(kernel_map, sz);
|
||||
if (va == 0)
|
||||
panic("bus_mapin");
|
||||
retval = va + off;
|
||||
|
||||
/* Map it to the specified bus. */
|
||||
#if 0 /* XXX */
|
||||
/* This has a problem with wrap-around... */
|
||||
pmap_map((int)va, pa | pmt, pa + sz, VM_PROT_ALL);
|
||||
#else
|
||||
do {
|
||||
pmap_enter(pmap_kernel(), va, pa | pmt, VM_PROT_ALL, FALSE);
|
||||
va += NBPG;
|
||||
pa += NBPG;
|
||||
} while ((sz -= NBPG) > 0);
|
||||
#endif
|
||||
|
||||
return ((char*)retval);
|
||||
}
|
||||
|
||||
static int
|
||||
mainbus_match(parent, match, aux)
|
||||
struct device *parent;
|
||||
void *match, *aux;
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int bus_order[] = {
|
||||
BUS_OBIO, /* For On-board I/O */
|
||||
BUS_NUBUS
|
||||
};
|
||||
#define BUS_ORDER_SZ (sizeof(bus_order)/sizeof(bus_order[0]))
|
||||
|
||||
static void
|
||||
mainbus_attach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct confargs ca;
|
||||
int i;
|
||||
|
||||
printf("\n");
|
||||
|
||||
for (i = 0; i < BUS_ORDER_SZ; i++) {
|
||||
ca.ca_bustype = bus_order[i];
|
||||
(void) config_found(self, &ca, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
struct cfattach mainbus_ca = {
|
||||
sizeof(struct device), mainbus_match, mainbus_attach
|
||||
};
|
||||
|
||||
struct cfdriver mainbus_cd = {
|
||||
NULL, "mainbus", DV_DULL
|
||||
};
|
||||
|
|
|
@ -0,0 +1,292 @@
|
|||
/* $NetBSD: mainbus.c,v 1.1 1996/06/19 03:21:05 scottr Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 University of Utah.
|
||||
* Copyright (c) 1982, 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* the Systems Programming Group of the University of Utah Computer
|
||||
* Science Department.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
/*-
|
||||
* Copyright (C) 1996 Allen K. Briggs
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Allen Briggs.
|
||||
* 4. The names of the Alice Group or any of its members may not be used
|
||||
* to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE ALICE GROUP ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE ALICE GROUP BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/dmap.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_kern.h>
|
||||
#include <vm/vm_map.h>
|
||||
|
||||
#include <machine/autoconf.h>
|
||||
#include <machine/vmparam.h>
|
||||
#include <machine/param.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/pte.h>
|
||||
|
||||
/*
|
||||
* Generic "bus" support functions. From NetBSD/sun3.
|
||||
*
|
||||
* bus_scan:
|
||||
* This function is passed to config_search() by the attach function
|
||||
* for each of the "bus" drivers (obio, nubus).
|
||||
* The purpose of this function is to copy the "locators" into our
|
||||
* confargs structure, so child drivers may use the confargs both
|
||||
* as match parameters and as temporary storage for the defaulted
|
||||
* locator values determined in the child_match and preserved for
|
||||
* the child_attach function. If the bus attach functions just
|
||||
* used config_found, then we would not have an opportunity to
|
||||
* setup the confargs for each child match and attach call.
|
||||
*
|
||||
* bus_print:
|
||||
* Just prints out the final (non-default) locators.
|
||||
*/
|
||||
int
|
||||
bus_scan(parent, child, aux)
|
||||
struct device *parent;
|
||||
void *child, *aux;
|
||||
{
|
||||
struct cfdata *cf = child;
|
||||
struct confargs *ca = aux;
|
||||
cfmatch_t mf;
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
if (parent->dv_cfdata->cf_driver->cd_indirect)
|
||||
panic("bus_scan: indirect?");
|
||||
if (cf->cf_fstate == FSTATE_STAR)
|
||||
panic("bus_scan: FSTATE_STAR");
|
||||
#endif
|
||||
|
||||
/* ca->ca_bustype set by parent */
|
||||
|
||||
/*
|
||||
* Note that this allows the match function to save
|
||||
* defaulted locators in the confargs that will be
|
||||
* preserved for the related attach call.
|
||||
*/
|
||||
mf = cf->cf_attach->ca_match;
|
||||
if ((*mf)(parent, cf, ca) > 0) {
|
||||
config_attach(parent, cf, ca, bus_print);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* From NetBSD/sun3.
|
||||
* Print out the confargs. The parent name is non-NULL
|
||||
* when there was no match found by config_found().
|
||||
*/
|
||||
int
|
||||
bus_print(args, name)
|
||||
void *args;
|
||||
char *name;
|
||||
{
|
||||
/* struct confargs *ca = args; */
|
||||
|
||||
if (name)
|
||||
printf("%s:", name);
|
||||
|
||||
return(UNCONF);
|
||||
}
|
||||
|
||||
vm_offset_t tmp_vpages[1];
|
||||
|
||||
/*
|
||||
* Read addr with size len (1,2,4) into val.
|
||||
* If this generates a bus error, return -1
|
||||
*
|
||||
* Create a temporary mapping,
|
||||
* Try the access using peek_*
|
||||
* Clean up temp. mapping
|
||||
*/
|
||||
int
|
||||
bus_peek(bustype, paddr, sz)
|
||||
int bustype;
|
||||
vm_offset_t paddr;
|
||||
int sz;
|
||||
{
|
||||
int off, pte, rv;
|
||||
vm_offset_t pgva;
|
||||
caddr_t va;
|
||||
|
||||
if (bustype != BUS_NUBUS)
|
||||
return -1;
|
||||
|
||||
off = paddr & PGOFSET;
|
||||
paddr -= off;
|
||||
pte = (paddr & PG_FRAME) | (PG_V | PG_W | PG_CI);
|
||||
|
||||
pgva = tmp_vpages[0];
|
||||
va = (caddr_t)pgva + off;
|
||||
|
||||
mac68k_set_pte(pgva, pte);
|
||||
TBIS(pgva);
|
||||
|
||||
/*
|
||||
* OK, try the access using one of the assembly routines
|
||||
* that will set pcb_onfault and catch any bus errors.
|
||||
*/
|
||||
rv = -1;
|
||||
switch (sz) {
|
||||
case 1:
|
||||
if (!badbaddr(va))
|
||||
rv = *((u_char *) va);
|
||||
break;
|
||||
case 2:
|
||||
if (!badwaddr(va))
|
||||
rv = *((u_int16_t *) va);
|
||||
break;
|
||||
case 4:
|
||||
if (!badladdr(va))
|
||||
rv = *((u_int32_t *) va);
|
||||
break;
|
||||
default:
|
||||
printf("bus_peek: invalid size=%d\n", sz);
|
||||
rv = -1;
|
||||
}
|
||||
|
||||
mac68k_set_pte(pgva, PG_NV);
|
||||
TBIS(pgva);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
char *
|
||||
bus_mapin(bustype, paddr, sz)
|
||||
int bustype, paddr, sz;
|
||||
{
|
||||
int off, pa, pmt;
|
||||
vm_offset_t va, retval;
|
||||
|
||||
if (bustype != BUS_NUBUS)
|
||||
return (NULL);
|
||||
|
||||
off = paddr & PGOFSET;
|
||||
pa = paddr - off;
|
||||
sz += off;
|
||||
sz = mac68k_round_page(sz);
|
||||
|
||||
/* Get some kernel virtual address space. */
|
||||
va = kmem_alloc_wait(kernel_map, sz);
|
||||
if (va == 0)
|
||||
panic("bus_mapin");
|
||||
retval = va + off;
|
||||
|
||||
/* Map it to the specified bus. */
|
||||
#if 0 /* XXX */
|
||||
/* This has a problem with wrap-around... */
|
||||
pmap_map((int)va, pa | pmt, pa + sz, VM_PROT_ALL);
|
||||
#else
|
||||
do {
|
||||
pmap_enter(pmap_kernel(), va, pa | pmt, VM_PROT_ALL, FALSE);
|
||||
va += NBPG;
|
||||
pa += NBPG;
|
||||
} while ((sz -= NBPG) > 0);
|
||||
#endif
|
||||
|
||||
return ((char*)retval);
|
||||
}
|
||||
|
||||
static int mainbus_match __P((struct device *, void *, void *));
|
||||
static void mainbus_attach __P((struct device *parent,
|
||||
struct device *self, void *aux));
|
||||
|
||||
static int
|
||||
mainbus_match(parent, match, aux)
|
||||
struct device *parent;
|
||||
void *match, *aux;
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int bus_order[] = {
|
||||
BUS_OBIO, /* For On-board I/O */
|
||||
BUS_NUBUS
|
||||
};
|
||||
#define BUS_ORDER_SZ (sizeof(bus_order)/sizeof(bus_order[0]))
|
||||
|
||||
static void
|
||||
mainbus_attach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct confargs ca;
|
||||
int i;
|
||||
|
||||
printf("\n");
|
||||
|
||||
for (i = 0; i < BUS_ORDER_SZ; i++) {
|
||||
ca.ca_bustype = bus_order[i];
|
||||
(void) config_found(self, &ca, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
struct cfattach mainbus_ca = {
|
||||
sizeof(struct device), mainbus_match, mainbus_attach
|
||||
};
|
||||
|
||||
struct cfdriver mainbus_cd = {
|
||||
NULL, "mainbus", DV_DULL
|
||||
};
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: swapgeneric.c,v 1.9 1996/05/05 06:18:56 briggs Exp $ */
|
||||
/* $NetBSD: swapgeneric.c,v 1.10 1996/06/19 03:21:06 scottr Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986 Regents of the University of California.
|
||||
|
@ -35,173 +35,19 @@
|
|||
* @(#)swapgeneric.c 7.5 (Berkeley) 5/7/91
|
||||
*/
|
||||
|
||||
/*
|
||||
* fake swapgeneric.c -- should do this differently.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/disklabel.h>
|
||||
|
||||
#include <dev/cons.h>
|
||||
|
||||
#include <ufs/ffs/ffs_extern.h>
|
||||
|
||||
#include <machine/pte.h>
|
||||
|
||||
#include "sd.h"
|
||||
#include "cd.h"
|
||||
int (*mountroot) __P((void *)) = NULL; /* tells autoconf.c that we are "generic" */
|
||||
|
||||
dev_t rootdev = NODEV;
|
||||
dev_t dumpdev = NODEV;
|
||||
|
||||
struct swdevt swdevt[] = {
|
||||
{ NODEV, 1, 0 },
|
||||
{ NODEV, 0, 0 },
|
||||
{ NODEV, 0, 0 },
|
||||
};
|
||||
|
||||
#if NSD > 0
|
||||
extern struct cfdriver sd_cd;
|
||||
#endif
|
||||
#if NCD > 0
|
||||
extern struct cfdriver cd_cd;
|
||||
#endif
|
||||
|
||||
struct genericconf {
|
||||
struct cfdriver *gc_driver;
|
||||
char *gc_name;
|
||||
dev_t gc_root;
|
||||
} genericconf[] = {
|
||||
#if NSD > 0
|
||||
{ &sd_cd, "sd", makedev(4,0) },
|
||||
#endif
|
||||
#if NCD > 0
|
||||
{ &cd_cd, "cd", makedev(6,0) },
|
||||
#endif
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
void setconf __P((void));
|
||||
void doboot __P((void));
|
||||
void gets __P((char *));
|
||||
int (*mountroot) __P((void)) = ffs_mountroot;
|
||||
|
||||
void
|
||||
setconf()
|
||||
{
|
||||
register struct genericconf *gc = NULL;
|
||||
int unit, swaponroot = 0;
|
||||
char *root_swap;
|
||||
|
||||
if (genericconf[0].gc_driver == 0)
|
||||
goto verybad;
|
||||
|
||||
if (boothowto & RB_MINIROOT)
|
||||
root_swap = "swap";
|
||||
else {
|
||||
if (rootdev != NODEV)
|
||||
goto doswap;
|
||||
root_swap = "root";
|
||||
}
|
||||
|
||||
if (boothowto & RB_ASKNAME) {
|
||||
char name[128];
|
||||
retry:
|
||||
printf("%s device? ", root_swap);
|
||||
gets(name);
|
||||
for (gc = genericconf; gc->gc_driver; gc++)
|
||||
if (gc->gc_name[0] == name[0] &&
|
||||
gc->gc_name[1] == name[1])
|
||||
goto gotit;
|
||||
printf("use one of:");
|
||||
for (gc = genericconf; gc->gc_driver; gc++)
|
||||
printf(" %s%%d", gc->gc_name);
|
||||
printf("\n");
|
||||
goto retry;
|
||||
gotit:
|
||||
if (name[3] == '*') {
|
||||
name[3] = name[4];
|
||||
swaponroot++;
|
||||
}
|
||||
if (name[2] >= '0' && name[2] <= '7' && name[3] == 0) {
|
||||
unit = name[2] - '0';
|
||||
goto found;
|
||||
}
|
||||
printf("bad/missing unit number\n");
|
||||
}
|
||||
unit = 0;
|
||||
for (gc = genericconf; gc->gc_driver; gc++) {
|
||||
if (gc->gc_driver->cd_ndevs > unit &&
|
||||
gc->gc_driver->cd_devs[unit]) {
|
||||
printf("Trying %s on %s0\n", root_swap, gc->gc_name);
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
verybad:
|
||||
printf("no suitable %s", root_swap);
|
||||
if (root_swap[0] == 's') {
|
||||
printf("\n");
|
||||
goto doswap;
|
||||
}
|
||||
printf(" -- hit any key to reboot\n");
|
||||
cngetc();
|
||||
doboot();
|
||||
printf(" Automatic reboot failed.\n");
|
||||
printf("You may reboot or turn the machine off, now.\n");
|
||||
for(;;);
|
||||
|
||||
found:
|
||||
gc->gc_root = makedev(major(gc->gc_root), unit * MAXPARTITIONS);
|
||||
if ((boothowto & RB_MINIROOT) == 0) {
|
||||
rootdev = gc->gc_root;
|
||||
}
|
||||
doswap:
|
||||
if (gc)
|
||||
swdevt[0].sw_dev = dumpdev =
|
||||
makedev(major(gc->gc_root), minor(gc->gc_root) + 1);
|
||||
else
|
||||
swdevt[0].sw_dev = dumpdev =
|
||||
makedev(major(rootdev), minor(rootdev) + 1);
|
||||
/* swap size and dumplo set during autoconfigure */
|
||||
if (swaponroot)
|
||||
rootdev = dumpdev;
|
||||
}
|
||||
|
||||
void
|
||||
gets(cp)
|
||||
char *cp;
|
||||
{
|
||||
register char *lp;
|
||||
register int c;
|
||||
|
||||
lp = cp;
|
||||
for (;;) {
|
||||
cnputc(c=cngetc());
|
||||
switch (c) {
|
||||
case '\n':
|
||||
case '\r':
|
||||
*lp++ = '\0';
|
||||
return;
|
||||
case '\b':
|
||||
case '\177':
|
||||
if (lp > cp) {
|
||||
lp--;
|
||||
cnputc(' ');
|
||||
cnputc('\b');
|
||||
}
|
||||
continue;
|
||||
case '#':
|
||||
lp--;
|
||||
if (lp < cp)
|
||||
lp = cp;
|
||||
continue;
|
||||
case '@':
|
||||
case 'u'&037:
|
||||
lp = cp;
|
||||
cnputc('\n');
|
||||
continue;
|
||||
default:
|
||||
*lp++ = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue