Page MenuHomeFreeBSD

Fallback booting pieces
ClosedPublic

Authored by imp on Apr 22 2019, 6:46 PM.

Details

Summary
  1. Read in and parse /efi/freebsd/loader.env from the boot device's partition as if it were on the command line.

Fetch FreeBSD-LoaderEnv UEFI enviornment variable. If set, read in loader environment variables from it. Otherwise read in /efi/freebsd/loader.env. Both are read relative to the device loader.efi loaded from (they aren't full UEFI device paths)

Next fetch FreeBSD-NextLoaderEnv UEFI environment variable. If present, read the file it points to in as above and delete the UEFI environment variable so it only happens once.

This lets one set environment variables in the bootloader. Unfortunately, we don't have all the mechanisms in place to parse the file, nor do we have the magic pattern matching in place that loader.conf has. Variables are of the form foo=bar. No quotes are supported, so spaces aren't allowed, for example. Also, variables like foo_load=yes are intercepted when we parse the loader.conf file and things are done based on that. Since those aren't done here, variables that cause an action to happen won't work.

  1. Implement uefi_rootdev

If uefi_rootdev is set in the environment, then treat it like a device path. Convert the string to a device path and see if we can find a device that matches. If so, use that device at our root dev no matter what. If it's bad in any way, the boot will fail.

  1. Implement uefi_ignore_boot_mgr env variable.

When set, we ignore all the hints that the UEFI boot manager has set for us. We also always fail back to the OK prompt when we can't find the right thing to boot rather than failing back to the UEFI boot manager. This has the side effect of also expanding the cases where we fail back to the OK prompt to include when we're booted under UEFI, but UEFI::BootCurrent isn't set in the environment and we can't find a proper place to boot from.

NOTE: I removed the iteration through the environment GUID space since I don't need it initially for stuff I'm doing and I'm unsure of its actual value.

Diff Detail

Repository
rS FreeBSD src repository
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

imp created this revision.Apr 22 2019, 6:46 PM
imp updated this revision to Diff 56506.Apr 22 2019, 6:49 PM

update to fix spelling mistake (by removing it) and move things around
a little more.

bcran added inline comments.Apr 22 2019, 9:32 PM
stand/efi/include/efi.h
80 ↗(On Diff #56506)

Typo ("persis").

81 ↗(On Diff #56506)

Typo ("theset").

stand/efi/loader/main.c
799 ↗(On Diff #56506)

Typo ("envirnment").

800 ↗(On Diff #56506)

Typo ("sting").

872 ↗(On Diff #56506)

Typo ("witht he").

963 ↗(On Diff #56506)

Typo ("subdly")

964 ↗(On Diff #56506)

type ("laod").

965 ↗(On Diff #56506)

Typo ("simplisitc").

972 ↗(On Diff #56506)

I wonder if we might want to read loader.env from whatever directory loader.efi is running from, instead?

imp added inline comments.Apr 23 2019, 2:10 AM
stand/efi/loader/main.c
972 ↗(On Diff #56506)

Two reasons I'm going to say now. I'd thought of this and talked myself out of that.

First, if we're loading from \efi\boot\bootx64.efi, then we'd be polluting that directory. We're only allowed to use \efi\freebsd.
Second, if we're loaded directly, then we'll have the FILE spec which includes the directory. If we're loaded from boot1.efi chain loading us (or loader.efi chain loading us) we don't seem to have that, at least not reliably. So we don't know we could get it from/boot/loader.env in the chain booting case. Rather than make special cases, I thought I'd fix the path.

imp added a comment.Apr 23 2019, 2:10 AM

bcran: thanks for the typos. Ugg.

bcran added inline comments.Apr 23 2019, 2:12 AM
stand/efi/loader/main.c
972 ↗(On Diff #56506)

Good points! Yeah, we can only use /efi/freebsd so it's not like people should be configuring boot entries from random directories so I agree.

imp updated this revision to Diff 56649.Apr 25 2019, 4:18 PM
  • Add efi_freebsd_delenv
  • Read in and parse /efi/freebsd/loader.env from the boot device's
  • Implement rootdev_uefi
  • Implement uefi_ignore_boot_mgr env variable.
imp edited the summary of this revision. (Show Details)Apr 25 2019, 4:24 PM
imp updated this revision to Diff 56664.Apr 25 2019, 8:31 PM

rebase to get the chaff out of the way.

  • Read in and parse /efi/freebsd/loader.env from the boot device's
  • Implement rootdev_uefi
  • Implement uefi_ignore_boot_mgr env variable.
imp updated this revision to Diff 56683.Apr 26 2019, 5:22 AM

Final tweaks... this works for Netflix's needs

time to get it upstream.

imp edited the summary of this revision. (Show Details)Apr 26 2019, 5:23 AM
emaste added a subscriber: emaste.Apr 26 2019, 2:35 PM
imp retitled this revision from Placeholder for UEFI fallback work -- current prototype to write design doc to Fallback booting pieces.Apr 26 2019, 2:35 PM
imp edited the summary of this revision. (Show Details)
imp added reviewers: bcran, kevans, tsoome.

Could you explain what problem this is solving, please? I don't think I've had a problem with loader.efi finding the FreeBSD installation to boot from.

imp added a comment.EditedApr 28 2019, 12:34 AM

Could you explain what problem this is solving, please? I don't think I've had a problem with loader.efi finding the FreeBSD installation to boot from.

NanoBSD: I have two partitions with valid systems on them. Which one to choose? It can FIND one, but it guesses wrong half the time without this change. We have a stupid implicit bias to assuming we need to find THE system to boot from, when in reality there can be several to choose from for different reasons. We've fixed bugs where we'd choose to boot the thumb drive instead of the installed OS when someone rebooted with an installation image in it. We've fixed bugs where we'd get confused between UFS and ZFS (though making ZFS always win likely is a loser decision sometime: I've not tried to improve that). It's a classic assumption that was OK enough for powerpc where boot1.efi came from and from whence all the other decisions flowed down into loader.efi (which used to never be in the ESP). powerpc generally was hobbyist use and didn't have more demanding boot requirements. x86 has grown up with all kinds of expectations of being able to finely pick what will boot (through various mechanisms both clever and hacky). Those mechanisms are somewhat lacking, but got the job done. Due to limitations in UEFI, we can't use some of the mechanisms here (raw partition entires are tricky, though less tricky than when I started), and besides, this provides a more robust "do what I told you to" way of eliminating DWIM and the possibility it doesn't do what I mean... When you boot off this ESP, use THAT / with a way to say "oh, this one time, try this other / and if that doesn't work fall back to what we were doing before" which existed in gpt, but not mbr land.

bcran accepted this revision.Apr 29 2019, 2:26 AM
bcran added inline comments.
stand/efi/loader/main.c
821 ↗(On Diff #56683)

Typo ("te")

This revision is now accepted and ready to land.Apr 29 2019, 2:26 AM
This revision was automatically updated to reflect the committed changes.