On 2/18/21 1:11 PM, Ilias Apalodimas wrote:
On Thu, Feb 18, 2021 at 12:15:30PM +0100, Heinrich Schuchardt wrote:
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.
That interpretation is a bit different from what I have. The separation between initrd files is denoted by the end of instance, not the end node with end of a device path (Sub-Type 0xFF).
I explicitly wrote sub-type *0x01*.
The EFI spec says "Each element in the array is variable length, and ends at the device path end structure" so I assume we can use either? I initially thought it meant Sub-Type = 0xFF.
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.
Not really. The whole point is that you'll have a single VenMedia indicating the start of the initrd device paths. Those are not separated by the end node (0xFF), but by the end of instance. Once you see an end node it's not an initrd filepath anymore. So you dont really need the number of elements in there.
Both in suggestions 1 and 2 individual initrd device paths are separated by end nodes of sub-type 0x01.
You make the assumption that nothing follows the last initrd path. But we may want to add additional device paths, e.g. for the device-tree.
This is why we should not assume that an end node of sub-type 0xFF follows the last initrd device-patch.
Best regards
Heinrich
In any case (1) is easier to code as well, since it practically allows you to append a DP, instead of search - append instance - copy the remaining DP, which will makje our lives easier.
Regards /Ilias
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