Installing Debian on F2FS Rootfs With Deboostrap and Systemd-Boot
I recently got a new NVME drive. My plan was to create a fresh Debian install on an F2FS root partition with compression for maximum performance. As it turns out, this is not entirely trivil to accomplish.
For one, the Debian installer does not support F2FS (here is my attempt to add it from 2021).
And even if it did, grub does not support F2FS with the
extra_attr flag that is required for compression support (at least as of grub 2.06).
Luckily, we can install Debian anyway with all these these shiny new features when we go the manual road with
debootstrap and using
systemd-boot as bootloader.
We can break down the process into several steps:
- Creating the partition table
- Creating and mounting the root partition
- Bootstrapping with
- Chrooting into the system
- Configure the base system
- Define static file system information
- Installing the kernel and bootloader
- Finishing touches
Warning: Playing around with partitions can easily result in data if you mess up! Make sure to double check your commands and create a data backup if you don’t feel confident about the process.
Creating the partition partble
The first step is to create the GPT partition table on the new drive. There are several tools to do this, I recommend the ArchWiki page on this topic for details. For simplicity I just went with the GParted since it has an easy GUI, but feel free to use any other tool. The layout should look like this:
Type │ Partition │ Suggested size ───────────┼────────────────┼─────────────── EFI │ /dev/nvme0n1p1 │ 512MiB Linux swap │ /dev/nvme0n1p2 │ 1GiB Linux fs │ /dev/nvme0n1p3 │ remainder
- The disk names are just an example and have to be adjusted for your system.
- Don’t set disk labels, they don’t appear on the new install anyway and some UEFIs might not like it on your boot partition.
- The size of the EFI partition can be smaller, in practive it’s unlikely that you need more than 300 MiB. However some UEFIs might be buggy and if you ever want to install an additional kernel or something like memtest86+ you will be happy to have the extra space.
- The swap partition can be omitted, it is not strictly needed. If you need more swap for some reason you can also add more using a swap file later (see ArchWiki page). If you know you want to use suspend-to-RAM, you want to increase the size to something more than the size of your memory.
- If you used GParted, create the EFI partition as FAT32 and set the
espflag. For the root partition use ext4 or F2FS if available.
Creating and mounting the root partition
To create the root partition, we need to install the
sudo apt install f2fs-tools
Now we can create the file system with the correct flags:
mkfs.f2fs -O extra_attr,inode_checksum,sb_checksum,compression,encrypt /dev/nvme0n1p3
For details on the flags visit the ArchWiki page.
Next, we need to mount the partition with the correct flags. First, create a working directory:
mkdir bootstrap cd bootstrap mkdir root export DFS=$(pwd)/root
Then we can mount the partition:
sudo mount -o compress_algorithm=zstd:6,compress_chksum,gc_merge,lazytime /dev/nvme0n1p3 $DFS
Again, for details on the mount options visit the above mentioned ArchWiki page.
First we need to install the
sudo apt install debootstrap
Now we can do the bootstrapping:
debootstrap --arch=amd64 --components=main,contrib,non-free,non-free-firmware unstable $DFS http://deb.debian.org/debian
--archsets the CPU architecture (see Debian Wiki).
--componentssets the archive components, if you don’t want non-free pacakges you might want to remove some entries here.
unstableis the Debian release, you might want to change that to
$DFSpoints to the mounting point of the root partition.
http://deb.debian.org/debianis the Debian mirror, you might want to set that to
http://ftp.de.debian.org/debianor similar if you have a fast mirror in you area.
Chrooting into the system
Before we can chroot into the newly created system, we need to prepare and mount virtual kernel file systems. First create the directories:
sudo mkdir -p $DFS/dev $DFS/dev/pts $DFS/proc $DFS/sys $DFS/run $DFS/sys/firmware/efi/efivars $DFS/boot/efi
Then bind-mount the directories from your system to the mount point of the new system:
sudo mount -v -B /dev $DFS/dev sudo mount -v -B /dev/pts $DFS/dev/pts sudo mount -v -B /proc $DFS/proc sudo mount -v -B /sys $DFS/sys sudo mount -v -B /run $DFS/run sudo mount -v -B /sys/firmware/efi/efivars $DFS/sys/firmware/efi/efivars
As a last step, we need to mount the EFI partition:
sudo mount -v /dev/nvme0n1p1 $DFS/boot/efi
Now we can chroot into new system:
sudo chroot $DFS /bin/bash
Configure the base system
The first step in the chroot is setting the locales. We need this since we might leak the locales from our base system into the chroot and if this happens we get a lot of annoying warnings.
export LC_ALL=C.UTF-8 LANG=C.UTF-8 apt install locales console-setup
Set your locales:
Set your keyboard layout:
Set your timezone:
Now you have a fully functional Debian chroot! However, it is not bootable yet, so let’s fix that.
Define static file system information
The first step is to make sure the system mounts all partitions on startup with the correct mount flags.
This is done in
/etc/fstab (see ArchWiki page).
Open the file and change its content to:
# file system mount point type options dump pass # NVME efi partition UUID=XXXX-XXXX /boot/efi vfat umask=0077 0 0 # NVME swap UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX none swap sw 0 0 # NVME main partition UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX / f2fs compress_algorithm=zstd:6,compress_chksum,gc_merge,lazytime 0 1
You need to fill in the UUIDs for the partitions. You can use
ls -lAph /dev/disk/by-uuid/
to match the UUIDs to the more readable disk name under
Installing the kernel and bootloader
First install the
apt install systemd-boot efibootmgr
Now we can install the bootloader:
bootctl install --path=/boot/efi
You can verify the procedure worked with
The next step is to install the kernel, you can find a fitting image with:
apt search linux-image-*
In my case:
apt install linux-image-amd64
After the installation of the kernel, apt will add an entry for
systemd-boot automatically. Neat!
However, since we are in a chroot the current settings are not bootable.
The first reason is the boot partition, which will likely be the one from your current system.
To change that, navigate to
/boot/efi/loader/entries, it should contain one config file.
When you open this file, it should look something like this:
title Debian GNU/Linux bookworm/sid version 6.1.0-3-amd64 machine-id 2967cafb6420ce7a2b99030163e2ee6a sort-key debian options root=PARTUUID=f81d4fae-7dec-11d0-a765-00a0c91e6bf6 ro systemd.machine_id=2967cafb6420ce7a2b99030163e2ee6a linux /2967cafb6420ce7a2b99030163e2ee6a/6.1.0-3-amd64/linux initrd /2967cafb6420ce7a2b99030163e2ee6a/6.1.0-3-amd64/initrd.img-6.1.0-3-amd64
The PARTUUID needs to point to the partition equivalent to
/dev/nvme0n1p3 on your system. You can use
ls -lAph /dev/disk/by-partuuid/
to match the PARTUUIDs to the more readable disk name under
The second problem is the
ro flag in
options which tell the kernel to boot in read-only mode.
The default is
rw, so you can just remove the
Once this is fixed, the new system should be bootable. You can change the boot order with:
However, before we reboot we might add well add a user and install some basic software.
Add a user:
useradd -m -G sudo -s /usr/bin/bash -c 'Full Name' username
Debian provides a TUI to install Desktop Environment. To open it, run:
Now you can finally reboot into your new system:
Resources for further reading
Thanks for reading!