[Just adding notes about what ubldr.bin does with and without loaderdev being specified (correctly). Overall it does not appear to me that the ubldr.bin based contexts can fully avoid the "systems with multiple partitions that might be right" issue.] On 2017-Dec-20, at 2:47 AM, Mark Millard <markmi at dsl-only.net> wrote: > On 2017-Dec-19, at 9:10 PM, Warner Losh <imp at bsdimp.com> wrote: > >> On Tue, Dec 19, 2017 at 9:06 PM, Mark Millard <markmi at dsl-only.net> wrote: >> [The usdcard in my rpi2 example does not contain any kernel files, >> nor any dtb files. Only the USB SSD stick does. The kernel and dtb >> do not come from the usdcard. This is what I'm not sure if it is >> generally supported or not.] >> >> On 2017-Dec-19, at 7:26 PM, Warner Losh <imp at bsdimp.com> wrote: >> >>> On Dec 19, 2017 4:26 PM, "Mark Millard" <markmi at dsl-only.net> wrote: >>>> >>>>> . . . >>>>> It sounds different then the results I get with ubldr.bin >>>>> on a rpi2 V1.1 . With the usdcard having a UFS / with >>>>> basically only: >>>>> >>>>> /etc/fstab (redirecting to a USB SSD stick) >>>>> /boot/* (with /boot/kernel/ empty and /boot/dtb/ empty) >>>>> >>>>> the result is that all 3 of the following come from the >>>>> USB SSD stick based on the "/" line from the /etc/fstab >>>>> from the usdcard: >>>>> >>>>> /boot/kernel >>>>> /boot/dtb/bcm2836-rpi-2-b.dtb >>>>> / (mounted root file system) >>>>> >>>>> In other words: it appears that for ubldr.bin on >>>>> a rpi2 V1.1 /etc/fstab is read and used before >>>>> finding the kernel that is to be loaded. (It or >>>>> another /etc/fstab may be read again later.) >>>>> >>>>> It is read. It is literally only used to set the root for userland. That is all. Nothing else. >>>>> >>>>> /usr/src/stand/common/boot.c does show an explicit >>>>> attempt to find a /etc/fstab: >>>>> >>>>> # grep -r /etc/fstab /usr/src/stand/ >>>>> . . . >>>>> /usr/src/stand/common/boot.c: * Try to find the /etc/fstab file on the filesystem (rootdev), >>>>> /usr/src/stand/common/boot.c: sprintf(lbuf, "%s/etc/fstab", rootdev); >>>>> . . . >>>>> >>>>> That is from getrootmount(char *rootdev): >>>>> >>>>> int >>>>> getrootmount(char *rootdev) >>>>> { >>>>> char lbuf[128], *cp, *ep, *dev, *fstyp, *options; >>>>> int fd, error; >>>>> >>>>> if (getenv("vfs.root.mountfrom") != NULL) >>>>> return(0); >>>>> >>>>> So if you set vfs.root.mountfrom in /boot/loader.conf, we don't read rootdev:/etc/fstab for the value to set vfs.root.mountfrom to. >>>>> >>>>> error = 1; >>>>> sprintf(lbuf, "%s/etc/fstab", rootdev); >>>>> if ((fd = open(lbuf, O_RDONLY)) < 0) >>>>> goto notfound; >>>>> . . . >>>>> >>>>> Supporting detail for the example rpi2 >>>>> boot context: >>>>> >>>>> With /mnt being the / from the usdcard: >>>>> >>>>> # find /mnt -print | more >>>>> /mnt >>>>> /mnt/.snap >>>>> /mnt/boot >>>>> /mnt/boot/defaults >>>>> /mnt/boot/defaults/loader.conf >>>>> /mnt/boot/dtb >>>>> /mnt/boot/firmware >>>>> /mnt/boot/kernel >>>>> /mnt/boot/modules >>>>> /mnt/boot/zfs >>>>> /mnt/boot/msdos >>>>> /mnt/boot/entropy >>>>> /mnt/boot/menu.rc.sample >>>>> /mnt/boot/ubldr >>>>> /mnt/boot/ubldr.bin >>>>> /mnt/boot/brand-fbsd.4th >>>>> /mnt/boot/logo-beastie.4th >>>>> /mnt/boot/logo-beastiebw.4th >>>>> /mnt/boot/logo-fbsdbw.4th >>>>> /mnt/boot/logo-orb.4th >>>>> /mnt/boot/logo-orbbw.4th >>>>> /mnt/boot/loader.conf >>>>> /mnt/boot/loader.efi >>>>> /mnt/boot/boot1.efi >>>>> /mnt/boot/boot1.efifat >>>>> /mnt/boot/beastie.4th >>>>> /mnt/boot/brand.4th >>>>> /mnt/boot/color.4th >>>>> /mnt/boot/check-password.4th >>>>> /mnt/boot/delay.4th >>>>> /mnt/boot/frames.4th >>>>> /mnt/boot/loader.4th >>>>> /mnt/boot/loader.help >>>>> /mnt/boot/menu.4th >>>>> /mnt/boot/menu-commands.4th >>>>> /mnt/boot/menusets.4th >>>>> /mnt/boot/screen.4th >>>>> /mnt/boot/shortcuts.4th >>>>> /mnt/boot/support.4th >>>>> /mnt/boot/version.4th >>>>> /mnt/boot/loader.rc >>>>> /mnt/boot/efi.4th >>>>> /mnt/boot/pcibios.4th >>>>> /mnt/boot/menu.rc >>>>> /mnt/etc >>>>> /mnt/etc/fstab >>>>> /mnt/COPYRIGHT >>>>> /mnt/lost+found >>>>> >>>>> # more /mnt/etc/fstab >>>>> /dev/da0p1 / ufs rw,noatime 1 1 >>>>> /dev/da0p2 none swap sw 0 0 >>>>> >>>>> May be this is somehow special to the rpi2 or to >>>>> ubldr.bin operation. (I've never managed to identify >>>>> accidents from deliberately working status in this >>>>> area.) >>>>> >>>> So you load /boot/loader and the kernel from the sdcard. >>> >>> No: There are no kernel files on the usdcard. See the complete >>> file list of its only UFS partition above. No dtb files either. >>> >>> [On a rpi2 ubldr.bin is copied to the msdosfs, where it >>> is actually put to use.] >> >> OK. Looks like the uboot code has the same bogus 'let's search everything' code that I'm removing from the UEFI case. > > Could be. My case was so limited that it does not show if > the search would continue if multiple USB drives were > present vs. stopping at the first even if the files would > not be found there (for example). > >> Still doesn't get anything from /etc/fstab. It can't. There's no translation code in the boot loader to try to guess. It just does a bruit force plow through all the devices and hopes for the best. > > Just FYI, the /usr/src/stand/common/boot.c comments say about > the /etc/fstab use: > > * Try to find the /etc/fstab file on the filesystem (rootdev), > * which should be be the root filesystem, and parse it to find > * out what the kernel ought to think the root filesystem is. > * > * If we're successful, set vfs.root.mountfrom to <vfstype>:<path> > * so that the kernel can tell both which VFS and which node to use > * to mount the device. If this variable's already set, don't > * overwrite it. > . . . > /* Build the <fstype>:<device> and save it in vfs.root.mountfrom */ > > This would fit with your description: finding any > kernel, as you have described, and then feeding it > the <fstype>:<device> text to find other things. > > [I have not yet identified the code that goes looking > around for the first /boot/kernel/kernel that it > can find that appears to be some form of kernel.] > >>>> /etc/fstab on the card points to the usb drive for /. >>> >>> True. And that is were the kernel and dtb come from, >>> not the usdcard. >> >> Right, but that's not how ubldr finds them. > > If the kernel loads the dtb file, it might use the > <fstype>:<device> that it was given to find > /boot/dtb/ to look up the dtb file? > > (That would still leave an arbitrary kernel being > loaded first if more than one is around.) > >>> For reference loader.config has: >>> >>> # more /mnt/boot/loader.conf >>> geom_label_load="YES" # File system labels (see glabel(8)) >>> # >>> kern.cam.boot_delay="10000" >>> vfs.mountroot.timeout="10" >>> dumpdev="/dev/da0p2" >>> >>> (So no vfs.root.mountfrom .) >> >> What does config.txt have? > > The rpi2 CONFIG.TXT on the msdosfs has: > > # more /media/CONFIG.TXT > init_uart_clock=3000000 > enable_uart=1 > kernel=u-boot.bin > kernel7=u-boot.bin > > (Unchanged by me: simply copied over from > the sysutils materials for the rpi2.) > >>>> This is all standard loader behavior. >>> >>> I'm not sure avoiding the kernel and dtb being on the usdcard >>> is standard-supported behavior. It might be a lucky, >>> limited-context accident rather than a general property as a >>> technique. > > Looks like not-desired in its current form. > >>>> It won't change. In your case, you aren't even using UEFI, so it doubly won't change. >>> >>> I also have access to an rpi3 and a pine64+ 2GB, which are >>> UEFI based. But I'd not yet tried a similar configuration >>> to what I'd recently done on the rpi2 V1.1 . >>> >>> The list notices made me unsure if I should even try. It >>> is this part that I'm trying to figure out, both for now >>> and for after the changes. >> >> You should try, but you may need one additional line to explicitly declare things. >> >>>> UEFI has more direct ways of doing this, but this setup would work there because it is explicit. It doesn't depend on the current boot1.efi behavior... >>> >>> The lack of depending on the "random order" status may well >>> be true. >>> >>> But I'm still not sure if the the lack of a kernel and dtb >>> file on the usdcard puts the technique out of bounds for >>> the rpi2 and pine64+ 2GB. > > [That last rpi2 should have been a rpi3.] > >> I think this is more of the same bogus random order behavior that's making your stuff word accidentally. Since ubldr is being phased out, I have no plans to change it. > >> But as someone that deploys systems with multiple partitions that might be right, I hate random :( > > Understandable. > >> Warner > > Thanks much. I understand a bit more now. > >>> Warner >>>> >>>>>> (For my particular interest the context uses UFS, not >>>>>> ZFS.) >>>>>> >>>>>>> What is being deleted is one final step: "otherwise use the first UFS partition on any drive in a random order that's usable." which used to be at the end of the boot1.efi psuedo code. It's my belief that no such installations actually use this due to the random factor today (plug in a new USB drive and it might take over). If my belief is wrong, it's my belief that efibootmgr will solve it, and failing that, the fallback mechanism (for platforms that use u-boot + EFI where UEFI variables don't work) will allow the two or three people that are doing this today. >>>>>> >>>>> >>> Looking at the ubldr.bin code it appears that the only way to avoid the ubldr.bin "find first in some order" is to have set loaderdev to indicate where to get the loader scripts and kernel from. Otherwise it will do the general probing, for example: . . . FreeBSD/armv7 U-Boot loader, Revision 1.2 DRAM: 948MB Number of U-Boot devices: 3 U-Boot env: loaderdev not set, will probe all devices. Found U-Boot device: disk Probing all disk devices... Checking unit=0 slice=<auto> partition=<auto>... good. Booting from disk0p1: . . . Matches up with: . . . device_types[] = { { "disk", DEV_TYP_STOR }, { "ide", DEV_TYP_STOR | DT_STOR_IDE }, { "mmc", DEV_TYP_STOR | DT_STOR_MMC }, { "sata", DEV_TYP_STOR | DT_STOR_SATA }, { "scsi", DEV_TYP_STOR | DT_STOR_SCSI }, { "usb", DEV_TYP_STOR | DT_STOR_USB }, { "net", DEV_TYP_NET } }; . . . /* * Parse a device string into type, unit, slice and partition numbers. A * returned value of -1 for type indicates a search should be done for the * first loadable device, otherwise a returned value of -1 for unit * indicates a search should be done for the first loadable device of the * given type. * * The returned values for slice and partition are interpreted by * disk_open(). * * Valid device strings: For device types: * * <type_name> DEV_TYP_STOR, DEV_TYP_NET * <type_name><unit> DEV_TYP_STOR, DEV_TYP_NET * <type_name><unit>: DEV_TYP_STOR, DEV_TYP_NET * <type_name><unit>:<slice> DEV_TYP_STOR * <type_name><unit>:<slice>. DEV_TYP_STOR * <type_name><unit>:<slice>.<partition> DEV_TYP_STOR * * For valid type names, see the device_types array, above. * * Slice numbers are 1-based. 0 is a wildcard. */ static void get_load_device(int *type, int *unit, int *slice, int *partition) { char *devstr; const char *p; char *endp; *type = -1; *unit = -1; *slice = 0; *partition = -1; devstr = ub_env_get("loaderdev"); if (devstr == NULL) { printf("U-Boot env: loaderdev not set, will probe all devices.\n"); return; } printf("U-Boot env: loaderdev='%s'\n", devstr); . . . It appears that loaderdev's notation depends on the <type_name><unit>: having a stable interpretation if it is to avoid picking different things based on what combination of other devices happen to be plugged in at the time. Stablility require binding, say, a unit 0 to a specific place even when the place was not populated. (Unlikely?) This suggests that <type_name><unit> notation is specific to each device type. But I'm not aware of a place to go look up a device type and get a definition for how <type_name><unit> will be bound to plugged in devices. It is not clear to me what happens with <slice> in the notation when the <type_name><unit>: identifies something with just, say, gpt partitioning. (No slice layer.) Listing 0 (the slice wildcard) could match a device with some non-gpt structure. An explicit, say, 1 could as well but would also have no slice to refer to for gpt partitioning. Overall it does not appear to me that the ubldr.bin based contexts can fully avoid the "systems with multiple partitions that might be right" issue when what is connected can change from boot to boot: There just is not the right kind of context for avoiding the issue. Still an explicit loaderdev use in some styles of usage could make mismatches less likely. === Mark Millard markmi at dsl-only.netReceived on Sat Dec 23 2017 - 21:49:15 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:41:14 UTC