firmware
firmware copied to clipboard
Unable to determine boot device on Pi 4B
With Pi 4B, one can specify multiple boot devices using BOOT_ORDER. Currently there seems to be no way to determine which boot device was actually used by the boot loader to load the 2nd stage FW and kernel from. vcgencmd can pull all sorts of boot/config information from the FW so it seems natural that it can provide that information as well?
Forum discussion: https://www.raspberrypi.org/forums/viewtopic.php?f=63&t=319240
This information is readily accessible within the firmware but not yet made available to OSs. It could easily be added to the Device Tree under /chosen or made available using a new mailbox message - do you have a preference?
Having discussed this internally there will be a new mailbox message - GET_BOOT_MODE (0x3005b) - that takes no parameters and returns two words:
- the boot order value (e.g. 1 for SD, 4 for MSD)
- a flag indicating if this was a signed boot
Is it possible to expose any more detailed information about the boot device? For example, if there are several bootable USB devices plugged in, can it identify the specific SD that was booted (by connection or UUID etc)? Or if there are several bootable partitions on a device, can it identify which partition was booted?
@juergh @procount Please can you describe the high-level use-case for needing to know the firmware / kernel boot devices vs the root filesystem? As @pelwell noted some information could be exposed but if software relies upon this it's important to understand the interface since the bootloader / firmware will change over time.
This issue has also been referenced in https://www.raspberrypi.org/forums/viewtopic.php?f=63&t=319841
It has been a while since I was looking at this, so I've probably forgotten some of the use cases, so apologies if I generalise a little too much. But mine obviously revolve around the multi-boot use cases of NOOBS/PINN (I shall just refer to PINN since NOOBS is now deprecated).
The typical use case of an OS is just to get it booted from the SD card, so by this time all the partition references have been determined during the installation and it just works. Until you start USB-booting. You can take your SD card, put it in a USB adapter and boot it from USB. Now it doesn't work, unless you have used partition label references, or UUIDs, or partuuids etc. Then someone decides to clone a device and have them both plugged in together. Now you don't have unique identifiers anymore, so whilst it may boot, which partition booted? Which device came up first? Even if the clones have different UUIDs, if they are both plugged in at startup, it is not a given which one will boot.
I suppose PINN is a bit different because it mostly deals with the installation and subsequent management of OSes on various devices, but it suffers similar issues. PINN needs to know the boot device so it can install OSes to the correct device and setup all the correct device and partition references. There is even code in NOOBS to try and identify the NOOBS drive (assuming it's the boot device) by searching for a specific file (recovery.rfs) on all block devices. This is ok until you plug in another PINN formatted device to install some OSes from it. Now it has to rely on the boot ordering to work out which one was possibly booted. But now that boot order is more flexible and recursive, so one can't infer which device was booted - it depends on device bring up order again.
In multiboot-scenarios, I can also imagine multiple boot partitions with different configurations that each boot the same rootfs.
Whilst there are some ways to try and identify the boot partition, it is often an inference and could be in error. Reporting the boot device type is certainly a start, but providing the actual device (device id,uuid or whatever) would be a great help.
In a multi-boot scenario like PINN where it is possible to boot to a specific partition, or the use of autoboot.txt, providing the partition number that was last booted would I'm sure also be very useful, although I can't think of a specific use case at present.
People should be using partition UUIDs or labels to identify file systems; upstream kernel devs have done everything short of randomising MMC/SD device numbers at boot to push users in that direction - mmcblk0 is only the SD card on most Pis because of a downstream patch that extracts device numbers from Device Tree. An installation where UUIDs are duplicated is invalid - we shouldn't be adding a mechanism simply to work around that error.
Yes I realise a lot of these are invalid or unpreferred - it's just what I have had to deal with. Not all OSes have the ability to use UUIDs (precluding them from USB boot), and the use of fixed labels prevents multiple installations of the same OS on the same device (e.g. Ubuntu). But given the plethora of devices that could have been booted, and the fact that the firmware knows which one was booted, it would be really nice to know which one was actually booted. In the case of PINN - If I have 2 devices formatted as PINN on USB devices, even with different UUIDs, how do I know which one booted? Which is the source and which is the target? There is no root partition as it is mapped to /dev/ram0. I have to map the boot partition using heuristics.
Sorry for the late reply, I somehow missed the notifications. My use case is that I have multiple (potentially) bootable devices attached. Each boot device has a simple 'OS installer' installed that can be invoked by pulling a GPIO. The installer's purpose is to reflash the current boot device so it needs to know where it was booted from.
Does that mean that you need information beyond the active BOOT_ORDER (such as USB device/partition)? It isn't clear from your description.
Ideally yes. But translating that additional info to a Linux device name might be tricky, no? So I'm thinking it might be easier to just append some unique data to cmdline.txt and then let the installer search for it on all block devices.
But if you are able to identify the USB device, it would be preferred over having to search all the block devices, IMHO. :wink:
The firmware and bootloader and OS agnostic so would not translate Linux device ids. They also don't use partition UUIDs. It's more like index (as passed to sudo reboot), route-string e.g. 0x41 (root hub1, hub port 4), and the LUN.
btw: In future, any 'read-only' firmware data is likely to be exported via device-tree under the /chosen node rather than vcgencmd or mailboxes. This avoids VC specific userland dependencies and should be easier for u-boot etc to parse.
Latest rpi-update firmware exposes the new information under /proc/device-tree/chosen/bootloader
With CURRENT: Tue 5 Oct 07:53:57 UTC 2021 (1633420437) I see the following files:
pi@zpi:~$ ls -l /proc/device-tree/chosen/bootloader/
total 0
-r--r--r-- 1 root root 4 Nov 15 17:46 build-timestamp
-r--r--r-- 1 root root 4 Nov 15 17:46 capabilities
-r--r--r-- 1 root root 11 Nov 15 17:46 name
-r--r--r-- 1 root root 4 Nov 15 17:46 update-timestamp
-r--r--r-- 1 root root 41 Nov 15 17:46 version
Am I missing something? Did I get the wrong directory?
Am I missing something? Did I get the wrong directory?
The commit was pushed to rpi-update on Tue Oct 19. So no, it won't be in firmware from two weeks earlier.
Thanks, it was late and I missed that :)
Hi, I have been unable to take any information regarding by boot device (eMMC vs USB on a CM3), so is it possible to confirm:
1 - boot mode is exposed under /proc/device-tree/chosen/bootloader/ 2 - boot mode is also exposed at mailbox GET_BOOT_MODE (0x3005b) 3 - this applies also to pre-RPI4 4 - This exposes the actual boot device and not the requested boot device. I.e., in a CM3, if the eMMC fails and a USB boot is caused, this will signal it.
- Yes.
- Yes.
- No.
- Yes (actual, not requested) and no (not on CM3).
- No.
- Yes (actual, not requested) and no (not on CM3).
So regarding older hardware, it's just abandoned or not possible? Or is there any way to poke what is the boot device?
As far as I know, this capability is implemented by exposing state from the Pi 4 bootloader EEPROM - all you will get for an older Pi is the partition number passed to "reboot
Is that about right, @timg236?
Yes, on Pi3 you only get the partition number. It should be possible to map the boot-mode but there's no easy way to get the USB topology. Therefore I think (3) is a medium priority TODO and (4) is not-going-to-fix on CM3
This feature is now covered in the official documentation for firmware generated device tree nodes (/chosen)
https://www.raspberrypi.com/documentation/computers/configuration.html#part4
Changes and docs merged a while ago so resolving as fixed.