diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..b0977df2 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +# Shell scripts must use LF line endings; CRLF breaks the shebang +# (e.g. `/usr/bin/env: 'bash\r'`) when COPYed into and executed in containers. +*.sh text eol=lf diff --git a/packages/npu/xdna/Dockerfile b/packages/npu/xdna/Dockerfile index afbe2b45..229cc1c6 100644 --- a/packages/npu/xdna/Dockerfile +++ b/packages/npu/xdna/Dockerfile @@ -31,8 +31,10 @@ RUN cd /ryzers/xdna-driver/tools && \ RUN cd /ryzers/xdna-driver/xrt/build/ && \ ./build.sh -npu -opt -noctest -# Build XDNA driver (-release also generates the .deb package) +# Build XDNA driver (-release also generates the .deb); stub download_npufws so +# firmware comes only from the linux-firmware deb, not repo.radeon.com RUN cd /ryzers/xdna-driver/build && \ + sed -i '/^download_npufws()/,/^}/c\download_npufws() { :; } # firmware via Ubuntu linux-firmware deb (extract_npu_firmware.sh)' build.sh && \ ./build.sh -release # Finally, save and install the XRT/XDNA debian packages @@ -43,7 +45,11 @@ RUN mkdir /ryzers/debs && \ cp /ryzers/xdna-driver/xrt/build/Release/xrt*-amd64-base.deb /ryzers/debs/ && \ dpkg -i /ryzers/debs/*.deb -# Cleanup +# Extract NPU firmware from Ubuntu's linux-firmware deb +COPY extract_npu_firmware.sh /ryzers/extract_npu_firmware.sh +RUN chmod +x /ryzers/extract_npu_firmware.sh && \ + /ryzers/extract_npu_firmware.sh + ENV SHELL=/bin/bash COPY test.sh /ryzers/ diff --git a/packages/npu/xdna/README.md b/packages/npu/xdna/README.md index 40e0b518..07eedc0f 100644 --- a/packages/npu/xdna/README.md +++ b/packages/npu/xdna/README.md @@ -48,4 +48,35 @@ Validation completed --- +## Host firmware + +The `amdxdna` kernel driver loads the NPU firmware (`*.sbin`) from `/lib/firmware/amdnpu/` on the **host**. If it is missing, the device never enumerates and you will not see `/dev/accel/accel0` (so `xrt-smi examine` finds no NPU). On Ubuntu 24.04+ this firmware ships in the `linux-firmware` package. + +Install it on the host using one of the following: + +```bash +# Option A: from the distro package (simplest on Ubuntu 24.04+) +sudo apt-get update && sudo apt-get install -y linux-firmware + +# Option B: extract just the amdnpu blobs with the helper script (no full package install) +sudo ./extract_npu_firmware.sh /lib/firmware/amdnpu + +# Option C: copy the firmware out of the built xdna image +docker run --rm -v "$PWD:/host" xdna:latest \ + bash -c "cp -a /lib/firmware/amdnpu /host/amdnpu" +sudo cp -a ./amdnpu /lib/firmware/ +``` + +After installing the firmware, reload the driver (or reboot) so it picks up the blobs: + +```bash +sudo modprobe -r amdxdna && sudo modprobe amdxdna +# then confirm the device shows up +xrt-smi examine +``` + +The same `extract_npu_firmware.sh` runs automatically inside the container build, so the firmware is present in the image; this section is only about the host kernel driver. The driver's own firmware fetch (`download_npufws`, which pulls `.sbin` blobs from `repo.radeon.com`) is stubbed out during the build, so the image's firmware comes **exclusively** from the `linux-firmware` deb. + +--- + For further details, refer to the official [xdna-driver](https://github.com/amd/xdna-driver) repository. diff --git a/packages/npu/xdna/extract_npu_firmware.sh b/packages/npu/xdna/extract_npu_firmware.sh new file mode 100644 index 00000000..f79c4019 --- /dev/null +++ b/packages/npu/xdna/extract_npu_firmware.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash +# Copyright (C) 2026 Advanced Micro Devices, Inc. All rights reserved. +# SPDX-License-Identifier: MIT +# +# Extract AMDNPU firmware (.sbin) from Ubuntu's linux-firmware deb. +# Usage: ./extract_npu_firmware.sh [target_dir] + +set -euo pipefail + +TARGET_DIR="${1:-/lib/firmware/amdnpu}" +WORK_DIR="$(mktemp -d)" + +cleanup() { rm -rf "$WORK_DIR"; } +trap cleanup EXIT + +echo "==> Downloading linux-firmware package..." +cd "$WORK_DIR" + +# apt-get download fetches the deb without installing it. +# On Ubuntu 24.04+ the amdnpu firmware is part of linux-firmware. +apt-get update -qq +apt-get download linux-firmware 2>/dev/null \ + || apt-get download linux-firmware-amdgpu 2>/dev/null \ + || { echo "ERROR: could not download linux-firmware package"; exit 1; } + +echo "==> Extracting AMDNPU firmware..." +mkdir -p extracted +for deb in *.deb; do + dpkg-deb --fsys-tarfile "$deb" \ + | tar -C extracted -x --wildcards '*/firmware/amdnpu/*' 2>/dev/null || true +done + +# Find where the firmware ended up (varies by package layout) +FW_SRC="" +for candidate in extracted/lib/firmware/amdnpu extracted/usr/lib/firmware/amdnpu; do + if [ -d "$candidate" ]; then + FW_SRC="$candidate" + break + fi +done + +if [ -z "$FW_SRC" ]; then + echo "ERROR: no amdnpu firmware found in downloaded package" + echo "Available firmware dirs:" + find extracted -type d -name 'firmware' 2>/dev/null + exit 1 +fi + +echo "==> Installing firmware to $TARGET_DIR" +mkdir -p "$TARGET_DIR" +cp -a "$FW_SRC"/* "$TARGET_DIR"/ + +echo "==> Installed NPU firmware:" +find "$TARGET_DIR" -type f -o -type l | sort +echo "Done."