summaryrefslogtreecommitdiff
path: root/sys/arch/i386
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2006-05-20 22:40:33 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2006-05-20 22:40:33 +0000
commit88a1b9be8a60676bd3cac36d07bdeb82a3cf4d74 (patch)
treef18e410ad9ba5c0e4a96edff9a39015f3d0fc0c6 /sys/arch/i386
parent71adbf45e0e11c71feb213db6438efcd1c992d23 (diff)
Detect BOOTARG_BOOTMAC coming from PXE; search for interface and attempt
to boot from it. At the same time add -a support for network interface selection; tested by reyk, mk, deraadt on i386, cloned code applied to amd64 and tested a little bit less
Diffstat (limited to 'sys/arch/i386')
-rw-r--r--sys/arch/i386/i386/autoconf.c180
1 files changed, 120 insertions, 60 deletions
diff --git a/sys/arch/i386/i386/autoconf.c b/sys/arch/i386/i386/autoconf.c
index 9925d7a6d87..f64fac9698f 100644
--- a/sys/arch/i386/i386/autoconf.c
+++ b/sys/arch/i386/i386/autoconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: autoconf.c,v 1.60 2006/05/20 07:52:36 deraadt Exp $ */
+/* $OpenBSD: autoconf.c,v 1.61 2006/05/20 22:40:30 deraadt Exp $ */
/* $NetBSD: autoconf.c,v 1.20 1996/05/03 19:41:56 christos Exp $ */
/*-
@@ -52,6 +52,13 @@
#include <sys/conf.h>
#include <sys/reboot.h>
#include <sys/device.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+
+#include <net/if.h>
+#include <net/if_types.h>
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
#include <uvm/uvm_extern.h>
@@ -234,15 +241,48 @@ void
setroot()
{
int majdev, mindev, unit, part, adaptor;
+ struct swdevt *swp;
dev_t orootdev;
+#if defined(NFSCLIENT)
+ extern bios_bootmac_t *bios_bootmac;
+#endif
#ifdef DOSWAP
dev_t temp = 0;
#endif
- struct swdevt *swp;
+
+#if defined(NFSCLIENT)
+ if (bios_bootmac) {
+ extern char *nfsbootdevname;
+ struct ifnet *ifp;
+
+ mountroot = nfs_mountroot;
+ nfsbootdevname = NULL; /* we do not know */
+
+ printf("PXE boot MAC address %s, ",
+ ether_sprintf(bios_bootmac->mac));
+
+ for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL;
+ ifp = TAILQ_NEXT(ifp, if_list)) {
+ if ((ifp->if_type == IFT_ETHER ||
+ ifp->if_type == IFT_FDDI) &&
+ bcmp(bios_bootmac->mac,
+ ((struct arpcom *)ifp)->ac_enaddr,
+ ETHER_ADDR_LEN) == 0)
+ break;
+ }
+ if (ifp) {
+ nfsbootdevname = ifp->if_xname;
+ printf("interface %s\n", nfsbootdevname);
+ } else
+ printf("no interface selected\n");
+ return;
+ }
+#endif
if (boothowto & RB_DFLTROOT ||
(bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC)
return;
+
majdev = B_TYPE(bootdev);
if (findblkname(majdev) == NULL)
return;
@@ -252,6 +292,8 @@ setroot()
mindev = (unit * MAXPARTITIONS) + part;
orootdev = rootdev;
rootdev = makedev(majdev, mindev);
+ mountroot = dk_mountroot;
+
/*
* If the original rootdev is the same as the one
* just calculated, don't need to adjust the swap configuration.
@@ -345,66 +387,89 @@ rootconf()
{
register struct genericconf *gc;
int unit, part = 0;
+#if defined(NFSCLIENT)
+ struct ifnet *ifp;
+#endif
+ char name[128];
char *num;
if (boothowto & RB_ASKNAME) {
- char name[128];
-retry:
- printf("root device? ");
- cnpollc(TRUE);
- getsn(name, sizeof name);
- cnpollc(FALSE);
- if (*name == '\0')
- goto noask;
- for (gc = genericconf; gc->gc_driver; gc++)
- if (gc->gc_driver->cd_ndevs &&
- strncmp(gc->gc_name, name,
- strlen(gc->gc_name)) == 0)
+ while (1) {
+ printf("root device? ");
+ cnpollc(TRUE);
+ getsn(name, sizeof name);
+ cnpollc(FALSE);
+ if (*name == '\0')
break;
- if (gc->gc_driver) {
- num = &name[strlen(gc->gc_name)];
-
- unit = -2;
- do {
- if (unit != -2 && *num >= 'a' &&
- *num <= 'a'+MAXPARTITIONS-1 &&
- num[1] == '\0') {
- part = *num++ - 'a';
+ for (gc = genericconf; gc->gc_driver; gc++)
+ if (gc->gc_driver->cd_ndevs &&
+ strncmp(gc->gc_name, name,
+ strlen(gc->gc_name)) == 0)
+ break;
+ if (gc->gc_driver) {
+ num = &name[strlen(gc->gc_name)];
+
+ unit = -2;
+ do {
+ if (unit != -2 && *num >= 'a' &&
+ *num <= 'a'+MAXPARTITIONS-1 &&
+ num[1] == '\0') {
+ part = *num++ - 'a';
+ break;
+ }
+ if (unit == -2)
+ unit = 0;
+ unit = (unit * 10) + *num - '0';
+ if (*num < '0' || *num > '9')
+ unit = -1;
+ } while (unit != -1 && *++num);
+
+ if (unit < 0) {
+ printf("%s: not a unit number\n",
+ &name[strlen(gc->gc_name)]);
+ } else if (unit >= gc->gc_driver->cd_ndevs ||
+ gc->gc_driver->cd_devs[unit] == NULL) {
+ printf("%d: no such unit\n", unit);
+ } else {
+ printf("root on %s%d%c\n", gc->gc_name, unit,
+ 'a' + part);
+ rootdev = makedev(gc->gc_major,
+ unit * MAXPARTITIONS + part);
+ mountroot = dk_mountroot;
break;
}
- if (unit == -2)
- unit = 0;
- unit = (unit * 10) + *num - '0';
- if (*num < '0' || *num > '9')
- unit = -1;
- } while (unit != -1 && *++num);
-
- if (unit < 0) {
- printf("%s: not a unit number\n",
- &name[strlen(gc->gc_name)]);
- } else if (unit >= gc->gc_driver->cd_ndevs ||
- gc->gc_driver->cd_devs[unit] == NULL) {
- printf("%d: no such unit\n", unit);
+#if defined(NFSCLIENT)
} else {
- printf("root on %s%d%c\n", gc->gc_name, unit,
- 'a' + part);
- rootdev = makedev(gc->gc_major,
- unit * MAXPARTITIONS + part);
- goto doswap;
+ ifp = ifunit(name);
+ if (ifp && (ifp->if_flags & IFF_BROADCAST)) {
+ extern char *nfsbootdevname;
+
+ mountroot = nfs_mountroot;
+ nfsbootdevname = ifp->if_xname;
+ return;
+ }
+#endif
}
- }
- printf("use one of: ");
- for (gc = genericconf; gc->gc_driver; gc++) {
- for (unit=0; unit < gc->gc_driver->cd_ndevs; unit++) {
- if (gc->gc_driver->cd_devs[unit])
- printf("%s%d[a-%c] ", gc->gc_name,
- unit, 'a'+MAXPARTITIONS-1);
+
+ printf("use one of: ");
+ for (gc = genericconf; gc->gc_driver; gc++) {
+ for (unit=0; unit < gc->gc_driver->cd_ndevs; unit++) {
+ if (gc->gc_driver->cd_devs[unit])
+ printf("%s%d[a-%c] ", gc->gc_name,
+ unit, 'a'+MAXPARTITIONS-1);
+ }
+ }
+#if defined(NFSCLIENT)
+ for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL;
+ ifp = TAILQ_NEXT(ifp, if_list)) {
+ if ((ifp->if_flags & IFF_BROADCAST))
+ printf("%s ", ifp->if_xname);
}
+#endif
+ printf("\n");
}
- printf("\n");
- goto retry;
}
-noask:
+
if (mountroot == NULL) {
/* `swap generic' */
setroot();
@@ -418,14 +483,9 @@ noask:
part = minor(rootdev) % MAXPARTITIONS;
unit = minor(rootdev) / MAXPARTITIONS;
printf("root on %s%d%c\n", findblkname(majdev), unit, part + 'a');
- return;
+ mountroot = dk_mountroot;
}
-
-doswap:
-#ifndef DISKLESS
- mountroot = dk_mountroot;
-#endif
- swdevt[0].sw_dev = argdev = dumpdev =
- makedev(major(rootdev), minor(rootdev) + 1);
- /* swap size and dumplo set during autoconfigure */
+ if (mountroot == dk_mountroot)
+ swdevt[0].sw_dev = argdev = dumpdev =
+ makedev(major(rootdev), minor(rootdev) + 1);
}