This post is an adapted clone of Arne Rantzen’s instructions (archived version).
1. Preliminary steps
- We start with a completely wiped HDD and a completely wiped SSD
- We boot the system we would like to install from a USB media. Make sure that we boot in UEFI mode and not in legacy BIOS mode.
- Do not proceed unless you are convinced that you booted your Ubuntu installation / testing USB system in UEFI mode (you should see an explicit entry in your startup F8 boot menu mentioning UEFI or EFI or similar).
- Once booted into Ubuntu from USB, choose “Try Ubuntu” (not “Install” for the moment)
- Open a terminal, make yourself root by issuing
sudo -i
and put the /dev path of the SSD and the HDD into some variables:
1 2 |
export SSD_POINT=/dev/sda export HDD_POINT=/dev/sdb |
1.1 Partitioning
Launch gparted from the testing system, format both drives as GPT devices (not MBR).
My general setup is as follows:
- I have a 128 GB SSD. 60 GB are held back for a later Win 11 installation, 38 GB are used to hold the core Linux system (without /var, /opt and /home), 21 GB are used for caching the most frequently accessed blocks on the HDD device and the rest is for small administrative partitions (/boot, /boot/efi, Microsoft hidden partitions etc.)
- A 2 TB HDD is completely used as a backing device for the cache, i.e. all data going to /home, /var/ and /opt essentially written to that bcache partition.
Therefore we create the following partitions using gparted:
Partition | Name | File System | Size | Remarks |
---|---|---|---|---|
sda1 | EFI System partition | FAT32 | 512 MB | tick esp and boot flags; will later be mounted as /boot/efi |
sda2 | boot | EXT4 | 1024 MB | will later be mounted as /boot |
sda3 | cache | cleared (will later be LUKS-formatted) | 21 GB | this will be our bcache device that holds most active blocks for fast access |
sda4 | system | EXT4 (but doesn’t matter) | 38 GB | will be managed both PV and VG, hold core system |
For our HDD we don’t have to do anything except writing the gpt partition table. The complete 2 TB will be taken as a backend for bcache. No need to create any partitions or format anything.
Next we set some variables in our terminal window:
1 2 3 |
export SSD_BOOT=/dev/sda2 export SSD_CACHE=/dev/sda3 export SSD_SYSTEM=/dev/sda4 |
1.2 Setting up caching with bcache
Still in our terminal as root, issue the following commands to install bcache-tools and wipe the file systems relating that later make up our virtual hybrid drive:
1 2 3 4 |
apt-get update apt-get install bcache-tools wipefs -a $SSD_CACHE wipefs -a $HDD_POINT |
Then set up the cache partition (-C) of the SSD and the backing device (-B), the HDD partition and tweak bcache to use the writeback caching mode. Finally, add the resulting mapped partition of the cache on the SSD and the data partition on the HDD to a new variable.
1 2 3 |
make-bcache -C $SSD_CACHE -B $HDD_POINT echo writeback > /sys/block/bcache0/bcache/cache_mode export BCACHE=/dev/bcache0 |
1.3 Setting up LUKS encryption
Our whole file system of the HDD together with the cache on the SSD is now mapped to $BCACHE
(/dev/bcache0
) and the system partition still at $SSD_SYSTEM
. Now we have to encrypt it. To setup LUKS we first have to create and format our encrypted devices. You will be asked for a password and confirm each time. Choose identical passwords as we want to have a master password to unlock the complete system at the startup.
1 2 |
cryptsetup luksFormat $SSD_SYSTEM cryptsetup luksFormat $BCACHE |
Next we have to open and unlock the container in order to proceed with further installations. You will be asked for the master encrytpion password that you in the previous step (again twice as you unlock two LUKS containers).
When opening a container, you can assign them a name, which will be cRoot
and cCache
respectively. These will be the names under which the containers can be accessed in the device mapper under /dev/mapper/
.
1 2 |
cryptsetup luksOpen $SSD_SYSTEM cRoot cryptsetup luksOpen $BCACHE cCache |
Next we export the device mapper paths of our opened containers:
1 2 |
export CROOT=/dev/mapper/cRoot export CCACHE=/dev/mapper/cCache |
1.4 Setting up Logical Volume Management
Initialization of physical volumes
We will now set up the logical volume manager. What do we want LVM to manage? First of all, we have a system partition on the sda4
on the SSD which LUKS has already mapped to /dev/mapper/cRoot
(or $CROOT
) and which will hold the core system files (basically everything that is ‘non-data’).
Secondly, we have our hybrid drive which we combined from the sda3
SSD partition and the complete sdb
HDD into a virtual hybrid drive ($BCACHE
or /dev/bcache0)
. This was encrypted by LUKS and is now accessible as ($CCACHE
or /dev/mapper/cCache
)
So we first tell LVM what physical volumes we have. Note that ‘physical’ in the language of LVM does not require a volume to be a separate tangible unit such as a hard drive. It might be a complete drive, but it can be a single partition or – as in our case – a mapped device.
1 2 |
pvcreate $CROOT pvcreate $CCACHE |
This initializes the hybrid drive and the SSD system partition for logical volume management. Our next step is to
Creation of volume groups
The next level up from the physical volume (PV) is a volume group (VG). Each PV can (but not necessarily needs to) be a member of exactly one VG and a VG can hold an arbitrary amount of PVs.
We create two logical volume groups: One data
group that will later hold everything that goes into /home
, /var
and /opt
. And one system
group that holds everything except these three. The vgcreate command allows us to create a group and at the same time determine what PVs should got into the group:
1 2 |
vgcreate system $CROOT vgcreate data $CCACHE |
Creation of logical volumes
In our final step, we have to create logical volumes which we will use to put mount points on later in the system installation.
1 2 3 4 |
lvcreate -n root -l 100%PVS system lvcreate -n home -L 650G data lvcreate -n var -L 30G data lvcreate -n opt -L 20G data |
2. Installation of Ubuntu
We now have everything in place to install Ubuntu. Still do not close the terminal window. With the the terminal window remaining open, launch Install Ubuntu from the desktop of your USB instance.
Fill in the usual chit-chat about language, keyboard etc. until you are asked about what Installation Type you desire. Pick Something else.
After this you will be shown a dialog similar to the gparted window you saw before. Don’t let yourself be confused by the fact that the same installation destination might be listed multiple times. Assign the destination devices for installation as in the following table:
Device path | Use as | Format | Mount Point |
---|---|---|---|
/dev/sda1 | FAT32 ? | not sure | /boot/efi |
/dev/sda2 | ext4 | True | /boot |
/dev/mapper/system-root | ext4 | True | / |
/dev/mapper/data-home | ext4 | True | /home |
/dev/mapper/data-var | ext4 | True | /var |
/dev/mapper/data-opt | ext4 | True | /opt |
Finally choose /dev/sda
as the device for the boot loader installation and click Install Now. Complete any remaining chit-chat about the user name, the machine name and so on.
When the graphical installer tells you that the installation has been completed, and offers you to reboot your machine into the installed system do not choose to reboot! Choose Continue Testing.
3. Post Install Steps
Now that the installation is over, we have to make sure that our system is able to use the cache and understand the encryption. Remember that so far only our testing system is really aware that
- we have combined an SSD partition and a HDD into a hybrid drive using bcache
- we have encrypted that hybrid drive and a system partition using LUKS
- we have created physical volumes, volume groups and logical volumes inside the LUKS
All this information will be gone once we shut down the testing installation. Therefore we have to mount the freshly installed system to install the caching kernel and set up encryption.
Go back to the terminal window and mount the system we just installed inside the testing system:
1 2 3 4 5 6 |
mount /dev/mapper/system-root /mnt mount $SSD_BOOT /mnt/boot mount -o bind /sys /mnt/sys mount -o bind /run /mnt/run mount -o bind /proc /mnt/proc mount -o bind /dev /mnt/dev |
Now we change to be root in the installed system we just mounted:
1 |
chroot /mnt |
So far the installed system has not even bcache-tools
installed (only our USB live system has). But as we just have become root in the installed system that we have mounted under /mnt
inside our live system, we can now install bcache-tools
:
1 2 |
apt update apt install bcache-tools |
To tell the installed system about our LUKS encrypted partitions, we have to set up /etc/crypttab:
1 2 3 |
echo "cRoot UUID=`blkid -o value $SSD_SYSTEM | head -1` none luks" > /etc/crypttab echo "cCache UUID=`blkid -o value $BCACHE | head -1` none luks" >> /etc/crypttab update-initramfs -uk all |
I am told the last command is super important, as without updating initramfs, the system will ignore the settings we just put into the crypttab file.
We almost there. What remains are some final cleanups:
- exit chroot,
- sync the system state (not sure what this is good for, but it can’t do harm either),
- unmount the installed system partitions
- deactivate the volume groups
- close the LUKS partition
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
exit sync #unmount the system umount /mnt/sys umount /mnt/run umount /mnt/proc umount /mnt/dev umount /mnt/boot umount /mnt #deactivate volume groups vgchange -an /dev/mapper/system vgchange -an /dev/mapper/data # close LUKS containers cryptsetup luksClose cCache cryptsetup luksClose cRoot sync reboot |
4. Installing Windows
Once we have established that our Ubuntu installation works as intended, we can care about the Windows installation.
4.1 Preparing the installation media
To prepare the USB key that holds the installation media I recommend the Rufus USB creation tool. This is particularly useful as it allows you to alter the installation image such that:
- you can bypass the dismal Win 11 ‘compatibility’ check which will even reject machines with an advanced i7 processor if it is not the latest generation
- you can thwart Microsoft’s desire to know more about you by
- bypassing the need to create an online account
- directly suppress data collection
Download the desired Windows 10 or 11 installation ISO from Microsoft. In my case it’s the Win 11 64bit English US version.
Let Rufus put a customize installation image onto your USB stick.
4.2 Installing Windows
In my case I need a native Windows installation for a one and only one single purpose: running Autodesk Fusion 360. There is no Linux version of this software available and it draws so heavily on machine ressources that it is not a good idea to run it inside a Windows virtual machine under Ubuntu.
Therefore I will install Win 11 on the remaining 60-something GB of SSD space, which is just enough to hold Windows and install Fusion 360 which will then have the undivided attention of my Core i7 processor, 24 Gigs of RAM and a fast SSD device. (Still Autodesk recommends replacing my 10-year-old AMD Radeon Dualhead graphics adapter, which was top of the shop when I bought it but now seems to be incredibly outdated…)
Now power down your machine, pop in the USB stick, power it up again, hit F8 to open the boot menu and choose the UEFI USB installation media that should show up.
There is no rocket science in the installation itself. I have used the installation notes at itsfoss.com as a rough guideline. It worked for me without the Ventoy thing and as we already have left 60 GB plus/minus small change on the SSD when installing Linux, there is no need to resize partitions either.
The only important moment is when the installer asks you Which type of installation do you want? As before the only correct answer is Custom Install.
When next asked Where do you want to install Windows? make sure to choose Drive 0 Unallocated Space (approx. 60 GB) at the end of the list. This will be the niche we left for Windows on the SSD. Click Next and the installation should start.
If that should happen to you, simply create or format the partition as advised by the Windows installer. Just make sure you don’t do any damage to your existing (Ubtuntu) partitions.
The installer will restart your machine several times along the installation. After everything is ready, you will find out that your machine will boot straight into Windows. Don’t panic. Your Ubuntu installation is not gone. You just have to rearrange the boot order in your BIOS again so that it boots into Ubuntu (UEFI) by default.
Itsfoss recommends to run sudo update-grub
to have windows listed as a boot option. In my case however, I really rarely use Windows (see above). So I prefer that the default behavior of my workstation is to boot into Ubuntu unless explicitly told otherwise. For the few moments when I want to boot Windows, I hit F8 after powering up my machine an hit F8 to get the complete list of UEFI boot options and choose Windows from there.