Skip to main content
The Axelera Metis is an M.2 Key M AI Processing Unit (AIPU) that connects over PCIe on the Exaviz Cruiser carrier board. It provides hardware-accelerated inference for workloads such as Frigate NVR object detection.

PCIe identifiers

AttributeValue
Vendor ID (metis-setup.sh)0x1f0f
Device ID (metis-setup.sh)0x0001
Vendor ID (preflight / dracut rules)0x1e81
PCI model nameAX2520
Two vendor IDs appear across the tooling: 0x1f0f is used in the udev rule written by metis-setup.sh, while 0x1e81 is the value checked by preflight.sh and used in the dracut udev rules. Use 0x1e81 for the accel subsystem rules and 0x1f0f for PCI subsystem rules.

Post-boot verification

After boot, confirm the Metis device is enumerated by the kernel:
1

Check PCI enumeration

lspci | grep -i axelera
Expected output:
0001:00:00.0 Processing accelerators: Axelera AI AX2520
2

Check PCIe link speed

lspci -vvv -d 1e81: | grep -E "LnkCap|LnkSta"
The Metis operates at PCIe Gen 3 (8 GT/s) x1. A degraded link speed indicates a seating or signal integrity issue.
3

Verify the device node symlink

ls -l /dev/axelera0
The symlink must point to /dev/accel0 (or the assigned accel node). If missing, check that the udev rules are installed and run udevadm trigger.

Group and udev setup

The axelera group controls access to the Metis device node. The setup script creates the group, installs the udev rule, and adds the frigate and hass service accounts.
1

Create the axelera group

groupadd -r axelera
The -r flag creates a system group. The || true in the script allows re-running safely if the group already exists.
2

Install the udev rule

cat > /etc/udev/rules.d/99-axelera-metis.rules <<'EOF'
SUBSYSTEM=="pci", ATTR{vendor}=="0x1f0f", ATTR{device}=="0x0001", \
    GROUP="axelera", MODE="0660", TAG+="systemd"
EOF

udevadm control --reload-rules
udevadm trigger
3

Add service users to the group

usermod -aG axelera frigate
usermod -aG axelera hass
Both the Frigate NVR container user and the Home Assistant user require membership to access /dev/axelera0 without elevated privileges.

axelera.service systemd unit

axelera.service loads the device-tree overlay for the Metis at runtime by writing the DTBO into the kernel’s configfs overlay interface. This applies the overlay without requiring a reboot.
axelera.service
[Service]
ExecStartPre=/usr/bin/mkdir -p /sys/kernel/config/device-tree/overlays/axelera
ExecStart=/usr/bin/sh -c 'cat /lib/firmware/overlays/axelera-metis.dtbo \
    > /sys/kernel/config/device-tree/overlays/axelera/dtbo'
Enable and start the service:
systemctl enable --now axelera.service

OpenRC status helper

For OpenRC-based systems, ax_status.openrc provides a custom status_ai command:
ax_status.openrc
#!/sbin/openrc-run

extra_commands="status_ai"

depend() {
    need axelera-slammer
}

status_ai() {
    if [ -e /dev/axelera0 ]; then
        /usr/bin/ax_status
    else
        echo "Hardware not initialized."
        return 1
    fi
}
Run the custom status check:
rc-service ax_status status_ai

axelera-watchdog OpenRC service

For OpenRC systems, axelera-watchdog runs axelera-stats-logger as a background daemon, logging AI chip health metrics to syslog every 60 seconds:
axelera-watchdog.openrc
#!/sbin/openrc-run

name="Axelera Hardware Monitor"
description="Background watchdog for AI chip health"

command="/usr/bin/axelera-stats-logger"
command_args="--interval 60 --syslog"
command_background="yes"
pidfile="/run/${RC_SVCNAME}.pid"

depend() {
    need dev
    after axelera-slammer   # Wait for the DTBO slammer to finish
}

start_pre() {
    # Verify the AI chip actually exists before backgrounding
    [ -e /dev/axelera0 ]
}
The start_pre() hook prevents the watchdog from starting if /dev/axelera0 is absent, avoiding a noisy failure on systems where the Metis has not yet been configured.

Dracut module

The 95rpi-hardware dracut module embeds the Exaviz Cruiser and Axelera Metis device-tree overlays into the initramfs. This ensures the overlays are available for early userspace hardware bring-up before the root filesystem is mounted.
module-setup.sh
#!/bin/bash
# /usr/lib/dracut/modules.d/95rpi-hardware/module-setup.sh

check() {
    # Only include this if we are on an ARM64 RPi
    [[ "$(uname -m)" == "aarch64" ]] || return 1
    return 0
}

depends() {
    echo "bash"
}

install() {
    # Include the Axelera driver and RPi5 I/O drivers
    inst_mods axdevice rp1_uart rp1_pci

    # Include the specific DTBOs in the initramfs
    inst "/boot/overlays/exaviz-cruiser.dtbo" "/boot/overlays/exaviz-cruiser.dtbo"
    inst "/boot/overlays/axelera-metis.dtbo"  "/boot/overlays/axelera-metis.dtbo"
}
Install the module and rebuild the initramfs:
install -Dm755 module-setup.sh /usr/lib/dracut/modules.d/95rpi-hardware/module-setup.sh
dracut --force --regenerate-all

99-axelera.rules dracut udev rules

These rules run inside the initramfs and create the /dev/axelera0 symlink for the Metis. The Hailo-8 rule is included for compatibility with other accelerators that use the same repository.
99-axelera.rules
# Axelera M.2 (Pre-release & Retail)
# Uses the 'accel' subsystem — new standard for AI chips
SUBSYSTEM=="accel", ATTRS{vendor}=="0x1e81", SYMLINK+="axelera0", \
    TAG+="systemd", MODE="0660", GROUP="render"

# Hailo-8
SUBSYSTEM=="hailo_pci", ATTRS{vendor}=="1e60", SYMLINK+="hailo0", \
    TAG+="systemd", MODE="0660", GROUP="render"
The render group is used here for initramfs compatibility. After the root filesystem is mounted, the axelera group takes over via the rule in /etc/udev/rules.d/99-axelera-metis.rules.

Installing the metis-dkms package (Arch Linux)

The metis-dkms PKGBUILD builds and installs the Axelera Metis PCIe kernel driver via DKMS. The driver source is fetched from the axelera-ai-hub/axelera-driver repository.
PKGBUILD
pkgname=metis-dkms
pkgver=1.5.0
pkgrel=1
pkgdesc="Axelera Metis PCIe driver (DKMS)"
arch=('x86_64' 'aarch64')
url="https://github.com/axelera-ai-hub/axelera-driver"
license=('GPL2')
depends=('dkms')
makedepends=('linux-headers')
source=("$pkgname-$pkgver::https://github.com/axelera-ai-hub/axelera-driver/archive/refs/tags/v$pkgver.tar.gz")
sha256sums=('SKIP')

build() {
    cd axelera-driver-$pkgver
}

package() {
    cd axelera-driver-$pkgver
    install -d "$pkgdir/usr/src/metis-$pkgver"
    cp -r . "$pkgdir/usr/src/metis-$pkgver"

    install -Dm644 dkms.conf \
        "$pkgdir/usr/src/metis-$pkgver/dkms.conf"
}
Build and install:
1

Clone or copy the PKGBUILD

git clone https://github.com/axelera-ai-hub/axelera-driver
cp PKGBUILD axelera-driver/
cd axelera-driver
2

Build the package

makepkg -s
3

Install the package

pacman -U metis-dkms-1.5.0-1-aarch64.pkg.tar.zst
DKMS will automatically build the kernel module for the running kernel and register it for future kernel updates.
4

Verify the module loaded

lsmod | grep axdevice
dmesg | grep -i axelera
sha256sums=('SKIP') is set in the PKGBUILD. Before deploying to production, pin the checksum to a known-good release tarball to prevent supply-chain substitution.

Build docs developers (and LLMs) love