mirror of
https://github.com/ItsDrike/dotfiles.git
synced 2025-06-29 12:10:42 +00:00
Major rewrite: switching back to Arch from NixOS
This commit is contained in:
parent
df585b737b
commit
254181c0fc
121 changed files with 5433 additions and 2371 deletions
205
guides/03_UNIFIED_KERNEL_IMAGES.md
Normal file
205
guides/03_UNIFIED_KERNEL_IMAGES.md
Normal file
|
@ -0,0 +1,205 @@
|
|||
# Unified Kernel Images (UKI) booting
|
||||
|
||||
A Unified Kernel Image is a single executable (`.efi` file), which can be
|
||||
booted directly from UEFI firmware, or be automatically sourced by boot loaders
|
||||
with no extra configuration.
|
||||
|
||||
> [!NOTE]
|
||||
> If you're still using BIOS, you will not be able to set up UKIs, they require
|
||||
> UEFI.
|
||||
|
||||
A UKI will include:
|
||||
|
||||
- a UEFI stub loader like (systemd-stub)
|
||||
- the kernel command line
|
||||
- microcode
|
||||
- an initramfs image
|
||||
- a kernel image
|
||||
- a splash screen
|
||||
|
||||
The most common reason why you might want to use UKIs is secure boot. That's
|
||||
because a UKI is something that can be signed and represents an immutable
|
||||
executable used for booting into your system.
|
||||
|
||||
This is good, because with a standalone bootloader, you would be allowed you to
|
||||
edit the kernel parameters, or even change the kernel image by editing the
|
||||
configuration inside of the (unencrypted) EFI partition. This is obviously
|
||||
dangerous, and we don't want to allow this.
|
||||
|
||||
## Define kernel command line
|
||||
|
||||
Since UKI contains the kernel command line, we will need to define it so that
|
||||
when the image is being built, it can pick it up.
|
||||
|
||||
This is a crucial step especially when you have encryption set up, as without
|
||||
it, the kernel wouldn't know what root partition to use.
|
||||
|
||||
To set this up, we will use `/etc/kernel/cmdline`.
|
||||
|
||||
This is how I setup my kernel arguments (If you're unsure what arguments you
|
||||
need, just check your current systemd-boot configuration, if you followed [the
|
||||
INSTALLATION guide](./01_INSTALLATION.md), you will have it in:
|
||||
`/efi/loader/entries/arch.conf`, all of the `options=` line contain
|
||||
kernel command line args):
|
||||
|
||||
```bash
|
||||
echo "rw loglevel=3" > /etc/kernel/cmdline
|
||||
echo "cryptdevice=LABEL=CRYPTFS:cryptfs:allow-discards" >> /etc/kernel/cmdline
|
||||
echo "root=/dev/mapper/cryptfs rootflags=subvol=/@" >> /etc/kernel/cmdline
|
||||
```
|
||||
|
||||
<!-- markdownlint-disable MD028 -->
|
||||
|
||||
> [!TIP]
|
||||
> If you prefer, you can also create `/etc/kernel/cmdline.d` directory, with
|
||||
> individual files for various parts of the command line. At the end, all of the
|
||||
> options from all files in this directory will be combined.
|
||||
>
|
||||
> You might find this useful if you set a lot of kernel parameters, so you might
|
||||
> have for example: `root.conf`, `apparmor.conf`, ...
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Note that you **shouldn't** be specifying the `cryptdevice` or `root` kernel
|
||||
> parameters if you're using `systemd` initramfs, rather than `BusyBox` one
|
||||
> (which mkinitramfs generates by default).
|
||||
>
|
||||
> That said, you will still need `rootflags` to select the btrfs subvolume
|
||||
> though, unless the root partition is your default subvolume.
|
||||
>
|
||||
> If you aren't sure which initramfs you're using, it's probably `BusyBox`.
|
||||
|
||||
<!-- markdownlint-disable MD028 -->
|
||||
|
||||
## Modify the linux preset for mkinitcpio to build UKIs
|
||||
|
||||
Now open `/etc/mkinitcpio.d/linux.preset`, where you'll want to:
|
||||
|
||||
- Uncomment `ALL_config`
|
||||
- Comment `default_image`
|
||||
- Uncomment `default_uki` (unified kernel image)
|
||||
- Uncomment `default_options`
|
||||
- Comment `fallback_image`
|
||||
- Uncomment `fallback_uki`
|
||||
|
||||
## Recreate /efi
|
||||
|
||||
First, we'll need to unmount `/boot`, which is currently bind-mounted to
|
||||
`/efi/EFI/arch`. This is because we'll no longer be storing the kernel,
|
||||
initramfs, nor the microcode in the EFI partition at all. The EFI partition will
|
||||
now only contain the final UKI, the rest can be left in `/boot`, which will now
|
||||
be a part of the root partition, not mounted anywhere.
|
||||
|
||||
```bash
|
||||
umount /boot
|
||||
vim /etc/fstab # remove the bind mount entry for /boot
|
||||
```
|
||||
|
||||
Now, we will clear the EFI partition and install `systemd-boot` again from
|
||||
scratch:
|
||||
|
||||
```bash
|
||||
rm -rf /efi/*
|
||||
```
|
||||
|
||||
Now, we will create a `/efi/EFI/Linux` directory, which will contain all of our
|
||||
UKIs. (You can change the location in `/etc/mkinitcpio.d/linux.preset` if you
|
||||
wish to use some other directory in the EFI partition, or you want a different
|
||||
name for the UKI file. Note that it is recommended that you stick with the same
|
||||
directory, as most boot loaders will look there when searching for UKIs.)
|
||||
|
||||
```bash
|
||||
mkdir -p /efi/EFI/Linux
|
||||
```
|
||||
|
||||
Finally, we will reinstall the kernel and microcode, re-populating `/boot` (now
|
||||
on the root partition).
|
||||
|
||||
This will also trigger a initramfs rebuild, which will now create the UKI image
|
||||
based on the `linux.preset` file.
|
||||
|
||||
```bash
|
||||
pacman -S linux amd-ucode # or intel-ucode
|
||||
```
|
||||
|
||||
## Proceeding without a boot manager
|
||||
|
||||
Because the Unified Kernel Images can actually be booted into directly from the
|
||||
UEFI, you don't need to have a boot manager installed at all. Instead, you can
|
||||
simply add the UKIs as entries to the UEFI boot menu.
|
||||
|
||||
> [!NOTE]
|
||||
> I prefer to still use a full boot manager alongside UKIs, as they allow you to
|
||||
> have a nice graphical boot menu, from which you can dynamically override the
|
||||
> kernel parameters during boot, or have extra entries for different operating
|
||||
> systems, without having to rely on the specific implementation of the boot
|
||||
> menu in your UEFI firmware (which might take really long to open, or just
|
||||
> generally not provide that good/clean experience).
|
||||
>
|
||||
> Do note though that going without a boot manager is technically a safer
|
||||
> approach, as it cuts out the middle-man entirely, whereas with a boot manager,
|
||||
> your UEFI firmware will be booting the EFI image of your boot manager, only to
|
||||
> then boot your own EFI image, being the UKI.
|
||||
>
|
||||
> Regardless, I still like to use `systemd-boot`, instead of booting UKIs
|
||||
> directly. If you wish to do the same, skip this section.
|
||||
|
||||
<!-- markdownlint-disable MD013 -->
|
||||
|
||||
```bash
|
||||
pacman -S efibootmgr
|
||||
efibootmgr --create --disk /dev/disk/nvme0n1 --part 1 --label "Arch Linux" --loader 'EFI\Linux\arch-linux.efi' --unicode
|
||||
efibootmgr -c -d /dev/disk/nvme0n1 -p 1 -L "Arch Linux Fallback" -l 'EFI\Linux\arch-linux-fallback.efi' -u
|
||||
pacman -R systemd-boot
|
||||
```
|
||||
|
||||
<!-- markdownlint-enable MD013 -->
|
||||
|
||||
You can also specify additional kernel parameters / override the default ones in
|
||||
the UKI, by simply adding a string as a last positional argument to the
|
||||
`efibootmgr` command, allowing you to create entires with different kernel
|
||||
command lines easily.
|
||||
|
||||
## Proceeding with a boot manager
|
||||
|
||||
> [!NOTE]
|
||||
> This is an alternative to the above, see the note in the previous section to
|
||||
> understand the benefits/cons of either approach.
|
||||
|
||||
Most boot managers can handle loading your UKIs. The boot manager of my choice
|
||||
is `systemd-boot`, but if you wish, you should be able to use grub, or any other
|
||||
boot manager too. That said, this guide will only mention `systemd-boot`.
|
||||
|
||||
All that we'll need to do now is installing systemd-boot, just like during the
|
||||
initial OS installation:
|
||||
|
||||
````bash
|
||||
```bash
|
||||
bootctl install --esp-path=/efi
|
||||
````
|
||||
|
||||
We can now reboot. Systemd-boot will pick up any UKI images in `/efi/EFI/Linux`
|
||||
automatically (this path is hard-coded), even without any entry configurations.
|
||||
|
||||
That said, if you do wish to do so, you can still add an explicit entry for your
|
||||
configuration in `/efi/loader/entries/arch.conf`, like so:
|
||||
|
||||
```text
|
||||
title Arch Linux
|
||||
sort-key 0
|
||||
efi /EFI/Linux/arch-linux.efi
|
||||
# If you wish, you can also specify kernel options here, it will
|
||||
# append/override those in the UKI image
|
||||
#options rootflags=subvol=/@
|
||||
#options rw loglevel=3
|
||||
```
|
||||
|
||||
Although do note that if your UKI image is stored in `/efi/EFI/Linux`, because
|
||||
systemd-boot picks it up automatically, you will see the entry twice, so you'll
|
||||
likely want to change the target directory for the UKIs (in
|
||||
`/etc/mkinitcpio.d/linux.preset`) to something else.
|
||||
|
||||
I however wouldn't recommend this approach, and I instead just let systemd-boot
|
||||
autodetect the images, unless you need something specific.
|
||||
|
||||
If everything went well, you should see a new systemd based initramfs, from
|
||||
where you'll be prompted for the LUKS2 password.
|
Loading…
Add table
Add a link
Reference in a new issue