Skip to content
bzd.gg
Go back

PPiNAS: Building a 6-Bay NAS with a Raspberry Pi 5

The pitch: a low-power, multi-drive NAS for under $150. The reality: a working setup that required patching the kernel boot configuration to work around a hardware bug in the ASM1166 SATA controller. Here’s how it went.

Hardware

ComponentModel
SBCRaspberry Pi 5 (4GB)
PCIe adapterGeekworm X1001 (M.2 → PCIe x1)
SATA controllerOLMaster 6-bay (ASM1166)
Drives1TB HD, 512GB HD, 256GB SSD

The Geekworm X1001 exposes the Pi 5’s PCIe lane through an M.2 slot, which the OLMaster enclosure uses to run the ASM1166 — a 6-port SATA controller. On paper, straightforward. In practice, the ASM1166 and the Pi 5 have a disagreement.

Architecture

RPi 5
└── Geekworm X1001 (PCIe M.2 → PCIe x1)
    └── ASM1166 SATA Controller (OLMaster 6 bays)
        ├── sda → 1TB HD     → /mnt/media-server
        ├── sdc → 256GB SSD  → /mnt/file-storage
        └── sdd → 512GB HD   → /mnt/backups

Each drive serves a distinct purpose: the 1TB spins for media, the SSD handles active file storage (fast enough for SMB transfers), and the 512GB sits on backup duty.

Problems

Boot hangs with drives connected

First boot with all drives plugged in: the Pi never came up. No output, no heartbeat — just a stuck green LED. Bisecting the problem, I disconnected all drives and the system booted fine. Plugged them back one at a time: same hang as soon as any drive was connected to the ASM1166.

Disabling PCIe at boot (dtparam=pciex1=off) confirmed the controller enumeration was the culprit. The Pi was hanging trying to initialize the ASM1166 before the OS had a chance to load.

Root cause: ASM1166 incompatibility with Pi 5’s MSI implementation

The Pi 5 PCIe controller uses a custom MSI (Message Signaled Interrupts) implementation called mip1, which allocates interrupt vectors at addresses above 4GB. The ASM1166 is a 32-bit device — it cannot address memory above the 4GB boundary, so when the kernel tries to assign MSI vectors using mip1, the chip locks up completely.

This is a known issue tracked at raspberrypi/linux#6214.

Fix

Two lines in /boot/firmware/config.txt:

dtparam=pciex1_gen=2
dtoverlay=pciex1-compat-pi5,no-mip

pciex1_gen=2 locks the PCIe link to Gen 2 speed. More importantly, no-mip disables the mip1 MSI implementation and falls back to a 32-bit-compatible path — exactly what the ASM1166 needs.

After this change, all six SATA ports enumerate cleanly and all drives show up as expected.

Reliable automount with nofail

With a multi-drive setup, a missing drive at boot (unplugged cable, spin-up delay) would stall systemd waiting for a mount that never comes. The fix is nofail in /etc/fstab:

UUID=<uuid1>  /mnt/media-server  ext4  defaults,nofail  0  2
UUID=<uuid2>  /mnt/file-storage  ext4  defaults,nofail  0  2
UUID=<uuid3>  /mnt/backups       ext4  defaults,nofail  0  2

With nofail, boot continues regardless of whether a drive is present. Missing mounts get logged but don’t block startup. Combined with UUID= instead of /dev/sdX (which shifts on every reboot), mounts are stable.

Result

The PPiNAS has been running for a few weeks now serving Jellyfin, Samba, and nightly rsync backups. Idle power draw sits around 8W with all drives spun up — reasonable for a 24/7 box.

The ASM1166 issue is the main gotcha. If you’re building a similar setup, add those two config lines before connecting any drives. It’s not obvious from any product documentation and costs a couple of hours if you hit it blind.



Previous Post
Hello, World