systemd / systemd

The systemd System and Service Manager
https://systemd.io
GNU General Public License v2.0
13.29k stars 3.8k forks source link

boot.mount for the ESP is not generated when using linuxx64.efi.stub #620

Closed gdamjan closed 9 years ago

gdamjan commented 9 years ago

I was testing secureboot etc, and wanted to create a single .efi executable combining the kernel, initramfs and the command line to boot it directly from UEFI.

    objcopy \
        --add-section .osrel=/etc/os-release --change-section-vma .osrel=0x20000 \
        --add-section .cmdline=/boot/cmdline.txt --change-section-vma .cmdline=0x30000 \
        --add-section .linux=/boot/vmlinuz-linux --change-section-vma .linux=0x40000 \
        --add-section .initrd=/boot/initramfs-linux.img --change-section-vma .initrd=0x3000000 \
        /usr/lib/systemd/boot/efi/linuxx64.efi.stub /boot/EFI/Secure/combined-boot.efi

This worked (i.e. booted fine), but boot.mount and .automount were not created by the generator. Running it manually gives:

$ SYSTEMD_LOG_LEVEL=debug /lib/systemd/system-generators/systemd-efi-boot-generator
EFI loader partition unknown, exiting.

Reading the man page it says that:

Note that this generator will execute no operation on non-EFI systems, on systems where the boot loader does not communicate the used ESP to the OS

so I'm assuming that the linuxx64.efi.stub stub doesn't communicate the ESP to the OS??

This is all done on ArchLinux testing, systemd-222-1 in a KVM guest. Also happens with 221 stable on a Thinkpad.

heftig commented 9 years ago

Yes, currently this is only done by systemd-boot (formerly known as gummiboot). It guess UEFI has no standard way of providing the launched application with information about the partition it was loaded from.

arvidjaar commented 9 years ago

It guess UEFI has no standard way of providing the launched application with information about the partition it was loaded from.

It has.

When installed, the Loaded Image Device Path Protocol specifies the device path that was used when a PE/COFF image was loaded through the EFI Boot Service LoadImage().

heftig commented 9 years ago

I see. Then it seems the kernel should be extracting this information while it exists (in arch/x86/boot/compressed/eboot.c it has access to the image handle) and keep it around for user space, if only by adding an otherwise-ignored parameter to its command line.

gdamjan commented 9 years ago

What are the differences between linuxx64.efi.stub and the full gummiboot bootloader?

heftig commented 9 years ago

It sets some volatile EFI variables, see http://www.freedesktop.org/wiki/Software/systemd/BootLoaderInterface/ .

gdamjan commented 9 years ago

Interesting how LoaderTimeInitUSec and LoaderTimeExecUSec are not set, but somehow systemd-analyze still reports firmware and loader time:

Startup finished in 3.847s (firmware) + 25ms (loader) + 6.606s (kernel) + 1.925s (userspace) = 12.404s

Would a patch like this be accepted or should I make it a bit less copy/pastish?

https://github.com/gdamjan/systemd/commit/e2421a1a224e88912af792308ff1c48dcfce3d00

gdamjan commented 9 years ago

I made a pull request https://github.com/systemd/systemd/pull/637 too add efi variables in the stub too

kaysievers commented 9 years ago

It sounds a bit weird to export the same stuff from the stub, and even overwrite values which the boot manager has set.

Most of the variables are non-essential and it is expected that things still work fine. Exporting things like LoaderTime* makes no real sense here, there is no "loading" involved in the stub, it is already loaded and running.

The missing export of the UUID though is different, it changes the actual behavior of the running system. We recognize other partitions like the rootfs, /home, ..., maybe we can change the generator logic for the /boot mount to not require the boot manager to export it. @poettering?

poettering commented 9 years ago

@kaysievers yeah, sounds like a good idea, to simply query the EFI var for the ESP partition directly, instead of making the stub/boot loader copy it from one var to another...

poettering commented 9 years ago

how precisely would i query the ESP partition from userspace?

arvidjaar commented 9 years ago

how precisely would i query the ESP partition from userspace?

If you actually mean - "how to query from which partition we have been booted" - you can't do it reliably from run-time.

gdamjan commented 9 years ago

So in conclussion … it's better to add these variables in the linuxx64.efi.stub if they don't exist, right? BTW, here's the output of bootctl of vanilla stub vs my patched, when booted directly from the UEFI (so no gummiboot):

System:
     Firmware: n/a (n/a)
  Secure Boot: enabled
   Setup Mode: user

Loader:
      Product: n/a
    Partition: n/a
         File: └─n/a

System:
     Firmware: UEFI 2.31 (Lenovo 0.4432)
  Secure Boot: enabled
   Setup Mode: user

Loader:
      Product: systemd-stub 223
    Partition: /dev/disk/by-partuuid/ad91ebc4-4d62-459d-9c77-f4fd7c041514
         File: └─/EFI/Secure/combined-boot-signed.efi
kaysievers commented 9 years ago

I don't think we should export the non-essential things from the stub, they are really meant for a boot manager. I don't see the need to add the purely cosmetic things here.

The timing values make no sense for a stub, because there is nothing to load, the entire single file is already running and in memory.

The LoaderDevicePartUUID is needed for runtime operations, I see no problem with unconditionally exporting it and overwriting any earlier values from inside the stub.

kaysievers commented 9 years ago

This should make /boot work: https://github.com/systemd/systemd/commit/8110e144ff5c3a95a2ac82691ee11528b4e6642a