Update on EFI work: refactoring ready for testing, GELI coming very soon

Eric McCorkle eric at metricspace.net
Sun May 15 20:37:43 UTC 2016


How close is that patch to going in?

Something like this would be pretty straightforward following the refactoring; however, its worth considering all the options here:

* GRUB works fine pulling loader off the disk, with either ZFS or UFS, with no boot1 at all.  This was my setup for developing the ZFS support, actually. 
* In theory it should be possible to install loader itself on the ESP and install a /boot/config that points it to the real kernel and rootfs

The takeaway is that boot1 is kind of an odd citizen in the EFI world. When you get into things like GELI support and secure boot (my next planned thing after this), its role is much clearer, but at that point it also becomes a key attack vector in a system that's presumably trying to resist some level of tampering. 

What I'm getting at is that there is a future-oriented case for keeping boot1 simple, and if it's a boot menu you want, grub is already an option (also, the loader-only method).

To be clear: I'm not opposed to adding this feature; I just want to make sure these issues are given due consideration. 

On May 15, 2016 12:00:58 PM EDT, Oliver Pinter <oliver.pinter at hardenedbsd.org> wrote:
>Hi Eric!
>
>Could you please take a look at this PR:
>https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=207940
>This feature would be nice too.
>
>On 5/15/16, Eric McCorkle <eric at metricspace.net> wrote:
>> Hello everyone,
>>
>> I've been working on a rather significant refactoring of the EFI
>boot/loader
>> code.  While this was originally in support of adding GELI support,
>it has
>> grown to such a scope that it could be considered a patch in its own
>right.
>>
>> The branch containing my work can be found here:
>> https://github.com/emc2/freebsd/tree/efize
>>
>> The following is a summary of the changes:
>> * Both boot1 and loader have been redesigned to look for instances of
>> EFI_SIMPLE_FILESYSTEM_PROTOCOL and load using that interface.  In
>loader,
>> this is accomplished through a new synthetic filesystem driver
>(called
>> efifs) that is just a wrapper around EFI_SIMPLE_FILESYSTEM_PROTOCOL. 
>In
>> boot, this is achieved by calling the interface directly.
>> * The efipart and filesystem back ends (including ZFS) have been
>moved into
>> a drivers directory, where they have been wrapped up into a
>filesystem
>> backend driver that does the same probing that loader does today, and
>then
>> installs an EFI_SIMPLE_FILESYSTEM_INTERFACE on all device handles
>that host
>> supported filesystems.  This interface is a wrapper around the
>filesystem
>> interface currently used by loader.
>> * boot now uses the same filesystem backend code as loader.  This
>increased
>> its size, necessitating recreation of the FAT templates.  The old
>boot
>> filesystem code and boot modules have been discarded.
>> * loader can use any protocol interface installed by boot just fine. 
>These
>> remain valid until ExitBootServices is called.  Moreover, the probing
>> process is idempotent, and is run by both boot and loader, with the
>first
>> one to run actually installing the interfaces.
>> * I had originally hoped to move the entire code base to use the EFI
>driver
>> model, which would support hotplugging devices.  However, the new
>bcache
>> stuff currently requires that all devices be statically detected
>before the
>> caches are used, which is fundamentally incompatible with this way of
>doing
>> things.  This was the sole blocker of such a transition (the
>handles.c code
>> requires some minor modification as well, but nothing problematic)
>> * I had also considered altering the device name code to use textual
>> representations of EFI device paths, but I don't see any real reason
>for
>> doing so.
>> * I have not touched efinet or nfs in this changeset.
>>
>> The rationale for these changes is as follows:
>> * The model of looking for EFI_SIMPLE_FILESYSTEM_PROTOCOL instances
>and
>> using them to load things increases interoperability with other
>systems.
>> For example, the new boot and loader would work just fine with
>interfaces
>> installed by GRUB or another boot loader, or perhaps custom
>filesystem
>> modules added into an open-source firmware implementation like
>coreboot.
>> * This model works really well for functionality like GELI or custom
>> partition schemes that potentially create new devices.  All you do is
>create
>> one or more new device nodes, attach device paths and block io
>interfaces,
>> and call ConnectController on them (for now, it's necessary to make
>sure the
>> fs_driver runs AFTER) all new nodes have been created. This also
>vastly
>> simplifies passing information between stages about filesystems and
>devices
>> (this is important for GELI).
>> * This approach can leverage drivers that are mandated by the EFI
>spec, like
>> the GPT partition driver.  This avoids reimplementing such a driver
>to
>> support partition schemes nested inside GELI volumes, for example.
>> * This model provides most of the groundwork for supporting hot
>plugging of
>> devices at boot time.  All that is required at this point is a
>refactoring
>> of bcache to support adding new devices dynamically (I had to draw
>the line
>> somewhere, and this had already gotten big enough, and I want to
>focus on
>> GELI support)
>> * Getting rid of the duplicated and minimized filesystem code in
>boot1
>> improves maintainability.  Indeed, the actual boot1 code is quite
>small
>> now.
>>
>> Some notes and future work:
>> * In general, the FreeBSD loader framework and the EFI framework do
>many
>> similar things.  For the most part, there is a fairly direct mapping,
>though
>> EFI interfaces tend to be more tedious.  The one thing EFI does
>decidedly
>> better is support dynamic detection of devices (hotplugging).
>> * There are some interesting possibilities for hotplugging beyond
>just the
>> obvious.  For example, loading GELI or other keys off of hotplugged
>USB
>> sticks.
>> * I didn't touch efinet or nfs on this patch.  It is certainly
>possible to
>> efize them as well, but I don't have a test setup for doing so (or
>frankly,
>> the motivation to do so).
>> * It might make more sense to use the EFI_LOAD_FILE_PROTOCOL to do
>the
>> actual loading, as some applications support this without supporting
>a full
>> filesystem interface (some embedded devices do this, as do some
>network boot
>> protocols).  However, this would involve changing the non-EFI boot
>code and
>> interfaces, which is something I specifically wanted to avoid in this
>work.
>>
>> This changeset can be tested as is, and should just work. 
>Disclaimer: I
>> rebased it to head yesterday, and haven't had time to build and test
>it yet,
>> but I will.  I know it works with ZFS, but I have no UFS systems on
>which to
>> test that functionality.
>>
>> If you intend to test this, I STRONGLY recommend installing an EFI
>shell on
>> your ESP, and then installing the modified boot block under something
>like
>> boot.tst.  This will allow you to run the modified boot block, but
>fall back
>> to a working boot if it fails.  Also, I had modified the loader path
>to
>> /boot/loader.tst for similar reasons, and it may still be set to that
>in the
>> code.
>>
>> I am currently adding GELI support as a proper EFI driver, and should
>be
>> coming in the very near future (the code is already written, in
>fact).  If
>> anyone wants to test the refactoring by itself, any results or
>comments are
>> certainly appreciated.
>> _______________________________________________
>> freebsd-hackers at freebsd.org mailing list
>> https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
>> To unsubscribe, send any mail to
>"freebsd-hackers-unsubscribe at freebsd.org"
>>

-- 
Sent from my Android device with K-9 Mail. Please excuse my brevity.


More information about the freebsd-hackers mailing list