diff --git a/local/recipes/system/redbear-firmware/recipe.toml b/local/recipes/system/redbear-firmware/recipe.toml index 58c2aa071f..e1cecac530 100644 --- a/local/recipes/system/redbear-firmware/recipe.toml +++ b/local/recipes/system/redbear-firmware/recipe.toml @@ -1,49 +1,120 @@ +# Red Bear OS firmware bundle recipe (v6.0 2026) +# +# Per the NO SILENT UPSTREAM PULLS policy (AGENTS.md), this recipe does +# NOT contact the network at build time. Firmware blobs are fetched +# explicitly by the user via local/scripts/fetch-firmware.sh and +# committed into `source/`. `fetch-firmware.sh` is gated by REPO_OFFLINE +# and is never invoked by `make all` / `make live`. +# +# Feature flags (env vars) toggle vendor subsets at build time: +# REDBEAR_FIRMWARE_AMD=1 package amdgpu/ + amd-ucode/ (default: 1) +# REDBEAR_FIRMWARE_INTEL=1 package i915/, iwlwifi-*, intel/ibt-* (default: 1) +# REDBEAR_FIRMWARE_RADEON=1 package radeon/ (default: 0) +# To omit firmware entirely, remove the package from the build config +# rather than zeroing every flag — an empty bundle is a config error. + [source] -# Local overlay recipe. Firmware sources are fetched during the custom build step into a shared -# cache, then staged into /lib/firmware. path = "source" -upstream = "https://gitlab.com/kernel-firmware/linux-firmware.git" [build] template = "custom" -script = """ -FIRMWARE_URL="https://gitlab.com/kernel-firmware/linux-firmware/-/archive/main/linux-firmware-main.tar.gz" -CACHE_DIR="${COOKBOOK_ROOT}/build/redbear-firmware-cache" -ARCHIVE="${CACHE_DIR}/linux-firmware-main.tar.gz" -EXTRACTED="${CACHE_DIR}/linux-firmware-main" +script = ''' +set -euo pipefail -mkdir -p "${CACHE_DIR}" +SRC="${COOKBOOK_SOURCE}" +STAGE="${COOKBOOK_STAGE}" -if [ ! -f "${ARCHIVE}" ]; then - wget -O "${ARCHIVE}" "${FIRMWARE_URL}" +if [ ! -d "${SRC}" ]; then + echo "ERROR: firmware source directory not found: ${SRC}" >&2 + echo " This recipe requires a manual linux-firmware archive." >&2 + echo " Run local/scripts/fetch-firmware.sh to populate it, then rebuild." >&2 + exit 1 fi -rm -rf "${EXTRACTED}" -mkdir -p "${EXTRACTED}" -tar -xf "${ARCHIVE}" -C "${EXTRACTED}" --strip-components=1 +FLAG_AMD="${REDBEAR_FIRMWARE_AMD:-1}" +FLAG_INTEL="${REDBEAR_FIRMWARE_INTEL:-1}" +FLAG_RADEON="${REDBEAR_FIRMWARE_RADEON:-0}" -mkdir -p "${COOKBOOK_STAGE}/lib/firmware" -mkdir -p "${COOKBOOK_STAGE}/lib/firmware/LICENSES" +if [ "${FLAG_AMD}" = "0" ] && [ "${FLAG_INTEL}" = "0" ] && [ "${FLAG_RADEON}" = "0" ]; then + echo "ERROR: all firmware feature flags are disabled (firmware-amd, firmware-intel, firmware-radeon)." >&2 + echo " If you do not want a firmware bundle, remove redbear-firmware from the config." >&2 + exit 1 +fi -install -Dm0644 "${EXTRACTED}/WHENCE" "${COOKBOOK_STAGE}/lib/firmware/LICENSES/WHENCE" -for lic in "${EXTRACTED}"/LICENCE* "${EXTRACTED}"/LICENSE*; do - [ -f "$lic" ] && install -Dm0644 "$lic" "${COOKBOOK_STAGE}/lib/firmware/LICENSES/$(basename "$lic")" +mkdir -p "${STAGE}/lib/firmware/LICENSES" + +if [ -f "${SRC}/WHENCE" ]; then + install -Dm0644 "${SRC}/WHENCE" "${STAGE}/lib/firmware/LICENSES/WHENCE" +fi +for lic in "${SRC}"/LICENCE* "${SRC}"/LICENSE*; do + [ -f "$lic" ] && install -Dm0644 "$lic" "${STAGE}/lib/firmware/LICENSES/$(basename "$lic")" done -FIRMWARE_DIRS="amdgpu radeon i915 iwlwifi" -for dir in ${FIRMWARE_DIRS}; do - if [ -d "${EXTRACTED}/${dir}" ]; then - mkdir -p "${COOKBOOK_STAGE}/lib/firmware/${dir}" - find "${EXTRACTED}/${dir}" -type f -exec install -Dm0644 {} "${COOKBOOK_STAGE}/lib/firmware/{}" \\; +install_vendor_dir() { + local src_subdir="$1" + local dst_subdir="$2" + if [ ! -d "${SRC}/${src_subdir}" ]; then + echo "WARN: vendor subset '${src_subdir}' not present in archive; skipping" >&2 + return 0 fi -done + mkdir -p "${STAGE}/lib/firmware/${dst_subdir}" + (cd "${SRC}/${src_subdir}" && find . -mindepth 1 -type f -print0) | \ + (cd "${STAGE}/lib/firmware/${dst_subdir}" && xargs -0 -I {} install -Dm0644 "${SRC}/${src_subdir}/{}" "{}") +} -cat > "${COOKBOOK_STAGE}/lib/firmware/LICENSES/index.txt" <<'EOF' +install_intel_wifi() { + local count=0 + shopt -s nullglob + for blob in "${SRC}"/iwlwifi-*.ucode "${SRC}"/iwlwifi-*.pnvm; do + mkdir -p "${STAGE}/lib/firmware" + install -Dm0644 "$blob" "${STAGE}/lib/firmware/$(basename "$blob")" + count=$((count + 1)) + done + shopt -u nullglob + if [ "$count" = "0" ]; then + echo "WARN: no iwlwifi-* firmware blobs in archive; skipping Intel Wi-Fi" >&2 + fi +} + +install_intel_bluetooth() { + if [ ! -d "${SRC}/intel" ]; then + echo "WARN: intel/ directory not present in archive; skipping Intel Bluetooth" >&2 + return 0 + fi + mkdir -p "${STAGE}/lib/firmware/intel" + (cd "${SRC}/intel" && find . -mindepth 1 -type f -name 'ibt-*' -print0) | \ + (cd "${STAGE}/lib/firmware/intel" && xargs -0 -I {} install -Dm0644 "${SRC}/intel/{}" "{}") +} + +installed_count=0 + +if [ "${FLAG_AMD}" = "1" ]; then + echo "Firmware: installing AMD amdgpu + amd-ucode subsets" + install_vendor_dir "amdgpu" "amdgpu" + install_vendor_dir "amd-ucode" "amd-ucode" + installed_count=$((installed_count + 1)) +fi + +if [ "${FLAG_INTEL}" = "1" ]; then + echo "Firmware: installing Intel i915 DMC + iwlwifi + Bluetooth subsets" + install_vendor_dir "i915" "i915" + install_intel_wifi + install_intel_bluetooth + installed_count=$((installed_count + 1)) +fi + +if [ "${FLAG_RADEON}" = "1" ]; then + echo "Firmware: installing legacy radeon subset" + install_vendor_dir "radeon" "radeon" + installed_count=$((installed_count + 1)) +fi + +cat > "${STAGE}/lib/firmware/LICENSES/index.txt" <