We need to tell GRUB how to boot into our chroot so the machine knows how to boot.
Background: init, initrd, and switch_root
One of the most god-tier commands I've ever encountered in Linux is
switch_root
; this super simple command is part of util-linux package and does
what it says on the tin. It's mostly meant to be used by initramfs to allow
bootloaders to change root, but you can use it as many times as you like.
Creating our init script
You can effectively put this script anywhere you like, but remember that this is going to run with absolutely max permissions at root. Put it in a secure place with the right permissions or you're going to be sad.
The script is simple:
#!/bin/bash
mount -o bind /path/to/chroot /path/to/chroot
# change the path to systemd as necessary
exec switch_root /path/to/chroot /usr/lib/systemd/systemd
And that's all we need. Obviously, change /path/to/chroot
and the path to
systemd
(as found in the chroot) or init
as necessary.
Adding the GRUB boot entry
Generally, I would suggest taking a peek at the /boot/grub/grub.cfg
file and
seeing how your existing menuentries look. This will largely determine how you
write your menuentry. Regardless of what you end up writing, you should add this
menuentry to /etc/grub.d/40_custom
so that it's added to grub.cfg safely.
My menuentry looks like this, for reference:
menuentry 'Blackarch' --class arch --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-blackarch-8ed35644-7895-4d7d-b4e9-59769ea11960' {
recordfail
load_video
gfxmode $linux_gfx_mode
insmod gzio
if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
insmod part_gpt
insmod ext2
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root aaaa83e9-ef27-4c29-8c54-b3c3468c49a6
else
search --no-floppy --fs-uuid --set=root aaaa83e9-ef27-4c29-8c54-b3c3468c49a6
fi
linux /vmlinuz-0blackarch rd.luks.uuid=4fa5a9e1-dbdd-4ad4-a0e7-52908229dd34 root=/dev/mapper/kubuntu--vg-root ro init=/home/addisoncrump/blackarch/scripts/blackarch-init
initrd /initramfs-0blackarch.img
}
Notable things:
- If you're using LUKS on LVM encryption, you need to add the
rd.luks.uuid
entry pointing to the encrypted LVM group. - Change the
root
value according to the name of your volume group entry as neccessary; my volume group is calledkubuntu-vg
and I need to boot into the group member calledroot
, so my root is/dev/mapper/kubuntu--vg-root
. - You need to change
init
to the path to your init script. - Change
0blackarch
to the name of your generated value as necessary. - Change all the block UUIDs as necessary using
blkid
.
Copying generated initramfs
You need to copy the initramfs
and vmlinuz
generated earlier into /boot
and rename them as necessary. This is left as an exercise to the reader, but
make sure it matches the values found in your menuentry.
update-grub
Now just run update-grub
. It'll let you know if there are problems with your
custom menuentry.
You may need to change your /etc/default/grub
as well, as most configurations
skip the GRUB menu by default. I leave this also as an exercise to the reader,
as this will largely depend on your configuration.
Reboot and test
Go ahead and reboot. If you have trouble here, you're largely on your own, but you can contact me if you really can't figure it out.
Conclusion
Yes, you can boot directly into a chroot, even on encrypted systems. Pretty powerful, actually.