Skip to main content
The Exaviz Cruiser exposes PCIe x1, an M.2 Key M slot for NVMe, and a SATA port via an ASM1061 bridge. All three interfaces share the CM5’s single PCIe lane and are enabled through config.txt parameters.

Enabling PCIe

Add the following line to /boot/efi/config.txt to activate the PCIe x1 interface:
/boot/efi/config.txt
# CM5 Exaviz carrier — PCIe/SATA will enumerate after UEFI handoff
dtparam=pciex1=on
PCIe is disabled by default on the CM5. Without dtparam=pciex1=on, neither the M.2 NVMe slot nor the SATA bridge will be visible to the kernel.

Enabling NVMe

With PCIe active, enable the NVMe driver overlay:
/boot/efi/config.txt
dtparam=pciex1=on
dtparam=nvme=on
After the next boot, verify enumeration:
lsblk -d -o NAME,MODEL,SIZE,TRAN | grep nvme
Expected output:
nvme0n1   Samsung SSD 980 500G   465.8G   nvme

SATA enumeration via ASM1061

The Exaviz Cruiser routes SATA through an ASM1061 PCIe-to-SATA bridge. No additional config.txt parameters are required beyond dtparam=pciex1=on. The kernel’s ahci driver handles the bridge automatically and the disk appears as /dev/sdX.
lsblk -d -o NAME,MODEL,SIZE,TRAN | grep sata
sda   WD Red Plus 2TB   1.8T   sata
If the SATA disk is not visible after enabling PCIe, check dmesg | grep -i asm106 to confirm the bridge was detected. A missing bridge usually indicates a PCIe link training failure — check that LnkSta reports the expected speed with lspci -vvv.

Adding NVMe to the btrfs pool

The CM5 image uses btrfs with a @ root subvolume on eMMC. After the NVMe device is confirmed present, add it to the pool and mirror the data:
1

Add the NVMe device

btrfs device add /dev/nvme0n1 /
2

Balance to RAID 1

btrfs balance start -dconvert=raid1 -mconvert=raid1 /
This converts both data and metadata to RAID 1 across eMMC and NVMe. The balance operation runs in the background and can be monitored with:
btrfs balance status /
3

Verify the pool

btrfs filesystem show /
Both devices should appear with their sizes and used space.
Enable fstrim.timer to periodically TRIM both the eMMC and NVMe for long-term health:
systemctl enable --now fstrim.timer

Frigate recordings and Docker layout

Frigate NVR writes large sequential recording files that do not benefit from btrfs copy-on-write. Two dedicated subvolumes with nodatacow are used to avoid performance penalties.

Btrfs subvolumes

Create the subvolumes during initial image setup (or post-boot on an existing pool):
btrfs subvolume create /mnt/@frigate
btrfs subvolume create /mnt/@docker

fstab entries

/etc/fstab
# Frigate recordings — nodatacow for large sequential writes
UUID=<ROOT_UUID>  /media/frigate   btrfs  compress=zstd,space_cache=v2,noatime,subvol=@frigate,nodatacow  0  0

# Docker layers — nodatacow improves layer extraction performance
UUID=<ROOT_UUID>  /var/lib/docker  btrfs  compress=zstd,space_cache=v2,noatime,subvol=@docker,nodatacow   0  0
nodatacow disables checksumming on those subvolumes. This is intentional for Frigate and Docker workloads, but means data corruption will not be detected by btrfs scrub. Back up critical data elsewhere.

Frigate recordings path

Frigate expects recordings at /media/frigate/recordings. With the @frigate subvolume mounted at /media/frigate, no additional configuration is needed in Frigate’s config file. The Samba share for snapshot browsing is configured at /media/frigate/snapshots. The Frigate container definition (from docker-compose.yml) mounts the path directly:
docker-compose.yml
frigate:
  image: ghcr.io/blakeblackshear/frigate:stable
  volumes:
    - /media/frigate:/media/frigate
  devices:
    - /dev/axelera0:/dev/axelera0   # Metis AIPU
    - /dev/dri:/dev/dri             # VC4 GPU for decode assist

SMART health monitoring

Install smartmontools for SATA disks and nvme-cli for NVMe devices. Both are listed in the stack packages:
pacman -S smartmontools nvme-cli

SATA disk health

# One-time short self-test
smartctl -t short /dev/sda

# Check results
smartctl -a /dev/sda | grep -E "SMART overall|Reallocated|Pending|Uncorrectable"

NVMe health

# NVMe SMART log
nvme smart-log /dev/nvme0n1

# Critical warnings field — 0x00 means healthy
nvme smart-log /dev/nvme0n1 | grep critical_warning
smartctl -a /dev/sda
Enable periodic SMART polling with smartd. Add /etc/smartd.conf entries for each device and enable the daemon:
systemctl enable --now smartd

Build docs developers (and LLMs) love