Used the below steps to set up three separate Ubuntu systems on one machine. Works great!
Ideas
Overview
- Obviously create multiple backups of any valuable data beforehand. Changing the boot procedure, formatting disks, enabling encryption, etcetera can be hazardous and care needs to be taken.
- Install Windows first.
- Seems to be a general recommendation, though should matter less with UEFI.
- It will prepare the GPT and ESP, this can also be done manually using GNOME Partition Editor from the Ubuntu USB/DVD.
- The ESP created by the Windows installer might not be big enough, depending on the number of Ubuntu instances and kernel sizes. 512 MB seems enough for 2 Ubuntu-instances, but 1 GB would be safer and allow more instances.
- Install
refind
and make sure it boots with Secure Boot.
- For each desired Ubuntu system instance:
- Run the default Ubuntu installer from USB or DVD.
- Select the option "Something else" to manually set up encryption and select partitions.
- Don't reboot after the installation, but stay to setup the
refind
boot process.
- Over time, perform maintenance tasks if there are kernel or driver updates.
Per-instance installation
Assumes that the GUID Partition Table (GPT) and the ESP has been set up by the Windows installer, and that there are additional partitions(s) or empty disk space for the Ubuntu instance(s).
Partition paths and names
For consistency I'll use this partition path naming below. Paths will be different on your system, and will vary by instance, so please keep notes.
/dev/nvme0n1p11
is your ESP.
/dev/nvme0n1p22
is your temporary /boot
partition.
/dev/nvme0n1p33
is your per-instance "physical volume for encryption" (locked) root /
partition.
/dev/mapper/nvme0n1p33_crypt
is your (unlocked) root /
partition.
Partition and install a new (additional) Ubuntu instance
- Get Ubuntu on USB or DVD, boot it selecting "Try out Ubuntu".
- Open a terminal to update and start the installer.
sudo apt update && sudo apt dist-upgrade -y
ubiquity --no-bootloader
- When asked about installation type (co-existing with other operating systems) and disk formatting/partitioning, select "Something else" to see a list of disks and partitions.
- Find the partition with type
efi
, the ESP.
- On my system this is
/dev/nvme0n1p11
.
- Make a note of the partition path name as you'll need it below.
- Check that it has at least 200 MB free before continuing, as it will be needed for the new instance kernel.
- Select or create a boot partition.
- On my system this is
/dev/nvme0n1p22
.
- Make a note of the boot partition path name as you'll need it below.
- Will be reused for subsequent Ubuntu instance installations.
- Create or select a small (maximum 512 MB) partition.
- Erase/format as EXT4.
- Click "change" and mount it as
/boot
.
- Select or create a root partition for Ubuntu.
- On my system this is
/dev/nvme0n1p33
.
- Make a note of the root partition path name as you'll need it below.
- It will be erased.
- 5 GB for minimal, 25+ GB for a full installation.
- Click "change" and make it an "physical volume for encryption".
- Choose a password which is not the same as for the other instances.
- Find the new, unlocked partition ending with
_crypt
.
- On my system this is
/dev/mapper/nvme0n1p33_crypt
.
- Change the mount point to root
/
.
- Let the installer finish, but do not reboot at the end by selecting "Continue testing".
Set up refind
for the new instance.
Enter chroot
to the new operating system to make more changes.
# NOTE: create temporary mount directories.
sudo mkdir /mnt/bootpartition /mnt/ospartition
# NOTE: Mount the newly created encrypted partition.
sudo mount -o subvol=@ /dev/mapper/nvme0n1p33_crypt /mnt/ospartition
sudo mount /dev/nvme0n1p22 /mnt/bootpartition
# NOTE: Copy the boot files into the encrypted partition.
# NOTE: Watch those trailing slashes! rsync is very sensitive to them.
sudo rsync -aXAH /mnt/bootpartition/ /mnt/ospartition/boot/
sudo mount /dev/nvme0n1p11 /mnt/ospartition/boot/efi
sudo mount --bind /dev /mnt/ospartition/dev
sudo mount --bind /proc /mnt/ospartition/proc
sudo mount --bind /sys /mnt/ospartition/sys
# NOTE: change root to the newly installed Ubuntu.
sudo chroot /mnt/ospartition
- Edit
/etc/fstab
and comment out the line for /boot
. The other entries are correct.
- Optional: make other low-level system file changes, such as workarounds for broken drivers1.
- Create an EFI-bootable copy of the kernel (
vmlinuz
) and the initial ramdisk (initrd
) for refind
. Remember to replace ubuntu-instance
with something of our own. I use "ubuntu-work" and similar. Do not use just "ubuntu" as it might get overwritten by the Ubuntu installer.
# NOTE: Choose your own per-instance directory name.
sudo mkdir /boot/efi/EFI/ubuntu-instance/
sudo cp /boot/vmlinuz* /boot/initrd* /boot/efi/EFI/ubuntu-instance/
- Look for
/dev/nvme0n1p33
, the physical volume for encryption for this instance. Make a note of (or copy to the clipboard) the UUID (but not the PARTUUID).
sudo blkid
- Prepare
refind
's Ubuntu instance kernel boot options for the encrypted partition in refind_linux.conf
. Create /boot/efi/EFI/ubuntu-instance/refind_linux.conf
from the below template, but with your path and UUID.
"Boot with standard options" "root=/dev/mapper/nvme0n1p33_crypt cryptdevice=UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:nvme0n1p33_crypt ro quiet splash"
"Boot to single-user mode" "root=/dev/mapper/nvme0n1p33_crypt cryptdevice=UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:nvme0n1p33_crypt ro single"
"Boot with minimal options" "root=/dev/mapper/nvme0n1p33_crypt cryptdevice=UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:nvme0n1p33_crypt ro"
- Exit
chroot
and reboot. Remember to select the new kernel in refind
.
exit
sudo reboot
Cleanup
Optional. This will remove unused boot options in refind
. I like to keep them around as a backup until the system is stable.
- Remove any leftover shared Ubuntu Grub bootloader.
# NOTE: The shared Ubuntu Grub EFI loader might be leftover from previous installations.
#sudo rm -r /boot/efi/EFI/ubuntu/
- Remove files from the unused boot partition.
# NOTE: Optionally clean up files from the Ubuntu installer.
#sudo mkdir /mnt/bootpartition
#sudo mount /dev/nvme0n1p22 /mnt/bootpartition
#sudo rm -r /mnt/bootpartition/*
Maintenance after kernel or driver updates
As Ubuntu doesn't know about refind
, kernel+driver updates require a manual copy step for vmlinuz+initrd.
- After installing updates, but before rebooting, copy the new vmlinuz+initrd from the encrypted
/boot
to the unencrypted ESP's ubuntu-instance
like above.
- If you forget to do this, and the system broke or new drivers didn't load, boot either:
- Single-user mode from
refind
by choosing custom boot options.
- The Ubuntu installer USB/DVD, and mount to temporary locations:
- The encrypted disk which contains
/boot
.
- The ESP.
- Copy the vmlinuz+initrd from your
/boot
to the ESP's ubuntu-instance
like above.
Future improvements
- If/when there are EFI file system drivers so
refind
can read encrypted LUKS partitions, investigate not keeping the kernels on the unencrypted ESP. This might greatly simplify the above setup.
- Running
ubiquity --no-bootloader
skips installing shim-signed
, so third-party DKMS modules/drivers (nvidia etcetera) require manual signing for secure boot. This can be done using kmodsign
for /lib/modules/x.y.z/updates/dkms/*.ko
after each kernel/driver update. A smoother alternative is to install shim-signed
(including parts of grub
), which does automatic signing. Perhaps there's an alternative which is less grubby?
- Figure out if kernel+driver updates can automatically trigger updating the per-instance ESP vmlinuz+initrd copy for
refind
.
- Improve temporary boot partition usage with one of:
- Configure the temporary boot partition as encrypted swap space in each of the Linux instances.
- Reusing the ESP for temporary
/boot
files. Didn't want the added risk of destroying the ESP by accidentally formatting it or similar, but might work just as well.
Inspiration
Thank you!
1 This Wayland plus Nvidia grapics driver problem caught me. It causes a black screen after the disk has been unlocked. Luckily it's easy to fix and Wayland can be restored once updated Nvidia drivers have been installed -- just remember to copy the updated kernel+initrd to your ESP.