Module Name: src Committed By: mrg Date: Sun Feb 5 22:42:39 UTC 2023
Modified Files: src/sys/arch/evbarm/evbarm: autoconf.c src/sys/arch/evbarm/fdt: fdt_machdep.c src/sys/arch/evbarm/include: types.h Log Message: 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 To generate a diff of this commit: cvs rdiff -u -r1.23 -r1.24 src/sys/arch/evbarm/evbarm/autoconf.c cvs rdiff -u -r1.99 -r1.100 src/sys/arch/evbarm/fdt/fdt_machdep.c cvs rdiff -u -r1.15 -r1.16 src/sys/arch/evbarm/include/types.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/evbarm/evbarm/autoconf.c diff -u src/sys/arch/evbarm/evbarm/autoconf.c:1.23 src/sys/arch/evbarm/evbarm/autoconf.c:1.24 --- src/sys/arch/evbarm/evbarm/autoconf.c:1.23 Sat Dec 19 21:54:00 2020 +++ src/sys/arch/evbarm/evbarm/autoconf.c Sun Feb 5 22:42:39 2023 @@ -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 @@ set_root_device(void) char *ptr, *end, *buf; size_t len; + if (booted_device) + return; + if (boot_args == NULL) return; @@ -118,7 +121,7 @@ set_root_device(void) 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 @@ set_root_device(void) #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_rootconf(void) +cpu_bootconf(void) { #ifndef MEMORY_DISK_IS_ROOT + set_root_device(); if (evbarm_cpu_rootconf) (*evbarm_cpu_rootconf)(); - set_root_device(); #endif +} + +void +cpu_rootconf(void) +{ + cpu_bootconf(); aprint_normal("boot device: %s\n", booted_device != NULL ? device_xname(booted_device) : "<unknown>"); rootconf(); Index: src/sys/arch/evbarm/fdt/fdt_machdep.c diff -u src/sys/arch/evbarm/fdt/fdt_machdep.c:1.99 src/sys/arch/evbarm/fdt/fdt_machdep.c:1.100 --- src/sys/arch/evbarm/fdt/fdt_machdep.c:1.99 Fri Nov 4 10:51:17 2022 +++ src/sys/arch/evbarm/fdt/fdt_machdep.c Sun Feb 5 22:42:39 2023 @@ -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 <jmcne...@invisible.ca> @@ -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 @@ delay(u_int us) 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 @@ fdt_detect_root_device(device_t dev) 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 @@ fdt_detect_root_device(device_t dev) 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); + + if (guid != NULL && len == 16) + booted_device = dev; - uuid_snprintf(guidbuf, sizeof(guidbuf), guid); - snprintf(rootarg, sizeof(rootarg), " root=wedge:%s", guidbuf); - strcat(boot_args, rootarg); + return; } if (of_hasprop(chosen, "netbsd,gpt-label")) { @@ -813,14 +815,19 @@ fdt_detect_root_device(device_t dev) 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 @@ fdt_detect_root_device(device_t dev) } } pserialize_read_exit(s); + + return; } } @@ -878,7 +887,6 @@ fdt_cpu_rootconf(void) { device_t dev; deviter_t di; - char *ptr; if (booted_device != NULL) return; @@ -887,11 +895,11 @@ fdt_cpu_rootconf(void) 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); } Index: src/sys/arch/evbarm/include/types.h diff -u src/sys/arch/evbarm/include/types.h:1.15 src/sys/arch/evbarm/include/types.h:1.16 --- src/sys/arch/evbarm/include/types.h:1.15 Thu Apr 1 04:35:45 2021 +++ src/sys/arch/evbarm/include/types.h Sun Feb 5 22:42:39 2023 @@ -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>