Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/alpha/alpha If we're netbooting on a system with, f...
details: https://anonhg.NetBSD.org/src/rev/c768eabe99e4
branches: trunk
changeset: 984462:c768eabe99e4
user: thorpej <thorpej%NetBSD.org@localhost>
date: Fri Jul 09 01:29:20 2021 +0000
description:
If we're netbooting on a system with, for example, an ISA DE204 Ethernet
interface, we don't have sufficient information to find the device using
the bus/slot scheme that we do with a PCI network interface. However, in
these cases, some versions of the SRM console supply the MAC address of
the interface in the booted_dev environment variable, like so:
BOOTP 1 1 0 0 0 5 0 08-00-2B-xx-xx-xx 1
So, if we weren't able to find the booted device by the usual means,
check for this and, if we find a MAC address, try to find the network
interface by the MAC address.
diffstat:
sys/arch/alpha/alpha/autoconf.c | 118 ++++++++++++++++++++++++++++++++++++---
1 files changed, 107 insertions(+), 11 deletions(-)
diffs (173 lines):
diff -r 9a871205022e -r c768eabe99e4 sys/arch/alpha/alpha/autoconf.c
--- a/sys/arch/alpha/alpha/autoconf.c Thu Jul 08 20:11:15 2021 +0000
+++ b/sys/arch/alpha/alpha/autoconf.c Fri Jul 09 01:29:20 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: autoconf.c,v 1.57 2021/05/22 15:05:36 thorpej Exp $ */
+/* $NetBSD: autoconf.c,v 1.58 2021/07/09 01:29:20 thorpej Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -42,7 +42,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
-__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.57 2021/05/22 15:05:36 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.58 2021/07/09 01:29:20 thorpej Exp $");
#include "pci.h"
@@ -57,6 +57,9 @@
#include <dev/pci/pcivar.h>
+#include <net/if.h>
+#include <net/if_ether.h>
+
#include <machine/autoconf.h>
#include <machine/alpha.h>
#include <machine/cpu.h>
@@ -66,8 +69,7 @@
struct bootdev_data *bootdev_data;
-void parse_prom_bootdev(void);
-static inline int atoi(const char *);
+static void parse_prom_bootdev(void);
/*
* cpu_configure:
@@ -138,6 +140,86 @@
booted_device = device_find_by_xname(cp);
}
+static bool
+parse_dec_macaddr(const char *str, uint8_t enaddr[ETHER_ADDR_LEN])
+{
+ char *cp;
+ long long l;
+ int i;
+
+ /*
+ * DEC Ethernet address strings are formatted like so:
+ *
+ * XX-XX-XX-XX-XX-XX
+ */
+
+ for (i = 0; i < ETHER_ADDR_LEN; i++) {
+ l = strtoll(str, &cp, 16);
+ if (l < 0 || l > 0xff) {
+ /* Not a valid MAC address. */
+ return false;
+ }
+ if (*cp == '-') {
+ /* Octet separator. */
+ enaddr[i] = (uint8_t)l;
+ str = cp + 1;
+ continue;
+ }
+ if (*cp == ' ' || *cp == '\0') {
+ /* End of the string. */
+ enaddr[i] = (uint8_t)l;
+ return i == ETHER_ADDR_LEN - 1;
+ }
+ /* Bogus character. */
+ break;
+ }
+
+ /* Encountered bogus character or didn't reach end of string. */
+ return false;
+}
+
+static void
+netboot_find_rootdev_planb(void)
+{
+ struct psref psref;
+ uint8_t enaddr[ETHER_ADDR_LEN];
+ char ifname[IFNAMSIZ];
+ int i;
+
+ if (strncasecmp(bootinfo.booted_dev, "BOOTP ", 6) != 0 &&
+ strncasecmp(bootinfo.booted_dev, "MOP ", 4) != 0) {
+ /* We weren't netbooted. */
+ return;
+ }
+
+ for (i = 2; bootinfo.booted_dev[i] != '\0'; i++) {
+ if (bootinfo.booted_dev[i] == '-') {
+ if (parse_dec_macaddr(&bootinfo.booted_dev[i - 2],
+ enaddr)) {
+ /* Found it! */
+ break;
+ }
+ }
+ }
+ if (bootinfo.booted_dev[i] == '\0') {
+ /* No MAC address in string. */
+ return;
+ }
+
+ /* Now try to look up the interface by the link address. */
+ struct ifnet *ifp = if_get_bylla(enaddr, ETHER_ADDR_LEN, &psref);
+ if (ifp == NULL) {
+ /* No interface attached with that MAC address. */
+ return;
+ }
+
+ strlcpy(ifname, if_name(ifp), sizeof(ifname));
+ if_put(ifp, &psref);
+
+ /* Ok! Now look up the device_t by name! */
+ booted_device = device_find_by_xname(ifname);
+}
+
void
cpu_rootconf(void)
{
@@ -147,13 +229,33 @@
}
if (booted_device == NULL) {
+ /*
+ * It's possible that we netbooted from an Ethernet
+ * interface that can't be matched via the usual
+ * logic in device_register() (a DE204 in an ISA slot,
+ * for example). In these cases, the console may have
+ * provided us with a MAC address that we can use to
+ * try and find the interface, * e.g.:
+ *
+ * BOOTP 1 1 0 0 0 5 0 08-00-2B-xx-xx-xx 1
+ */
+ netboot_find_rootdev_planb();
+ }
+
+ if (booted_device == NULL) {
printf("WARNING: can't figure what device matches \"%s\"\n",
bootinfo.booted_dev);
}
rootconf();
}
-void
+static inline int
+atoi(const char *s)
+{
+ return (int)strtoll(s, NULL, 10);
+}
+
+static void
parse_prom_bootdev(void)
{
static char hacked_boot_dev[128];
@@ -213,12 +315,6 @@
bootdev_data = &bd;
}
-static inline int
-atoi(const char *s)
-{
- return (int)strtoll(s, NULL, 10);
-}
-
void
device_register(device_t dev, void *aux)
{
Home |
Main Index |
Thread Index |
Old Index