Page MenuHomeFreeBSD

Let the EFI loader build a partition menu
AbandonedPublic

Authored by stephane.rochoy_stormshield.eu on Fri, Feb 27, 10:43 AM.
Tags
None
Referenced Files
Unknown Object (File)
Sun, Mar 15, 6:20 AM
Unknown Object (File)
Tue, Mar 10, 6:21 PM
Unknown Object (File)
Wed, Mar 4, 9:27 AM
Unknown Object (File)
Mon, Mar 2, 7:37 PM
Unknown Object (File)
Mon, Mar 2, 11:01 AM
Unknown Object (File)
Mon, Mar 2, 4:22 AM
Unknown Object (File)
Sun, Mar 1, 6:15 AM
Unknown Object (File)
Sun, Mar 1, 6:15 AM
Subscribers

Details

Summary

It build the menu using either a static list of partitions (filtered by name
and/or unit) or by using the BOOTME attribute. Under the hood it use the
PARTITION_INFO protocol if available but fallback to builtin GPT parsing when
missing.

The following tunables are available to tweak the menu:

  • partmenu_default What partition to try when the user don't press any key after partmenu_delay seconds. Only value supported: firstbootme.
  • partmenu_firstkey The first key to use when building the menu. Default to 0.
  • partmenu_maxdelay How many seconds to wait for user input. Default to 10 seconds.
  • partmenu_names Name of partitions to include in the menu.
  • partmenu_units Unit (i.e., partition number) of partitions to include in the menu.

Note that you can combine partmenu_default=firstbootme with partmenu_names
or partmenu_units to be able to easily change the default boot partition.
With the following in loader.conf:

# Two partitions, defaulting to the first one having the BOOTME attribute
partmenu_default=firstbootme
partmenu_names=2,7

You can switch default from 2 to 7 as follow:

gpart unset -a bootme -i 2 ada0
gpart set   -a bootme -i 7 ada0

Here is an example of menu:

>>> Partitions
[1] Boot MAIN
[2] Boot BACKUP
[i] Display Information
Default: firstbootme, MAIN
Choose: boot MAIN

This patch follow a discussion in PR#207940.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 71064
Build 67947: arc lint + arc unit

Event Timeline

My big problem with this is three fold. 1. Gpt bootme is non standard, so I don't want to build anything on it. 2 all menu stuff should be in lua, not c. The part protocol is not a good base to start from. And I guess 3: it ignore the BootXXXX protocol, so locks out all other oses. It is a big reason I never merged the boot1 changes in that pr. It is too limited in what it can boot and isn't scriptable.

In D55559#1271244, @imp wrote:

My big problem with this is three fold. 1. Gpt bootme is non standard, so I don't want to build anything on it. 2 all menu stuff should be in lua, not c. The part protocol is not a good base to start from. And I guess 3: it ignore the BootXXXX protocol, so locks out all other oses. It is a big reason I never merged the boot1 changes in that pr. It is too limited in what it can boot and isn't scriptable.

Well, let's split the big problem into smaller ones then ;)

  1. The use of BOOTME is something we use here at Stormshield. I should be able to remove it from the patch. Not a big deal I guess.
  1. Putting menu in Lua looks great but I'm lacking some understanding here: is it possible before picking the partition where /boot/lua is? If yes, I'll be more than happy the use this approach.
  1. I didn't know the PARTITION_INFO protocol was a Bad Thing but as long as there's alternatives, let's see.
  1. By using the BootXXXX protocol, you means crafting the menu from it? Looks like a good idea to me :)

And if I understand correctly, 4 would solve 1 and 3, right?

In D55559#1271244, @imp wrote:

My big problem with this is three fold. 1. Gpt bootme is non standard, so I don't want to build anything on it. 2 all menu stuff should be in lua, not c. The part protocol is not a good base to start from. And I guess 3: it ignore the BootXXXX protocol, so locks out all other oses. It is a big reason I never merged the boot1 changes in that pr. It is too limited in what it can boot and isn't scriptable.

Well, let's split the big problem into smaller ones then ;)

  1. The use of BOOTME is something we use here at Stormshield. I should be able to remove it from the patch. Not a big deal I guess.

It's something that stubborn and won't die. I'd prefer not to support it at all, but it if it is supported, then I'd like it to be in a separate series. After all, I wrote gptboot.efi...

  1. Putting menu in Lua looks great but I'm lacking some understanding here: is it possible before picking the partition where /boot/lua is? If yes, I'll be more than happy the use this approach.

So the best way to do this is to chain boot, I think. Having it be before lua means it can't be scripted and we've had all kinds of problems with the unscripted parts of the system. Especially since the way you did this option we'd have to have it off by default, which forces people to compile things in. I also think it would be easier to 'restart' the interpreter with a new lua root if we needed to do that if chain-booting is too much overhead. The script to make this selection can be separate from other scripts as well, though that's less appealing to me since it means more / different config mechanisms which we've tried to avoid. Chain booting is safest, especially for not FreeBSD choices, though. It comes down to a safety vs speed issue for the feature.

  1. I didn't know the PARTITION_INFO protocol was a Bad Thing but as long as there's alternatives, let's see.

Well, it isn't a BAD thing, per se. We use it all over the place to find the partitions in a system (so the patches duplicate that work). It's just an unusual way to locate things to boot. And we already loop through all the possible root filesystems to find the right one, so re-doing that will only introduce inconsistencies into a part of the loader we've tried hard to make consistent...

  1. By using the BootXXXX protocol, you means crafting the menu from it? Looks like a good idea to me :)

Yes. That would be a full 'chain boot' situation, though. But it's super easy to implement: set NextBoot to XXXX and exit. The efi boot manager will boot that next one (though knowing what I know about the, ahem, quality of some of the EFI implementations, you may need to use the current 'chain boot' code to actually load the next stage...

And if I understand correctly, 4 would solve 1 and 3, right?

Yes. It would also solve 2. when you can trust the BootXXXX since it would just start the loader with the right root to start with.

But if people haven't setup nice, alternative boot configurations, then the 'where do I read my lua from' and 'where do I get my config from' and all those issues start to come up if we're not chain booting. The trouble is, when you have just a naked partition, what do you do with it? Do you assume the current booting environment and parameters are mostly right and just roll with that, or do you try to setup the things that get set with the BootXXXX stuff. Thankfully, most of the time, you could likely chainboot the next loader.efi from the new parition and it will do the right thing. The only wrinkle I can see is that we need to make sure when we're doing this, we opt for a more 'strict' selection of root rather than the more 'relaxed' selection of root we can have.

So thanks for the thoughtful reply. I just re-read what I wrote and I was more sleep deprived than I thought while writing it. Thanks for not reading into it the grumpiness that I can see in it (or ignoring it if you did). And your reply has given me some food for thought... What is it we're trying to build here?

In D55559#1271466, @imp wrote:
  1. The use of BOOTME is something we use here at Stormshield. I should be able to remove it from the patch. Not a big deal I guess.

It's something that stubborn and won't die. I'd prefer not to support it at all, but it if it is supported, then I'd like it to be in a separate series. After all, I wrote gptboot.efi...

Don't get me wrong: if we find something that let us call a command similar to nextboot to pick the next partition to boot, I'll drop use of BOOTME faster than light :)

In D55559#1271466, @imp wrote:

What is it we're trying to build here?

My objective is to have a boot menu:

  1. allowing to select the partition to boot
  2. from a list of candidate partitions that is configurable
  3. and we must be able to set a partition as the default one in a persistent way (i.e., not using BootNext)

My understanding is that the BootXXXX protocol is 100% suitable. The remaining question I have is how to use Lua for that. The obvious first answer would be to add the Lua scripts to the ESP (next to loader.env) but I suspect you may have some other ideas ;)

As of imp@'s comment, it seems that listing up bootable partitions/pools in loader.efi and expose the list (table / matrix) to lua, and make lua scripts to use the list and create menus would be the way to go.

Current implementation for boot1.efi at Bug 207940 does both of them inside itself, as boot1.efi doesn't have script interpreters like Forth or Lua in it.

So the first level is BootXXXX. I think that's well in hand.
The next level is 'I want to boot this other thing.' that's harder. Though kevans pointed me at something he'd started that will help that a lot...

In D55559#1272827, @imp wrote:

So the first level is BootXXXX. I think that's well in hand.

OK, I'll start working on that then.

I submitted a PoC following our discussion, see D55936.