On 18.02.21 10:04, Ilias Apalodimas wrote:
Hi,
An arch agnostic way was recently added on the kernel, as an alternative method to load an initrd [1]. The kernel call to the firmware ends up calling the protocol with a Device Path End Structure, so the firmware must know which initrd to load on the buffer the kernel provides.
The protocol is currently implemented by U-boot and EDK2, which both define a way of specifying the initrd to load. We could use this protocol, in order to provide vertical distros a way of loading (kernel, initrd) pairs without GRUB. In that case we need a common way for firmware implementations to define and manage the initrd. User space applications that control the boot flow (e.g efibootmgr), should also be able to change the variable accordingly.
Looking at the EFI spec and specifically ยง 3.1.3 Load Options, we can use the FilePathList[] of the EFI_LOAD_OPTION, which is described as:
"A packed array of UEFI device paths. The first element of the array is a device path that describes the device and location of the Image for this load option. The FilePathList[0] is specific to the device type. Other device paths may optionally exist in the FilePathList, but their usage is OSV specific. Each element in the array is variable length, and ends at the device path end structure. Because the size of Description is arbitrary, this data structure is not guaranteed to be aligned on a natural boundary. This data structure may have to be copied to an aligned natural boundary before it is used."
So FilePatrhList[1-n] are available for OS usage. There are 3 ways we could implement that. All 3 ways would allow us to specify multiple initrds (and we could extend the same logic to DTBs, but that's a different discussion). They all re-use the same idea, prepend a VenMedia DP, which has a GUID. We can then use that GUID to identify the filetype and behavior of the device paths.
- Prepend a VenMedia Device Path in every initrd Device Path. In that case
FilePathList[] would look like this:
Loaded Image device path - end node - VenMedia - Initrd DP - end node
- VenMedia - Initrd DP - end node - repeat
- Prepend a VenMedia Device Path once. In that case FilePathList[] would look
like this:
Loaded Image device path - end node - VenMedia - Initrd DP - end instance - (repeat) - Initrd DP - end node - other DPs
In this case we could use the VenMedia Vendor Defined Data to indicate the number of device paths that follow, although it's redundant, since each instance would terminate on the Device Path End Structure.
- Use Vendor Defined Data of the VenMedia device path and copy the initrd
device path(s) in there. In that case the Vendor Defined Data will it self be in a device path format with all the initrds we want.
Loaded Image device path - end node - VenMedia - end node - other DPs
When passing the device path of the boot option to the EDK2 implementation of EFI_DEVICE_PATH_TO_TEXT_PROTOCOL.ConvertDevicePathToText(), it will print out all array elements as comma separated list like
HD(1,GPT,..,0x2000,0x200000)/File(\EFI\debian\shimaa64.efi),/VenMedia(00000001-0000-0000-0000-000000000000)/HD(2,GPT,..,0x2000,0x200000)/File(\initrd1),/VenMedia(00000001-0000-0000-0000-000000000000)/HD(2,GPT,..,0x2000,0x200000)/File(\initrd2)
The device path end nodes of sub-type 0x01 are rendered as commas.
With 1 and 2 this would show a readable output like above. With 3 you will just see a hex-string.
This excludes 3 for me.
If 2 does not add the number of initrds, it cannot be determined if a following array element starting with a VenMedia() node is an initrd or has a completely different meaning.
With 1 you can individually determine for each element its meaning by looking at the first node.
Therefore I prefer 1.
Best regards
Heinrich
Any preference on these? Is one of them closer to the EFI spec, so we could go ahead and try to standardize some of the GUIDs of the VenMedia?
[1] https://lkml.org/lkml/2020/2/16/105
Regards /Ilias