I've created a comprehensive list of the Multiboot2 tags to help the community on this topic. Hopefully you'll find this information useful. As a result, I've found two tags that could be added to the Multiboot2 spec: Type 22, Boot log and Type 23, FMAP. That's all. Both could (and should) be defined as common (non-coreboot specific) tags.
TL;DR only the "coreboot to payload" information structure makes sense, and that should be passed as an argument to the payload's main() function. This won't hurt non-Multiboot2-aware payloads either which currently don't expect arguments.
I've identified one major problem with the Multiboot2 spec: it is for 32-bit only. However exactly the same information could be passed to a 64-bit payload without any problems, should we decide not to care about this part of the spec.
# Glossary of definitions in Multiboot2 spec
boot loader - in coreboot terms, the coreboot base OS image - in coreboot terms, the payload information request - a static data structure in the payload (makes no sense in coreboot, see below) boot information - a data structure constructed by coreboot and passed to the payload upon handover (to replace sysinfo_t and other tables)
From the Multiboot2 spec:
``` There are three main aspects of a boot loader/OS image interface:
1. The format of an OS image as seen by a boot loader. 2. The state of a machine when a boot loader starts an operating system. 3. The format of information passed by a boot loader to an operating system. ``` NOTE: this is all there is to Multiboot2. It is simple. I like simple.
Now since the payload (OS image) isn't loaded dynamically as per the Multiboot2 spec, rather statically linked into the coreboot's rom image, point 1 is meaningless, as in the file format as well as in the request structure's existence.
State of the machine is relevant, however with some sane defaults (still Multiboot2 compliant) based on how coreboot works.
Point 3 is what could be used to replace current coreboot tables.
Now let's check each tag one by one in detail. I've used the same order as in the Multiboot2 spec.
# Request tags, payload to coreboot
As a rule of thumb, makes not much sense since the payload isn't loaded dynamically, rather statically linked with coreboot into a single rom image. Therefore coreboot should be able to run a payload in lack of such data structure without problems. Also there's not much sense in parsing these in run-time, because coreboot can only offer services it was compiled for, and payload can't be (and shouldn't be) replaced dynamically either.
## Type 1, Multiboot2 information request
Useless in terms of coreboot if it's going to pass the data in Multiboot2 tags anyway.
## Type 2, address tag
Just like type 1, makes not much sense. Maybe the load address could be used to relocate the payload in run-time, but that would require additional development (maybe in the future, has to be 1M for now).
## Type 3, entry address
Just like type 2, since the payload is statically linked, the entry address of the payload is already known at compile time, no need for this tag.
## Type 8 and 9, EFI entry addresses
Makes no sense with coreboot at all.
## Type 4, flags
No matter what flags the payload passes, coreboot is using the features it was configured for in compile time, so it will discard all feature requests anyway.
## Type 5, framebuffer
Again, coreboot is using the framebuffer resolution it was configured for at compile time, doesn't matter what values this tag holds.
## Type 6, module alignment
Yet again, payload is statically linked into the rom image, therefore dynamically loadable modules make no sense with coreboot.
## Type 7, EFI boot services tag
No sense with coreboot, unless coreboot wishes to mimic EFI tables too. And again, coreboot is either compiled with EFI support or not, doesn't matter what the payload is asking for with this tag.
## Type 10, relocatable header
Not sure if it makes sense with current coreboot, but just like type 2, maybe could be implemented in the future for run-time relocating the payload (but that seems unnecessary bloat to me).
That's for all the tags passed from the payload to coreboot. As you can clearly see, none of them makes sense, therefore could be omitted entirely in coreboot payloads and there's absolutely no need to implement a parser in coreboot for these.
Let's see the other way, coreboot to payload tags.
# Information tags, coreboot to payload
Coreboot should create and pass these to all payloads the same way as sysinfo_t is currently passed, and regardless if payload has a Multiboot2 request structure or not. It won't hurt payloads that don't use Multiboot2, the same way as sysinfo_t is constructed for payloads that don't use that doesn't hurt them either. I think here state of the machine should be extended a bit. The Multiboot2 information address should not be passed in EBX register only, rather as an argument to the payload's main() function too IMHO. Technically this means RBX should have the same value as RSI (or top value on the stack or whatever register the payload ABI uses), and that's it. Wouldn't break Multiboot2 compliance, but would make payload writer's life much simpler.
## Type 4, Basic memory information
Since there's also a tag (type 6) memory map, pretty useless, but could be generated without probs.
## Type 5, BIOS Boot device
Makes absolutely no sense, payload isn't loaded from a device, rather from rom. But a sane value could be generated perhaps?
## Type 1, Boot command line
Not sure if this makes sense, but it's just a zero terminated string, could be generated no probs. Maybe could contain the coreboot configureation?
## Type 3, Modules and Type 9, Symbols
Again, payload isn't loaded dynamically, so no modules and no ELF symbol parser needed, but could be generated statically in compile time if one really wants them.
## Type 6, Memory map
Same as sysinfo.memrange, memory types might need a simple conversion, that's all.
## Type 2, Boot loader name
Simple zero terminated string, easy to provide. Might include coreboot version too.
## Type 10, type 7, type 13; APM, VBE and SMBIOS
I see no point in these in coreboot's context, but shouldn't be hard to generate these tags with some sane default values if needed.
## Type 8, framebuffer info
This tag should be generated if coreboot is configured with high resolution framebuffor support, and in that case contains the same values as sysinfo.framebuffer. If coreboot was configured without framebuffer, that this tag should be simply missing. NOTE: IMHO this should not depend on the request tag, this tag's existence should only depend on how coreboot was configured and compiled.
## Type 11, type 12, EFI system table
Makes no sense unless coreboot wishes to mimic EFI tables and functionality as well.
## Type 14, type 15, ACPI
Straightforward. NOTE: these tags contain of a **copy** of the RSDT/XSDT, therefore 64-bit ACPI base address is not an issue.
## Type 16, networking info
Straightforward, only needs to be generated if coreboot was compiled with networking support, otherwise simply missing.
## Type 17, EFI memory map
A major fuck up in Multiboot2 spec, this tags should NOT exists in the first place. EFI memory map should be converted to a list with tag type 6 in the first place.
## Type 18, EFI boot services
Makes not much sense with coreboot.
## Type 19, type 20, EFI image handle
Makes not much sense with coreboot.
## Type 21, load base physical address
Again, since payload is not dynamically loaded rather statically linked, load address is already known at compilation time. But this tag could be generated no probs.
Conclusion: only the coreboot to payload tags are relevant because payload is linked into the same rom image as coreboot base. Except for the boot log and fmap, there are tags for all coreboot features.
On 12/11/2022, bzt bztemail@gmail.com wrote:
As someone who implemented a payload, I think there's nothing wrong with coreboot tables. They work pretty great, and they are simple to use.
But if you insist to change that for whatever reason, my vote goes to Multiboot2 too instead of that nightmarish and bloated FDT. Placing handover data in a different structure requires minimal effort, and it won't add complexity to coreboot. It's a pretty straightforward thing (no additional code or ABI, just a little change to represent existing data in a different, more structured format).
However,
From OS point of view, multiboot2 has currently all tables what an OS needs...
I agree, I see no reason for new tags, but if you decide to do so...
ask multiboot2 spec owners to create a special "bootloader specific tag"
Please don't, never ever do that! That kills all the benefits of a standard. Instead decide on a bootloader independent, common tag, and ask he Multiboot2 spec owners to add THAT.
Just for the sake of the argument, let's assume Multiboot2 is missing memory region list (it's not, this is just an example). Then asking for a bootloader specific coreboot_specific_stuff tag and squash the memory table into that binary blob is a VERY BAD idea, goes against everything a standard is created for.
It's much better to ask for a common, loader-independent memory table tag, which coreboot can use for sure, but hopefully can be useful to other Multiboot2 compliant loaders in the future as well. (Again, just an example for the sake of the argument, there's a memory table in Multiboot2.)
Considering we all agree that Multiboot2 already has every tag needed for an OS to boot, I don't think there could be many tags to ask for in the first place. Frankly right now there's nothing I can think of that coreboot provides and payloads need, but can't be described with the existing Multiboot2 tags.
Cheers, bzt
On 12/11/2022, Rudolf Marek r.marek@assembler.cz wrote:
Hi,
On 11. 11. 22 16:19, Nico Huber wrote:
Thoughts are tumbling in my head right now: The whole Multiboot spec thing seems too complex to put into ramstage. But so does the Universal Payload thing! If we'd end up with a shim after ramstage anyway, we could as well use the existing standard.
Well it is not so complex. It has two sets of tags, one set is defined by the program to be loaded (defined in its image), and second which defines stuff similar to what coreboot tables are doing (defined in the memory and passed by certain registers at point of handover).
Multiboot2 has a *big* advantage that it also defines the machine state at the point of handover! Note that multiboot2 tags are forced to begin 8 byte aligned which seems like a plus for ABI.
I think there are some limitations of multiboot2 that some fields are only 32-bits. See the EFI notes in there for further hints. From OS point of view, multiboot2 has currently all tables what an OS needs... The previous multiboot1 lacks ACPI pointer which is a nightmare for an OS to find RSDP... (if it is no longer in legacy places...)
Anyway, what you could probably do, is simply to add a way to directly boot multiboot2 payloads from coreboot. You can leave coreboot tables as is for now and create multiboot2 tables out of coreboot tables. That would be a great step forward I think and you would instantly have a way to boot anything multiboot2 capable!
On the other hand If you want to experiment with extending the multiboot2 here are exercises to a kind reader:
Check the multiboot2 spec and coreboot_tables.h and see what tags are coreboot unique and which needs to be "added".
- Think how to incorporate them or piggyback to the multiboot2
a) ask multiboot2 spec owners to create a special "bootloader specific tag"
+--------------------+
u32 | type = 42 | u32 | size | u8[n] | bootloader specific| +--------------------+
You could embedded them in u8[n] either one by one or having it many loader specific tags.
b) for PoC you could probably misuse the bootloader name tag and do following:
3.6.9 Boot loader name
+-------------------+
u32 | type = 2 | u32 | size | u8[8] | COREBOOT | u32 | mustbezero | u32 | reserved | u32 | lb_size | u32 | lb_tag | .... +-------------------+
size = ROUNDUP(8 + 8 + 4 + 4 + lb_size, 8)
And you could have multiple boot loader tags, each for extended coreboot tag...
And there you have it...
Thanks, Rudolf
coreboot mailing list -- coreboot@coreboot.org To unsubscribe send an email to coreboot-leave@coreboot.org