Use the new machine-independent setroot().
This commit is contained in:
parent
8496115a38
commit
8763a04e25
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: autoconf.c,v 1.30 1997/01/30 08:59:29 thorpej Exp $ */
|
||||
/* $NetBSD: autoconf.c,v 1.31 1997/01/31 01:49:41 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 Jason R. Thorpe. All rights reserved.
|
||||
|
@ -74,6 +74,7 @@
|
|||
#include <sys/dmap.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
#include <dev/cons.h>
|
||||
|
@ -110,9 +111,7 @@ extern char *extiobase;
|
|||
|
||||
/* The boot device. */
|
||||
struct device *booted_device;
|
||||
|
||||
/* The device we mount as root. */
|
||||
struct device *root_device;
|
||||
int booted_partition;
|
||||
|
||||
/* How we were booted. */
|
||||
u_int bootdev;
|
||||
|
@ -162,8 +161,6 @@ ddlist_t dev_data_list; /* all dev_datas */
|
|||
ddlist_t dev_data_list_hpib; /* hpib controller dev_datas */
|
||||
ddlist_t dev_data_list_scsi; /* scsi controller dev_datas */
|
||||
|
||||
void setroot __P((void));
|
||||
void swapconf __P((void));
|
||||
void findbootdev __P((void));
|
||||
void findbootdev_slave __P((ddlist_t *, int, int, int));
|
||||
void setbootdev __P((void));
|
||||
|
@ -231,14 +228,26 @@ mainbussearch(parent, cf, aux)
|
|||
return (0);
|
||||
}
|
||||
|
||||
struct devnametobdevmaj hp300_nam2blk[] = {
|
||||
{ "ct", 0 },
|
||||
{ "rd", 2 },
|
||||
{ "sd", 4 },
|
||||
#ifdef notyet
|
||||
{ "md", 0 },
|
||||
#endif
|
||||
{ NULL, 0 },
|
||||
};
|
||||
|
||||
/*
|
||||
* Determine the device configuration for the running system.
|
||||
*/
|
||||
void
|
||||
configure()
|
||||
{
|
||||
register struct hp_hw *hw;
|
||||
int found;
|
||||
extern int (*mountroot) __P((void));
|
||||
struct dev_data *dd;
|
||||
struct device *dv;
|
||||
struct vfsops *vops;
|
||||
|
||||
/*
|
||||
* Initialize the dev_data_lists.
|
||||
|
@ -291,8 +300,45 @@ configure()
|
|||
}
|
||||
}
|
||||
|
||||
setroot();
|
||||
dv = booted_device;
|
||||
|
||||
/*
|
||||
* If wild carded root device and wired down NFS root file system,
|
||||
* pick the network interface device to use.
|
||||
*/
|
||||
if (rootspec == NULL) {
|
||||
vops = vfs_getopsbyname("nfs");
|
||||
if (vops != NULL && vops->vfs_mountroot == mountroot) {
|
||||
for (dd = dev_data_list.lh_first;
|
||||
dd != NULL; dd = dd->dd_list.le_next) {
|
||||
if (dd->dd_dev->dv_class == DV_IFNET) {
|
||||
/* Got it! */
|
||||
dv = dd->dev;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (dd == NULL) {
|
||||
printf("no network interface for NFS root");
|
||||
dv = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If bootdev is bogus, ask the user anyhow.
|
||||
*/
|
||||
if (bootdev == 0)
|
||||
boothowto |= RB_ASKNAME;
|
||||
|
||||
/*
|
||||
* If we booted from tape, ask the user.
|
||||
*/
|
||||
if (booted_device != NULL && booted_device->dv_class == DV_TAPE)
|
||||
boothowto |= RB_ASKNAME;
|
||||
|
||||
setroot(dv, booted_partition, hp300_nam2blk);
|
||||
swapconf();
|
||||
dumpconf();
|
||||
|
||||
/*
|
||||
* Set bootdev based on how we mounted root.
|
||||
|
@ -394,446 +440,15 @@ device_register(dev, aux)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Configure swap space and related parameters.
|
||||
*/
|
||||
void
|
||||
swapconf()
|
||||
{
|
||||
struct swdevt *swp;
|
||||
int nblks, maj;
|
||||
|
||||
for (swp = swdevt; swp->sw_dev != NODEV; swp++) {
|
||||
maj = major(swp->sw_dev);
|
||||
if (maj > nblkdev)
|
||||
break;
|
||||
if (bdevsw[maj].d_psize) {
|
||||
nblks = (*bdevsw[maj].d_psize)(swp->sw_dev);
|
||||
if (nblks != -1 &&
|
||||
(swp->sw_nblks == 0 || swp->sw_nblks > nblks))
|
||||
swp->sw_nblks = nblks;
|
||||
swp->sw_nblks = ctod(dtoc(swp->sw_nblks));
|
||||
}
|
||||
}
|
||||
dumpconf();
|
||||
}
|
||||
|
||||
struct nam2blk {
|
||||
char *name;
|
||||
int maj;
|
||||
} nam2blk[] = {
|
||||
{ "ct", 0 },
|
||||
{ "rd", 2 },
|
||||
{ "sd", 4 },
|
||||
};
|
||||
|
||||
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))
|
||||
== 0)
|
||||
return (nam2blk[i].maj);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static char *
|
||||
findblkname(maj)
|
||||
int maj;
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < sizeof(nam2blk) / sizeof(nam2blk[0]); ++i)
|
||||
if (maj == nam2blk[i].maj)
|
||||
return (nam2blk[i].name);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
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(" halt\n");
|
||||
}
|
||||
return (dv);
|
||||
}
|
||||
|
||||
static 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);
|
||||
|
||||
if (len == 4 && !strcmp(str, "halt"))
|
||||
boot(RB_HALT, 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()
|
||||
{
|
||||
struct swdevt *swp;
|
||||
struct device *dv;
|
||||
register int len;
|
||||
dev_t nrootdev, nswapdev = NODEV;
|
||||
char buf[128], *rootdevname;
|
||||
extern int (*mountroot) __P((void *));
|
||||
dev_t temp;
|
||||
struct device *bootdv, *rootdv, *swapdv;
|
||||
int bootpartition = 0;
|
||||
#ifdef NFSCLIENT
|
||||
extern char *nfsbootdevname;
|
||||
extern int nfs_mountroot __P((void *));
|
||||
#endif
|
||||
#ifdef FFS
|
||||
extern int ffs_mountroot __P((void *));
|
||||
#endif
|
||||
|
||||
bootdv = booted_device;
|
||||
|
||||
/*
|
||||
* If 'swap generic' and we couldn't determine root device,
|
||||
* ask the user.
|
||||
*/
|
||||
if (mountroot == NULL && bootdv == NULL)
|
||||
boothowto |= RB_ASKNAME;
|
||||
|
||||
/*
|
||||
* If bootdev is bogus, ask the user anyhow.
|
||||
*/
|
||||
if (bootdev == 0)
|
||||
boothowto |= RB_ASKNAME;
|
||||
else
|
||||
bootpartition = B_PARTITION(bootdev);
|
||||
|
||||
/*
|
||||
* If we booted from tape, ask the user.
|
||||
*/
|
||||
if (bootdv != NULL && bootdv->dv_class == DV_TAPE)
|
||||
boothowto |= RB_ASKNAME;
|
||||
|
||||
if (boothowto & RB_ASKNAME) {
|
||||
for (;;) {
|
||||
printf("root device");
|
||||
if (bootdv != NULL) {
|
||||
printf(" (default %s", bootdv->dv_xname);
|
||||
if (bootdv->dv_class == DV_DISK)
|
||||
printf("%c", bootpartition + 'a');
|
||||
printf(")");
|
||||
}
|
||||
printf(": ");
|
||||
len = getstr(buf, sizeof(buf));
|
||||
if (len == 0 && bootdv != NULL) {
|
||||
strcpy(buf, bootdv->dv_xname);
|
||||
len = strlen(buf);
|
||||
}
|
||||
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 the same device type as root,
|
||||
* for network devices this is easy.
|
||||
*/
|
||||
if (rootdv->dv_class == DV_IFNET) {
|
||||
swapdv = NULL;
|
||||
goto gotswap;
|
||||
}
|
||||
for (;;) {
|
||||
printf("swap device");
|
||||
printf(" (default %s", rootdv->dv_xname);
|
||||
if (rootdv->dv_class == DV_DISK)
|
||||
printf("b");
|
||||
printf(")");
|
||||
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(nrootdev), 1);
|
||||
break;
|
||||
case DV_TAPE:
|
||||
case DV_TTY:
|
||||
case DV_DULL:
|
||||
case DV_CPU:
|
||||
break;
|
||||
}
|
||||
swapdv = rootdv;
|
||||
break;
|
||||
}
|
||||
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': honor rootdev/swdevt.
|
||||
* rootdev/swdevt/mountroot already properly set.
|
||||
*/
|
||||
|
||||
#ifdef NFSCLIENT
|
||||
if (mountroot == nfs_mountroot) {
|
||||
struct dev_data *dd;
|
||||
/*
|
||||
* `root on nfs'. Find the first network
|
||||
* interface.
|
||||
*/
|
||||
for (dd = dev_data_list.lh_first;
|
||||
dd != NULL; dd = dd->dd_list.le_next) {
|
||||
if (dd->dd_dev->dv_class == DV_IFNET) {
|
||||
/* Got it! */
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (dd == NULL) {
|
||||
printf("no network interface for NFS root");
|
||||
panic("setroot");
|
||||
}
|
||||
root_device = dd->dd_dev;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
rootdevname = findblkname(major(rootdev));
|
||||
if (rootdevname == NULL) {
|
||||
printf("unknown root device major 0x%x\n", rootdev);
|
||||
panic("setroot");
|
||||
}
|
||||
bzero(buf, sizeof(buf));
|
||||
sprintf(buf, "%s%d", rootdevname, DISKUNIT(rootdev));
|
||||
|
||||
for (dv = alldevs.tqh_first; dv != NULL;
|
||||
dv = dv->dv_list.tqe_next) {
|
||||
if (strcmp(buf, dv->dv_xname) == 0) {
|
||||
root_device = dv;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (dv == NULL) {
|
||||
printf("device %s (0x%x) not configured\n",
|
||||
buf, rootdev);
|
||||
panic("setroot");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
root_device = rootdv;
|
||||
|
||||
switch (rootdv->dv_class) {
|
||||
#ifdef NFSCLIENT
|
||||
case DV_IFNET:
|
||||
mountroot = nfs_mountroot;
|
||||
nfsbootdevname = rootdv->dv_xname;
|
||||
return;
|
||||
#endif
|
||||
#ifdef 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(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
findbootdev()
|
||||
{
|
||||
int type, ctlr, slave, punit;
|
||||
int type, ctlr, slave, punit, part;
|
||||
int scsiboot, hpibboot, netboot;
|
||||
struct dev_data *dd;
|
||||
|
||||
booted_device = NULL;
|
||||
booted_partition = 0;
|
||||
|
||||
if ((bootdev & B_MAGICMASK) != B_DEVMAGIC)
|
||||
return;
|
||||
|
@ -842,6 +457,7 @@ findbootdev()
|
|||
ctlr = B_ADAPTOR(bootdev);
|
||||
slave = B_CONTROLLER(bootdev);
|
||||
punit = B_UNIT(bootdev);
|
||||
part = B_PARTITION(bootdev);
|
||||
|
||||
scsiboot = (type == 4); /* sd major */
|
||||
hpibboot = (type == 0 || type == 2); /* ct/rd major */
|
||||
|
@ -889,7 +505,7 @@ findbootdev()
|
|||
booted_device->dv_xname, type);
|
||||
booted_device = NULL;
|
||||
}
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -910,11 +526,15 @@ findbootdev()
|
|||
booted_device->dv_xname, type);
|
||||
booted_device = NULL;
|
||||
}
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Oof! */
|
||||
printf("WARNING: UNKNOWN BOOT DEVICE TYPE = %d\n", type);
|
||||
|
||||
out:
|
||||
if (booted_device != NULL)
|
||||
booted_partition = part;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in New Issue