Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[mkinitcpio] Create UEFI executables #53

Merged
merged 12 commits into from
Jul 7, 2021

Conversation

Foxboron
Copy link
Member

@Foxboron Foxboron commented Apr 5, 2021

Missing stuff for this pull-request.

  • Do we want a new section in the manpages?
  • Is the flags okay enough?
  • Testing

Implement UEFI executable generation in mkinitcpio by utilizing UEFI
stubs provided by systemd/gummiboot.

This allows us to create a unified boot image we can boot from UEFI
with. These are practical for secure boot as we can sign initramfs,
kernel cmdline and the kernel all at once. By utilizing the
BOOT_LOADER_SPECIFICATION we can also drop new images into the correct
patch and have systemd-boot/gummiboot pick up the images.

The code does several things and does a fair amount of guessing to
figure out all the inputs needed.

We use /etc/kernel/cmdline to localize the kernel cmdline options we
want for the image. This is inherited from the kernel-install hook
system which might double as some form of standard.

We also do a dance to get the correct kernel image. We do a lookup into
/lib/modules and /boot for both versioned and unversioned kernels
(mainly Arch Linux).

There is an attempt to support both 32bit and 64bit lookup paths for the
stub images, but only 64bit is tested.

Gummiboot is also not tested.

https://www.freedesktop.org/software/systemd/man/kernel-install.html

https://systemd.io/BOOT_LOADER_SPECIFICATION/#type-2-efi-unified-kernel-images

Signed-off-by: Morten Linderud morten@linderud.pw

Implement UEFI executable generation in mkinitcpio by utilizing UEFI
stubs provided by systemd/gummiboot.

This allows us to create a unified boot image we can boot from UEFI
with. These are practical for secure boot as we can sign initramfs,
kernel cmdline and the kernel all at once. By utilizing the
BOOT_LOADER_SPECIFICATION we can also drop new images into the correct
patch and have systemd-boot/gummiboot pick up the images.

The code does several things and does a fair amount of guessing to
figure out all the inputs needed.

We use `/etc/kernel/cmdline` to localize the kernel cmdline options we
want for the image. This is inherited from the `kernel-install` hook
system which might double as some form of standard.

We also do a dance to get the correct kernel image. We do a lookup into
/lib/modules and /boot for both versioned and unversioned kernels
(mainly Arch Linux).

There is an attempt to support both 32bit and 64bit lookup paths for the
stub images, but only 64bit is tested.

Gummiboot is also not tested.

https://www.freedesktop.org/software/systemd/man/kernel-install.html

https://systemd.io/BOOT_LOADER_SPECIFICATION/#type-2-efi-unified-kernel-images

Signed-off-by: Morten Linderud <morten@linderud.pw>
mkinitcpio Outdated Show resolved Hide resolved
mkinitcpio Outdated Show resolved Hide resolved
mkinitcpio Show resolved Hide resolved
mkinitcpio Outdated Show resolved Hide resolved
mkinitcpio Outdated Show resolved Hide resolved
mkinitcpio.d/example.preset Outdated Show resolved Hide resolved
mkinitcpio Outdated Show resolved Hide resolved
mkinitcpio Show resolved Hide resolved
mkinitcpio Show resolved Hide resolved
mkinitcpio.d/example.preset Outdated Show resolved Hide resolved
mkinitcpio.d/example.preset Outdated Show resolved Hide resolved
Signed-off-by: Morten Linderud <morten@linderud.pw>
Signed-off-by: Morten Linderud <morten@linderud.pw>
@Foxboron
Copy link
Member Author

Foxboron commented Apr 7, 2021

Added a manpage. Missing some '/usr/lib/os-release' fallback but should be'ish fine I think. @grazzolini I think a general ack/nack or changes you want to see would be useful at this point.

mkinitcpio Show resolved Hide resolved
@gdamjan
Copy link

gdamjan commented Apr 7, 2021

It would be useful to have an Example in the man page, for manual non-preset invocation,

Signed-off-by: Morten Linderud <morten@linderud.pw>
@Foxboron
Copy link
Member Author

Manpages has been fixed up. I intend to try expand the preset documentation in another PR. It should preferably explain how it works instead of you having to infer it through examples.

@Foxboron Foxboron marked this pull request as ready for review April 10, 2021 17:27
Signed-off-by: Morten Linderud <morten@linderud.pw>
Signed-off-by: Morten Linderud <morten@linderud.pw>
Signed-off-by: Morten Linderud <morten@linderud.pw>
Signed-off-by: Morten Linderud <morten@linderud.pw>
Signed-off-by: Morten Linderud <morten@linderud.pw>
@Foxboron
Copy link
Member Author

I think everything should be good. I have built a package people can test if they want to.

https://pkgbuild.com/~foxboron/repos/loose-pkgs/

https://github.com/Foxboron/PKGBUILDS/tree/master/mkinitcpio

@Foxboron
Copy link
Member Author

I realized #8 is a thing. I hijacked -R for --osrelease. Does anyone have a better flag suggestion :D?

@klausenbusk
Copy link
Member

I think everything should be good. I have built a package people can test if they want to.

I tested this and it works like a dream, good work! :)

@gdamjan
Copy link

gdamjan commented Apr 13, 2021

I realized #8 is a thing. I hijacked -R for --osrelease. Does anyone have a better flag suggestion :D?

-O ?

edit:
on a second thought, -O seems to much like an output (ie in curl etc). I think overriding osrelease should be so uncommon that it shouldn't even have a short flag at all.

@Foxboron
Copy link
Member Author

I have no clue how I missed the availability of -O...

@Foxboron
Copy link
Member Author

I'd be happy to drop all the short options (except for -U) if @grazzolini thinks it's fine. I have mostly just mirrored the existing stuff which all have both.

@gdamjan
Copy link

gdamjan commented Apr 25, 2021

First of all, great feature. Just a simple suggestion.

Currently the command mkinitcpio --uefi /boot/EFI/Linux/xyz.efi finishes with Dry run complete, use -g IMAGE to generate a real image.

In my opinion, it makes sense that the command already had an image specified , and it should just make the initramfs in /tmp// and then create the final uefi image it was asked for.

@Foxboron
Copy link
Member Author

Foxboron commented Apr 25, 2021

Frankly I'd prefer if mkinitcpio -p linux -- --uefi /boot/EFI/Linux/xyz.efi would be possible which is what #56 introduces.

I agree that mkinitcpio --uefi should do the correct thing but I'm a bit unsure if this is a super ugly hack or not :)

diff --git a/mkinitcpio b/mkinitcpio
index 0111f80..eda4dca 100755
--- a/mkinitcpio
+++ b/mkinitcpio
@@ -599,6 +599,14 @@ if [[ -n $_d_flag_hooks && -n $_d_flag_install ]]; then
     _d_install=${_d_flag_install%:}
 fi
 
+
+# If we specified --uefi but no -g we want to create a temporary initramfs which will be used with the efi executable.
+if [[ $_optuefi && $_optgenimg == "" ]]; then
+    tmpfile=$(mktemp -t mkinitcpio.XXXXXX)
+    trap "rm $tmpfile" EXIT
+    _optgenimg="$tmpfile"
+fi
+
 # insist that /proc and /dev be mounted (important for chroots)
 # NOTE: avoid using mountpoint for this -- look for the paths that we actually
 # use in mkinitcpio. Avoids issues like FS#26344.

man/mkinitcpio.8.txt Outdated Show resolved Hide resolved
@grazzolini grazzolini self-assigned this Jun 30, 2021
Signed-off-by: Morten Linderud <morten@linderud.pw>
Preferably we shouldn't need to have a dry run when `mkinitcpio -U` is
invoked, instead create a temporary initramfs we use for the UEFI
executable.

Signed-off-by: Morten Linderud <morten@linderud.pw>
@Foxboron
Copy link
Member Author

Foxboron commented Jul 5, 2021

I have removed the short options, fixed up the manpage+help text. I also implemented the -U workaround with a temporary initramfs as suggested.

Signed-off-by: Morten Linderud <morten@linderud.pw>
@grazzolini grazzolini merged commit f40bb42 into archlinux:master Jul 7, 2021
@Foxboron
Copy link
Member Author

Foxboron commented Jul 7, 2021

@grazzolini I'm not quite sure why you decided to merge this with 11 fixup commits I intended to squash before finalizing. The idea was to make it easier to review incremental changes.

@yan12125
Copy link
Contributor

yan12125 commented Jul 8, 2021

@Foxboron Huge thanks for this feature! Here is a missing fix - the short option -m for --microcode is dropped, while the mkinitcpio script still uses -m for microcode imags parsed from preset files [1]

[1]

preset_cmd+=(-m "$mc")

@Foxboron
Copy link
Member Author

Foxboron commented Jul 8, 2021

@yan12125 ohnoo! I'll send a fix :)

EDIT: Fixed with #58

@grazzolini
Copy link
Member

@grazzolini I'm not quite sure why you decided to merge this with 11 fixup commits I intended to squash before finalizing. The idea was to make it easier to review incremental changes.

I don't mind the fixups, don't worry. I plan on making a new release soon.

mkinitcpio Show resolved Hide resolved
mkinitcpio Show resolved Hide resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants