← All posts
Jun 24, 2026

PPiNAS: 6-Bay NAS on a Raspberry Pi 5, and the ASM1166 Boot Hang

TL;DR: The Pi 5’s PCIe controller uses a proprietary MSI implementation (mip1) that allocates interrupt vectors at addresses above 4 GB; the ASM1166 is a 32-bit device and cannot address those vectors, so with drives attached the controller locks up silently during PCIe enumeration — no kernel output, no error logged, just a system that never comes up. Fixed with two lines in /boot/firmware/config.txt: dtoverlay=pciex1-compat-pi5,no-mip falls back to a 32-bit-compatible interrupt path, and dtparam=pciex1_gen=2 locks the link to Gen 2 to prevent a separate class of enumeration failures through the X1001 adapter.

The Pi 5’s native PCIe lane is genuinely useful for NAS builds — no USB, dedicated bandwidth per drive. The catch is that several common SATA controllers, including the ASM1166, are 32-bit devices that cannot work with the Pi 5’s default MSI implementation. This post covers the hardware stack, the silent boot hang it produced, the root cause in the Pi 5’s interrupt subsystem, and the config change that resolves it.

The Pi 5 booted fine. I connected the drives. Nothing — no UART output, no heartbeat LED pattern, the green LED solid while the system never came up. The hang produced no log and gave no indication of where in the boot sequence it had occurred. That silence is the whole problem: a PCIe enumeration failure at this layer produces nothing a user can search for.

This post is for anyone running a Raspberry Pi 5 with a PCIe SATA controller and hitting an identical blank boot. You should already be comfortable editing /boot/firmware/config.txt and reading dmesg output. The root cause is in the Pi 5’s MSI implementation, not in the drives, the controller firmware, or the cable.

Table of Contents

Open Table of Contents

Hardware

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

The X1001 converts the Pi 5’s FPC PCIe connector to an M.2 slot. The OLMaster enclosure uses that slot to expose the ASM1166 — a 6-port SATA controller from ASMedia.

Layout

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

The 1 TB spins for Jellyfin media. The SSD handles active file storage — fast enough for Samba transfers. The 512 GB runs nightly rsync backups. No RAID.

PCIe enumeration stalls silently with drives attached — no output, no error

First boot with drives connected: nothing. Green LED on, no UART output, no heartbeat. The system never came up.

I pulled drives one at a time. With no drives attached, the Pi booted fine. With any drive connected to the ASM1166, it hung before the kernel could output anything. Leaving the controller in the PCIe slot but disconnecting all SATA cables — it booted. The hang was happening during PCIe enumeration of the ASM1166 with drives attached.

# With no drives: controller shows up normally
lspci -vvv
# 0000:01:00.0 SATA controller: ASMedia Technology Inc. ASM1166 Serial ATA Controller (rev 02)

With drives, the system never reached a point where lspci could run.

Why the ASM1166 locks up: 32-bit devices can’t reach mip1’s interrupt vectors

The Pi 5 PCIe controller uses a proprietary MSI (Message Signaled Interrupts) implementation called mip1. It allocates interrupt vectors at addresses above 4 GB. The ASM1166 is a 32-bit device — it cannot address memory above that boundary. When the kernel tries to assign MSI vectors using mip1, the controller locks up. No error is raised, no log is written. The bus stalls silently.

This is tracked at raspberrypi/linux#6214. Multiple SATA and NVMe controllers hit the same issue for the same reason.

Two lines in config.txt restore normal enumeration

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

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

no-mip disables the mip1 MSI implementation and falls back to a 32-bit-compatible interrupt path. That’s the fix. The ASM1166 can now be assigned interrupt vectors it can actually reach, and enumeration completes normally.

pciex1_gen=2 locks the link to Gen 2. The ASM1166 through the X1001 doesn’t negotiate Gen 3 reliably, so this prevents a separate class of enumeration failures.

After these two lines:

[    3.241] ata1: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
[    3.251] ata2: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
[    3.261] ata3: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
[    3.271] ata4: SATA link down (SStatus 0 SControl 300)
[    3.281] ata5: SATA link down (SStatus 0 SControl 300)
[    3.291] ata6: SATA link down (SStatus 0 SControl 300)

Three ports with drives, three empty. All disks visible.

SATA enumeration order is non-deterministic — /dev/sdX paths will betray you

SATA enumeration order is not guaranteed. It depends on link-up timing, which varies with drive spin-up speed and controller state. A disk that was sdb on the last boot can be sdd on the next. Using device paths in fstab will mount the wrong filesystem at best, and corrupt data at worst.

blkid /dev/sda
# /dev/sda: UUID="a1b2c3d4-..." TYPE="ext4"
# /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

nofail tells systemd not to block boot if a mount fails. Without it, a missing or slow-to-spin drive causes a 90-second timeout followed by emergency mode — which matters when you’re rebooting the machine remotely.

Several weeks of operation: power draw, spindown, and one firm caveat

Idle draw with all three drives spun up: ~8 W. With HDDs in spindown via hdparm -S: ~5 W.

The setup has been running for several weeks with Jellyfin, Samba, and nightly rsync without issues. One caveat: don’t hot-plug drives. With the no-mip workaround active, hot-plug doesn’t crash the system, but enumeration becomes inconsistent.

If you’re building the same setup, add the two config.txt lines before connecting any drives. The boot hang produces no logs and is not obvious to diagnose from first principles.

Where this fix doesn’t apply and what it doesn’t solve

The no-mip workaround is necessary because the Pi 5’s mip1 implementation allocates interrupt vectors outside the 32-bit address space. Any 32-bit PCIe device will hit this, not only the ASM1166. If you swap in a different SATA controller and see the same silent hang, check the device’s address width with lspci -vvv — look for DevCap: ... 32-bit in the capabilities list. If it’s there, the same fix applies.

What this does not fix: the Pi 5 is still a single-lane PCIe Gen 2 path after applying pciex1_gen=2. Saturating all six SATA ports simultaneously will expose that bottleneck. For media streaming and rsync-based backups on three drives it’s not a problem in practice — sequential reads from a single HDD top out well below PCIe Gen 2 throughput. A workload writing to multiple drives concurrently has a ceiling here.

Hot-plug remains unreliable with no-mip active. If you need to swap drives without rebooting, this setup is the wrong choice. The workaround trades hot-plug capability for stable enumeration at boot — the two don’t coexist cleanly on current Pi 5 firmware.

References


Breno Zanato Detomini
Breno Zanato Detomini

Embedded systems and network engineer based in Brazil.

← All posts