Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/evbarm fix root detection on evbarm when raid is in...



details:   https://anonhg.NetBSD.org/src/rev/7a396adf9d9c
branches:  trunk
changeset: 373370:7a396adf9d9c
user:      mrg <mrg%NetBSD.org@localhost>
date:      Sun Feb 05 22:42:39 2023 +0000

description:
fix root detection on evbarm when raid is involved

there are several problems solved in this change:
- lots of work was re-done when we already have determined the
  device booted from, so several new early returns introduced
  if booted_device has been set
- due to the lack of cpu_bootconf(), raidframe softroot would
  override "root=xxx" on the boot command line (note that
  platforms that use eg, device_register() to detect the boot
  device are not affected by this issue as they find the
  boot device much earlier.)
- in the new cpu_bootconf(), switch the order of the platform
  boot-config with the set_root_device() call.  this avoids a
  problem where "root=xxx" is checked after automated methods,
  and is thus ignored.
- in fdt_detect_root_device(), remove the code to add "root=xxx""
  string to the boot_args[] that would be later parsed by the
  set_root_device() call, and simply set booted_device and, for
  mbr installs, booted_partition directly.  also, for any
  successful call, perform an early return.
- define __HAVE_CPU_BOOTCONF so early boot calls cpu_bootconf().


tested on:
- rockpro64 booting from emmc, sata (big, and little endian)
- rockpro64 loading kernel from msdos partition
- rockpro64 booting from network (fails to auto-detect, with or
  without this change)
- quartz64 booting from nvme
- lx2k booting from nvme

XXX: pullup-10

diffstat:

 sys/arch/evbarm/evbarm/autoconf.c |  30 ++++++++++++-----
 sys/arch/evbarm/fdt/fdt_machdep.c |  64 +++++++++++++++++++++-----------------
 sys/arch/evbarm/include/types.h   |   4 +-
 3 files changed, 60 insertions(+), 38 deletions(-)

diffs (225 lines):

diff -r 3a99e8120322 -r 7a396adf9d9c sys/arch/evbarm/evbarm/autoconf.c
--- a/sys/arch/evbarm/evbarm/autoconf.c Sun Feb 05 21:20:14 2023 +0000
+++ b/sys/arch/evbarm/evbarm/autoconf.c Sun Feb 05 22:42:39 2023 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: autoconf.c,v 1.23 2020/12/19 21:54:00 mrg Exp $        */
+/*     $NetBSD: autoconf.c,v 1.24 2023/02/05 22:42:39 mrg Exp $        */
 
 /*-
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.23 2020/12/19 21:54:00 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.24 2023/02/05 22:42:39 mrg Exp $");
 
 #include "opt_md.h"
 #include "opt_ddb.h"
@@ -108,6 +108,9 @@
        char *ptr, *end, *buf;
        size_t len;
 
+       if (booted_device)
+               return;
+
        if (boot_args == NULL)
                return;
 
@@ -118,7 +121,7 @@
                return;
 
        /* NUL-terminate string, get_bootconf_option doesn't */
-       for (end=ptr; *end != '\0'; ++end) {
+       for (end = ptr; *end != '\0'; ++end) {
                if (*end == ' ' || *end == '\t') {
                        break;
                }
@@ -144,16 +147,25 @@
 #endif
 
 /*
- * Set up the root device from the boot args
+ * Set up the root device from the boot args.
+ *
+ * cpu_bootconf() is called before RAIDframe root detection,
+ * and cpu_rootconf() is called after.
  */
 void
+cpu_bootconf(void)
+{
+#ifndef MEMORY_DISK_IS_ROOT
+       set_root_device();
+       if (evbarm_cpu_rootconf)
+               (*evbarm_cpu_rootconf)();
+#endif
+}
+
+void
 cpu_rootconf(void)
 {
-#ifndef MEMORY_DISK_IS_ROOT
-       if (evbarm_cpu_rootconf)
-               (*evbarm_cpu_rootconf)();
-       set_root_device();
-#endif
+       cpu_bootconf();
        aprint_normal("boot device: %s\n",
            booted_device != NULL ? device_xname(booted_device) : "<unknown>");
        rootconf();
diff -r 3a99e8120322 -r 7a396adf9d9c sys/arch/evbarm/fdt/fdt_machdep.c
--- a/sys/arch/evbarm/fdt/fdt_machdep.c Sun Feb 05 21:20:14 2023 +0000
+++ b/sys/arch/evbarm/fdt/fdt_machdep.c Sun Feb 05 22:42:39 2023 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: fdt_machdep.c,v 1.99 2022/11/04 10:51:17 jmcneill Exp $ */
+/* $NetBSD: fdt_machdep.c,v 1.100 2023/02/05 22:42:39 mrg Exp $ */
 
 /*-
  * Copyright (c) 2015-2017 Jared McNeill <jmcneill%invisible.ca@localhost>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fdt_machdep.c,v 1.99 2022/11/04 10:51:17 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fdt_machdep.c,v 1.100 2023/02/05 22:42:39 mrg Exp $");
 
 #include "opt_arm_debug.h"
 #include "opt_bootconfig.h"
@@ -741,16 +741,10 @@
 static void
 fdt_detect_root_device(device_t dev)
 {
-       struct mbr_sector mbr;
-       uint8_t buf[DEV_BSIZE];
-       uint8_t hash[16];
-       const uint8_t *rhash;
-       char rootarg[64];
-       struct vnode *vp;
-       MD5_CTX md5ctx;
        int error, len;
-       size_t resid;
-       u_int part;
+
+       if (booted_device)
+               return;
 
        const int chosen = OF_finddevice("/chosen");
        if (chosen < 0)
@@ -758,6 +752,14 @@
 
        if (of_hasprop(chosen, "netbsd,mbr") &&
            of_hasprop(chosen, "netbsd,partition")) {
+               struct mbr_sector mbr;
+               uint8_t buf[DEV_BSIZE];
+               uint8_t hash[16];
+               const uint8_t *rhash;
+               struct vnode *vp;
+               MD5_CTX md5ctx;
+               size_t resid;
+               u_int part;
 
                /*
                 * The bootloader has passed in a partition index and MD5 hash
@@ -787,22 +789,22 @@
                MD5Update(&md5ctx, (void *)&mbr, sizeof(mbr));
                MD5Final(hash, &md5ctx);
 
-               if (memcmp(rhash, hash, 16) != 0)
-                       return;
+               if (memcmp(rhash, hash, 16) == 0) {
+                       booted_device = dev;
+                       booted_partition = part;
+               }
 
-               snprintf(rootarg, sizeof(rootarg), " root=%s%c", device_xname(dev), part + 'a');
-               strcat(boot_args, rootarg);
+               return;
        }
 
        if (of_hasprop(chosen, "netbsd,gpt-guid")) {
-               char guidbuf[UUID_STR_LEN];
-               const struct uuid *guid = fdtbus_get_prop(chosen, "netbsd,gpt-guid", &len);
-               if (guid == NULL || len != 16)
-                       return;
+               const struct uuid *guid =
+                   fdtbus_get_prop(chosen, "netbsd,gpt-guid", &len);
 
-               uuid_snprintf(guidbuf, sizeof(guidbuf), guid);
-               snprintf(rootarg, sizeof(rootarg), " root=wedge:%s", guidbuf);
-               strcat(boot_args, rootarg);
+               if (guid != NULL && len == 16)
+                       booted_device = dev;
+
+               return;
        }
 
        if (of_hasprop(chosen, "netbsd,gpt-label")) {
@@ -813,14 +815,19 @@
                device_t dv = dkwedge_find_by_wname(label);
                if (dv != NULL)
                        booted_device = dv;
+
+               return;
        }
 
        if (of_hasprop(chosen, "netbsd,booted-mac-address")) {
-               const uint8_t *macaddr = fdtbus_get_prop(chosen, "netbsd,booted-mac-address", &len);
+               const uint8_t *macaddr =
+                   fdtbus_get_prop(chosen, "netbsd,booted-mac-address", &len);
+               struct ifnet *ifp;
+
                if (macaddr == NULL || len != 6)
                        return;
+
                int s = pserialize_read_enter();
-               struct ifnet *ifp;
                IFNET_READER_FOREACH(ifp) {
                        if (memcmp(macaddr, CLLADDR(ifp->if_sadl), len) == 0) {
                                device_t dv = device_find_by_xname(ifp->if_xname);
@@ -830,6 +837,8 @@
                        }
                }
                pserialize_read_exit(s);
+
+               return;
        }
 }
 
@@ -878,7 +887,6 @@
 {
        device_t dev;
        deviter_t di;
-       char *ptr;
 
        if (booted_device != NULL)
                return;
@@ -887,11 +895,11 @@
                if (device_class(dev) != DV_DISK)
                        continue;
 
-               if (get_bootconf_option(boot_args, "root", BOOTOPT_TYPE_STRING, &ptr) != 0)
-                       break;
-
                if (device_is_a(dev, "ld") || device_is_a(dev, "sd") || device_is_a(dev, "wd"))
                        fdt_detect_root_device(dev);
+
+               if (booted_device != NULL)
+                       break;
        }
        deviter_release(&di);
 }
diff -r 3a99e8120322 -r 7a396adf9d9c sys/arch/evbarm/include/types.h
--- a/sys/arch/evbarm/include/types.h   Sun Feb 05 21:20:14 2023 +0000
+++ b/sys/arch/evbarm/include/types.h   Sun Feb 05 22:42:39 2023 +0000
@@ -1,8 +1,10 @@
-/*     $NetBSD: types.h,v 1.15 2021/04/01 04:35:45 simonb Exp $        */
+/*     $NetBSD: types.h,v 1.16 2023/02/05 22:42:39 mrg Exp $   */
 
 #ifndef _EVBARM_TYPES_H_
 #define        _EVBARM_TYPES_H_
 
+#define        __HAVE_CPU_BOOTCONF
+
 #ifdef __aarch64__
 #include <aarch64/types.h>
 



Home | Main Index | Thread Index | Old Index