Updated Guide: Encrypted Root Partition on uConsole Trixie

Full Disk Encryption for uConsole CM5 (Debian Trixie)

This guide encrypts the uConsole completely, including root! Thanks a ton to mclbin’s previous guide on this forum, I could not have written this without their excellent work.

What you need: A uConsole CM5 (not tested with CM4 or others), a second Linux computer, a card reader, and about 30 minutes.


1. Flash Image & Prepare Storage

Download Rex’s Debian Trixie image for the uConsole CM5: [Trixie 6.12.y for the uConsole and DevTerm]

Flash it to your SD card / eMMC using your tool of choice (I like Fedora Media Writer).

Before booting, open the flashed media in GParted (or similar). The root filesystem on the fresh image is small, and we need some room to install updates before encrypting.

In GParted:

  • Create a new ~5 GiB partition directly after the root partition (p2)
  • Create another partition filling the remaining empty space after that
  • Delete the 5 GiB partition you just created

This leaves a ~5 GiB gap of unallocated space right after root. On first boot, the system expands into the empty space, and the partition at the end blocks it from eating the whole card so we don’t have to wait three hours when we flash the FS back later.

Apply changes, eject, insert into uConsole, and boot.

Once booted, update and reboot:

sudo apt update && sudo apt full-upgrade -y
sudo reboot

2. Install Packages

sudo nano etc/initramfs-tools/initramfs.conf

Find the line with modules=dep and change it to modules=most.

Then install prerequisite packages.

sudo apt install busybox cryptsetup cryptsetup-initramfs initramfs-tools

3. Add Kernel Modules to Initramfs

Append the following to /etc/initramfs-tools/modules:

# --- Crypto modules (AES-XTS + SHA256, ARM hardware-accelerated) ---
aes_arm64
aes_ce_blk
aes_ce_cipher
sha256_arm64
sha256_ce
dm-crypt
xts

# --- Display modules (needed so the password prompt shows on the uConsole screen) ---
drm
drm_kms_helper
drm_shmem_helper
drm_dma_helper
drm_ttm_helper
drm_display_helper
drm_panel_orientation_quirks
ttm
cec
backlight
ocp8178_bl
panel-cwu50
vc4
v3d
drm-rp1-dsi

The display modules need to be included so we can see the password prompt on boot.


4. Create Display Init Script

Create the file:

sudo nano /etc/initramfs-tools/scripts/init-top/display

Contents:

#!/bin/sh
PREREQ=""
prereqs() { echo "$PREREQ"; }
case $1 in prereqs) prereqs; exit 0;; esac

# Load display stack. Order matters.
modprobe drm
modprobe drm_kms_helper
modprobe backlight
modprobe ocp8178_bl         # uConsole backlight controller
modprobe panel-cwu50        # uConsole LCD panel driver
modprobe vc4                # Broadcom VideoCore GPU
modprobe v3d                # Broadcom V3D 3D engine

sleep 1                     # Give the panel time to initialize

modprobe drm-rp1-dsi        # RP1 DSI bridge (connects SoC to panel)
modprobe fbcon              # Framebuffer console (renders text on screen)

Make it executable:

sudo chmod +x /etc/initramfs-tools/scripts/init-top/display

The sleep 1 is critical, don’t remove it!! Without it, drm-rp1-dsi tries to bind before the panel is ready and you get a blank screen.


5. Create Kernel Postinst Hook

Create the file:

sudo nano /etc/kernel/postinst.d/initramfs-rebuild

Contents:

#!/bin/sh -e

version="$1"

# Only rebuild for the currently running kernel
[ "$version" = "$(uname -r)" ] || exit 0

# Back up existing initramfs before overwriting
[ -e /boot/firmware/initramfs_2712 ] && \
    cp /boot/firmware/initramfs_2712 /boot/firmware/initramfs_2712.bak

update-initramfs -c -k "$version"
mkinitramfs -o /boot/firmware/initramfs_2712 "$version"

Make it executable:

sudo chmod +x /etc/kernel/postinst.d/initramfs-rebuild

6. Build Initramfs

sudo update-initramfs -c -k "$(uname -r)"
sudo mkinitramfs -o /boot/firmware/initramfs_2712 "$(uname -r)"

7. Configure Boot

config.txt

Append under [all] in /boot/firmware/config.txt:

auto_initramfs=1

cmdline.txt

Replace the contents of /boot/firmware/cmdline.txt with:

console=serial0,115200 console=tty1 root=/dev/mapper/sdcard rootfstype=ext4 fsck.repair=yes rootwait fbcon=rotate:1 psi=1 quiet loglevel=3

8. Configure fstab & crypttab

/etc/fstab

Find the line that mounts / and replace it with:

/dev/mapper/sdcard  /  ext4  defaults,noatime  0  1

/etc/crypttab

Append this line:

sdcard  /dev/mmcblk0p2  none  luks

9. Backup & Encrypt (On Another Linux Machine)

Power off the uConsole. Move your storage media to another Linux computer.

Make sure you install: partclone, zstd, cryptsetup, parted, e2fsprogs and sfdisk.

Your device is assumed to be /dev/mmcblk0 below. Don’t forget to adjust each command it if it shows up as /dev/sdX or something.

Back up

# Save the partition layout
sudo sfdisk -d /dev/mmcblk0 > uconsole-partitions.txt

# Clone both partitions with compression
sudo partclone.fat32 -c -s /dev/mmcblk0p1 | zstd -T0 > uconsole-boot.img.zst
sudo partclone.ext4 -c -s /dev/mmcblk0p2 | zstd -T0 > uconsole-root.img.zst

Encrypt and restore

Delete the big partition at the end of your disk you made to fill up space.

# Resize partition to fill available space
sudo parted /dev/mmcblk0 resizepart 2 100%

# Format as LUKS2 with AES-XTS-256 and Argon2id KDF
sudo cryptsetup luksFormat \
    --type luks2 \
    --cipher aes-xts-plain64 \
    --hash sha256 \
    --key-size 512 \
    --pbkdf argon2id \
    --iter-time 5000 \
    /dev/mmcblk0p2

# Open the new LUKS volume
sudo cryptsetup luksOpen /dev/mmcblk0p2 sdcard

# Restore the root filesystem into the encrypted container
zstd -d -c uconsole-root.img.zst | sudo partclone.ext4 -r -C -o /dev/mapper/sdcard

# Expand the filesystem to fill the LUKS volume
sudo e2fsck -f /dev/mapper/sdcard
sudo resize2fs /dev/mapper/sdcard

sudo cryptsetup luksClose sdcard

Move the storage back to the uConsole and boot it up.


10. First Boot and Finalize

The first boot will take a while, then drop you into an initramfs shell. This is expected!

You just have to login manually:

cryptsetup luksOpen /dev/mmcblk0p2 sdcard

Then continue the boot by exiting:

exit

You should now boot into your encrypted system!

Rebuild the initramfs one final time so the LUKS prompt triggers automatically on future boots:

sudo update-initramfs -c -k "$(uname -r)"
sudo mkinitramfs -o /boot/firmware/initramfs_2712 "$(uname -r)"

Reboot. The password prompt should now appear on the uConsole screen at boot.

Tadaa!

5 Likes

The guides are piling up, not bad!

I think you have some unnecessary steps in there (no need to manually incluude kernel modules). But what you have is an automated initramfs hook!

I’m currently on a trip, but when I’m back, I will definitely integrate than in my guide. If you’re interested, you can have a look too. Maybe we can throw together the “definite” root encryption guide for the uConsole

1 Like

Thanks for your input!! I wish I could still edit the post, I would make some more changes (like eliminating the backup step for the initramfs hook). You’re probably right that I don’t need to include most of the kernel modules I mention explicitly, but some are needed (I think) like the uConsole stuff. Edit: just saw your guide does not specify those at all! Seems like I can eliminate the entire step?

Happy you liked the guide :slight_smile:

1 Like

Just discovered a mistake. For step 5, the postinst hook script should be:

#!/bin/sh -e

version="$1"
update-initramfs -c -k "$version"
mkinitramfs -o /boot/firmware/initramfs_2712 "$version"

The logic was wrong for the version check, just rebuild the initramfs every time instead of checking.

1 Like

Another mistake, -c should be -u (to update instead of create).

#!/bin/sh -e

version="$1"
update-initramfs -u -k "$version"
mkinitramfs -o /boot/firmware/initramfs_2712 "$version"

There can never really be a definite guide for FDE on the uConsole because there are multiple subtly different ways to achieve it, each with their own pros and cons, like using dm-crypt over crypttab. The best way to go about it is probably less about listing a bunch of commands that may or may not work depending on underlying operating system, and more explaining what each command does, why it might not be useful, and how to fix the problems it may cause.

Even sudo may not be on a uConsole’s operating system. An old custom was to write root commands with a hash prompt (#) and user commands with a dollar prompt ($).

2 Likes

I registered on the forum just to say thank you. Your guide worked really well for me, but I ran into a few issues along the way, so I’m leaving some notes here in case they help someone else.

  1. If you’ve already installed everything on your system and skipped Step 1, don’t worry too much. You can still continue by shrinking your disk right before Step 9 and leaving the rest of the disk unallocated. For example, if you’ve already used 10 GB of your SD card space, resize it to something close to the currently used size.
e2fsck -f /dev/mmcblk0p2
resize2fs /dev/mmcblk0p2 16G

Once that’s done, use GParted or Parted to leave the rest of the disk space unallocated.

parted /dev/mmcblk0
(parted) unit GiB
(parted) print
(parted) resizepart 2 16
(parted) mkpart primary ext4 16 100%
(parted) quit

You’ll be reclaiming disk space in Step 9, so there shouldn’t be any issues doing this right before Step 9.

  1. (To the author) I think you should update the main post to reflect the latest information. I had to jump back and forth between documents to cross-check things. I changed update-initramfs later, and something broke completely, so I had to start over from scratch. I still don’t know what the main cause was.

  2. I still don’t know why the disk got corrupted during the fix, so for anyone who really doesn’t want to risk losing all their data, make sure to back up your LUKS headers in case something goes wrong. I think SD cards and the uConsole may be more prone to corruption than a typical desktop Linux setup, so I’d personally recommend backing up your LUKS header anyway.

cryptsetup luksHeaderBackup /dev/mmcblk0p2 --header-backup-file ./luks-header.img
  1. For Step 8, I did blkid /dev/mmcblk0p2 and used the PARTUUID in /etc/crypttab instead. You can get the PARTUUID from blkid /dev/mmcblk0p2 and then edit /etc/crypttab like this:
sdcard PARTUUID="[partial_uuid]-2" none luks

@bjornVallem: This is a valid request. Would you be so kind as to edit and update your original post so that the instructions remain clear and easy to follow? That way, your instructions will continue to be a valuable resource for anyone interested. :+1:

Thank you so much for your enthusiasm, I love that my guide made a difference for you!! I would have been editing the guide instead of commenting, but you can’t edit posts on this forum after like 4 (?) hours or so. I’ve been thinking to make a new post but as one commenter rightly mentioned, it would have to be updated as well. Not sure what to do about that, maybe a link to a github txt file? But still, that would not be very forum friendly… Maybe you know a way? @Codiator

1 Like

That’s odd. Are you sure? I can edit posts that are several months old.

You should be able to!

I have updated my guide several times and I also plan to integrate your initramfs hook as soon as I have time to.