mirror of
https://github.com/ItsDrike/dotfiles.git
synced 2025-06-29 04:00: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
211
guides/05_SYSTEMD_INITRAMFS.md
Normal file
211
guides/05_SYSTEMD_INITRAMFS.md
Normal file
|
@ -0,0 +1,211 @@
|
|||
# Systemd initramfs
|
||||
|
||||
The initial ramdisk is in essence a very small environment (early userspace)
|
||||
whihc loads various kernel modules and sets up necessary things before handing
|
||||
control over to `init` program (systemd).
|
||||
|
||||
By default, Arch Linux uses a BusyBox+udev based initial ramdisk, generated by
|
||||
`mkinitcpio`. This default initrd is essentially just a small script, that
|
||||
executes other scripts, called hooks.
|
||||
|
||||
As an alternative to this, it's possible to have systemd run from the very
|
||||
start, during that initial ramdisk phase. With this approach, the tasks ran at
|
||||
this phase are determined by regular systemd unit files.
|
||||
|
||||
## Why?
|
||||
|
||||
Obviously, BusyBox initramfs works just fine, so why would you want to switch?
|
||||
Well, there's a few reasons:
|
||||
|
||||
- **Consistency across boot phases:** The same systemd process that handles your
|
||||
system after boot can also manage the early userspace during boot, providing
|
||||
consistency in handling services, devices and dependencies throughout the
|
||||
entire boot process.
|
||||
- **Simplified troubleshooting:** The tools and logs available during the boot
|
||||
process will be the same as those used once the system is fully booted,
|
||||
allowing you to troubleshoot problems with familiar tools (`journalctl`,
|
||||
`systemctl`, ...)
|
||||
- **Consistent Unit Files:** Since systemd uses the same unit files in the
|
||||
initramfs as it does in the fully booted system, the configuration for many
|
||||
tasks (like mounting filesystems) is unified, reducing duplication of
|
||||
configuration files.
|
||||
- **TPM Unlocking Support:** Systemd has built-in support for requesting data
|
||||
from TPM, allowing for a setup with TPM auto-unlocking an encrypted root
|
||||
partition, without having to specify the decryption password.
|
||||
- **Parallel Service Startup:** Systemd is known for the ability to start
|
||||
services in parallel, which can potentially **speed up the boot process**
|
||||
compared to sequential script-based approach.
|
||||
- **Integrated Mount Handling:** With systemd, managing complex mount setup
|
||||
(e.g. LVM RAID) can be more seamless, since it natively supports these and can
|
||||
handle them with less custom scripting.
|
||||
|
||||
That said, it's important to also mention some downsides and reasons why you
|
||||
might not want to use systemd-based initramfs:
|
||||
|
||||
- **Simplicity:** If you prefer a simple, more minimalistic approach,
|
||||
BusyBox-based initramfs might be sufficient and easier to manage.
|
||||
- **Size:** A systemd-based initramfs might be larger than a minimal
|
||||
BusyBox-based initramfs, which could be a concern on systems with very limited
|
||||
space.
|
||||
- **Compatibility:** If you're running some custom scripts or hooks, they might
|
||||
not work with a systemd-based initramfs.
|
||||
|
||||
## Switching to systemd initramfs
|
||||
|
||||
Open `/etc/mkinitcpio.conf` and find a line that starts with `HOOKS=`
|
||||
|
||||
- Change `udev` to `systemd`
|
||||
- Change `keymap consolefont` to `sd-vconsole`
|
||||
- Add `sd-encrypt` before `block`, and remove `encrypt`
|
||||
- If you were using `mkinitcpio-numlock`, also remove `numlock`, it doesn't work
|
||||
with systemd (we'll go over how to auto-enable numlock later)
|
||||
|
||||
Additionally, with systemd initramfs, you shouldn't be specifying `root` nor
|
||||
`cryptdevice` kernel arguments, as systemd can actually pick those up
|
||||
automatically (they'll be discovered by [systemd-cryptsetup-generator] and
|
||||
auto-mounted from initramfs via [systemd-gpt-auto-generator]). We will however
|
||||
still need the `rootflags` argument for selecting the btrfs subvolume (unless
|
||||
your default subvolume is the root partition subvolume).
|
||||
|
||||
[systemd-cryptsetup-generator]: https://wiki.archlinux.org/title/Dm-crypt/System_configuration#Using_systemd-cryptsetup-generator
|
||||
[systemd-gpt-auto-generator]: https://wiki.archlinux.org/title/Systemd#GPT_partition_automounting
|
||||
|
||||
So, let's edit our kernel parameters:
|
||||
|
||||
```bash
|
||||
echo "rw loglevel=3" > /etc/kernel/cmdline # overwrite the existing cmdline
|
||||
echo "rootflags=subvol=/@" >> /etc/kernel/cmdline
|
||||
```
|
||||
|
||||
You'll also need to modify the `/etc/fstab`, as systemd will not use the
|
||||
`/dev/mapper/cryptfs` name, but rather you'll have a `/dev/gpt-auto-root`
|
||||
(there'll also be `/dev/gpt-auto-root-luks`, which is the encrypted partition).
|
||||
If you prefer using a mapper device, you can also use `/dev/mapper/root`.
|
||||
Alternatively, you can use the label to mount. (if you followed the
|
||||
installation guide, that would be `/dev/disk/by-label/FS`.)
|
||||
|
||||
```bash
|
||||
vim /etc/fstab
|
||||
```
|
||||
|
||||
Finally, regenerate the initramfs with: `pacman -S linux` (you could also do
|
||||
`mkinitcpio -P`, however that won't trigger the pacman hook which auto-signs our
|
||||
UKI images for secure boot, so you'd have to re-sign them with `sbctl` manually,
|
||||
if you're using secure-boot) and reboot to check if it worked.
|
||||
|
||||
## Activating numlock
|
||||
|
||||
Since we had to remove `mkinitcpio-numlock`, as that hook isintended for BusyBox
|
||||
based initrd, we'll want to have an alternative available.
|
||||
|
||||
First though, we should also remove the package: `pacman -R mkinitcpio-numlock`.
|
||||
|
||||
### The simple, but imperfect option
|
||||
|
||||
There is a `systemd-numlockontty` AUR package which creates a systemd service
|
||||
that enables numlock in TTYs after booting (you'll need to enable it), this
|
||||
however doesn't happen in initramfs directly, only afterwards.
|
||||
|
||||
Depending on what you will need, this may be sufficient. If you are going to be
|
||||
typing a decryption password at this early stage and you wish to have numlock
|
||||
support there, you will need to do some more work.
|
||||
|
||||
### The proper solution
|
||||
|
||||
To enable numlock before you're prompted for the decryption password, we'll need
|
||||
to create a custom initcpio hook, that will return a systemd service which will
|
||||
do the enabling. We'll put this hook into `/usr/lib/initcpio/install/numlock`,
|
||||
with the following content:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
build() {
|
||||
add_binary /bin/bash
|
||||
add_binary /usr/bin/setleds
|
||||
add_binary /usr/local/bin/numlock
|
||||
|
||||
cat >"$BUILDROOT/usr/lib/systemd/system/numlock.service" <<EOF
|
||||
[Unit]
|
||||
Description=Enable numlock
|
||||
Before=cryptsetup-pre.target
|
||||
DefaultDependencies=no
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/local/bin/numlock
|
||||
EOF
|
||||
|
||||
add_systemd_unit cryptsetup-pre.target
|
||||
cd "$BUILDROOT/usr/lib/systemd/system/sysinit.target.wants" || exit
|
||||
ln -sf /usr/lib/systemd/system/cryptsetup-pre.target cryptsetup-pre.target
|
||||
ln -sf /usr/lib/systemd/system/numlock.service numlock.service
|
||||
}
|
||||
|
||||
help() {
|
||||
cat <<EOF
|
||||
This hook adds support to enable numlock before sd-encrypt hook is run.
|
||||
EOF
|
||||
}
|
||||
```
|
||||
|
||||
This script is also present in my dotfiles, so you can just copy it from there:
|
||||
|
||||
```bash
|
||||
cp ~/dots/root/usr/lib/initcpio/install/numlock /usr/lib/initcpio/install
|
||||
```
|
||||
|
||||
Next we will need to create that `/usr/local/bin/numlock` script. This script
|
||||
will do the actual enabling of numlock. Note that we can only use the binaries
|
||||
that we explicitly included in our hook inside our script.
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
for tty in /dev/tty[0-9]; do
|
||||
/usr/bin/setleds -D +num < "$tty"
|
||||
done
|
||||
```
|
||||
|
||||
If you ran the `install_root.sh` script from my dotfiles during
|
||||
[INSTALLATION](./01_INSTALLATION.md), this script will already be present in
|
||||
your `/usr/local/bin`
|
||||
|
||||
Now we will need to add our custom new `numlock` hook to
|
||||
`/etc/mkinitcpio.conf`, before the `sd-encrypt` hook (assuming you're using
|
||||
encryption), but after the `keyboard` and `sd-vconsole` hooks.
|
||||
|
||||
Finally, we'll need to rebuild initramfs, which we should trigger with `sudo
|
||||
pacman -S linux`, to make sure the secure-boot signing also runs. When
|
||||
re-building the initramfs, pay attention on the output, you should see it pass
|
||||
with no errors:
|
||||
|
||||
```text
|
||||
-> Running build hook: [base]
|
||||
-> Running build hook: [systemd]
|
||||
-> Running build hook: [autodetect]
|
||||
-> Running build hook: [microcode]
|
||||
-> Running build hook: [modconf]
|
||||
-> Running build hook: [kms]
|
||||
-> Running build hook: [keyboard]
|
||||
-> Running build hook: [sd-vconsole]
|
||||
-> Running build hook: [numlock] # <-- make sure this is present
|
||||
-> Running build hook: [sd-encrypt]
|
||||
-> Running build hook: [block]
|
||||
-> Running build hook: [filesystems]
|
||||
-> Running build hook: [fsck]
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> If you see some warnings there, like:
|
||||
> `==> WARNING: Possibly missing firmware for module: 'xyz'`, you can usually
|
||||
> safely ignore these. Just make sure there's no `==> ERROR: ...`
|
||||
|
||||
If you didn't see any errors, you can now reboot.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> In some cases, the numlock led indicator might not turn on immediately, even
|
||||
> though numlock was actually turned on. This may mislead you towards thinking
|
||||
> it is not on, even though it actually is. I'd recommend trying it out by
|
||||
> actually typing something it at this time.
|
||||
>
|
||||
> Note that after this early boot stage, the indicator should light up
|
||||
> eventually.
|
Loading…
Add table
Add a link
Reference in a new issue