From 729f1ddb4c754603a16b2628b4807e79b2b5c641 Mon Sep 17 00:00:00 2001 From: Christina Ying Wang Date: Fri, 5 Dec 2025 13:20:03 -0800 Subject: [PATCH] pages/learn: Add docs for extra-firmware feature Change-type: patch Signed-off-by: Christina Ying Wang --- pages/learn/develop/extra-firmware.md | 113 ++++++++++++++++++++++++++ shared/general/labels.md | 3 + 2 files changed, 116 insertions(+) create mode 100644 pages/learn/develop/extra-firmware.md diff --git a/pages/learn/develop/extra-firmware.md b/pages/learn/develop/extra-firmware.md new file mode 100644 index 0000000000..93bfbacd96 --- /dev/null +++ b/pages/learn/develop/extra-firmware.md @@ -0,0 +1,113 @@ +--- +title: Extra firmware +excerpt: Add Linux firmware to your fleet using the extra firmware block +--- + +# Extra firmware + +Some devices require specific Linux firmware files to enable hardware functionality such as WiFi, Bluetooth, or GPU acceleration. The {{ $names.os.lower }} root filesystem has limited space, which restricts the firmware that can be included by default. The extra firmware block allows you to incorporate device-specific firmware into your fleet without waiting for an OS release. + +## How it works + +The extra firmware block mirrors the [linux-firmware][linux-firmware] repository and copies the required firmware files into a named volume `extra-firmware`, which mounts at `/extra-firmware` in container. When the feature is enabled, {{ $names.os.lower }} configures itself to look in this volume location for Linux firmware in addition to the default firmware paths. + +## Requirements + +To use the extra firmware feature, your device must meet the following requirements: + +| Requirement | Version | +| --- | --- | +| {{ $names.os.upper }} | v6.10.7 or higher | +| Supervisor | v17.5.2 or higher | + +## Using the extra firmware block + +### Step 1: Add the firmware block to your fleet + +Add the extra firmware block as a service in your `docker-compose.yml` file. We release firmware blocks for the following architectures: + +| Architecture | Image | +| --- | --- | +| armv6 | `bh.cr/balena_os/linux-firmware-armv6hf` | +| armv7 | `bh.cr/balena_os/linux-firmware-armv7hf` | +| armv8 | `bh.cr/balena_os/linux-firmware-aarch64` | +| x86 | `bh.cr/balena_os/linux-firmware-amd64` | + +The firmware block **must** include the `io.balena.features.extra-firmware` label to enable the feature: + +```yaml +version: '2.4' + +services: + firmware: + image: bh.cr/balena_os/linux-firmware-aarch64 + labels: + io.balena.features.extra-firmware: '1' +``` + +### Step 2: Enable the feature in other services (optional) + +If you have other services that need to add firmware files to the extra firmware location, you can also apply the `io.balena.features.extra-firmware` label to those services: + +```yaml +version: '2.4' + +services: + firmware: + image: bh.cr/balena_os/linux-firmware-aarch64 + labels: + io.balena.features.extra-firmware: '1' + + my-service: + build: ./my-service + labels: + io.balena.features.extra-firmware: '1' +``` + +### Step 3: Deploy and reboot + +After deploying a release that includes the firmware block, you must either reload the drivers that use the extra firmware, or reboot the device for the firmware to take effect. This is especially important for firmware that is used early in the application startup process. + +You can initiate a reboot using the [Supervisor API][supervisor-api-reboot]: + +```bash +curl -X POST \ + -H "Content-Type:application/json" \ + -H "Authorization: Bearer $BALENA_SUPERVISOR_API_KEY" + "$BALENA_SUPERVISOR_ADDRESS/v1/reboot" +``` + +__Note:__ To use the Supervisor API, your service must have the `io.balena.features.supervisor-api` [label][labels-link] set. + +## Example configuration + +Here is a complete example of a multicontainer fleet using the extra firmware block alongside an application service: + +```yaml +version: '2.4' + +services: + firmware: + image: bh.cr/balena_os/linux-firmware-aarch64 + labels: + io.balena.features.extra-firmware: '1' + + custom-firmware: + build: ./custom-firmware + depends_on: + - firmware + labels: + io.balena.features.extra-firmware: '1' + io.balena.features.supervisor-api: '1' + command: + - /bin/sh + - -c + - | + cp /usr/share/my-firmware/* /extra-firmware/ + exec /usr/src/app/wait-then-restart.sh + restart: always +``` + +[linux-firmware]:https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/ +[supervisor-api-reboot]:/reference/supervisor/supervisor-api/#post-v1reboot +[labels-link]:/reference/supervisor/docker-compose/#labels diff --git a/shared/general/labels.md b/shared/general/labels.md index 616b359d51..7d8ce16310 100644 --- a/shared/general/labels.md +++ b/shared/general/labels.md @@ -7,6 +7,7 @@ io.{{ $names.company.short }}.features.procfs | false | Bind mounts the host OS io.{{ $names.company.short }}.features.kernel-modules | false | Bind mounts the host OS `/lib/modules` into the container (i.e. `/lib/modules:/lib/modules`). | v7.23.0 | v2.21.0 io.{{ $names.company.short }}.features.firmware | false | Bind mounts the host OS `/lib/firmware` into the container. | v7.23.0 | v2.21.0 io.{{ $names.company.short }}.features.journal-logs | false | Bind mounts journal log directories `/var/log/journal` and `/run/log/journal` as well as `/etc/machine-id` in read only mode. Required by some logging agents such as `promtail`. Journal logs can be read using libraries such as `sd-journal` in C or `sdjournal` in Go. | v12.0.1 | v2.61.0 +io.{{ $names.company.short }}.features.extra-firmware | false | Enables the service to provide [extra firmware][extra-firmware] files to the host OS. Use this with the extra firmware block to add Linux firmware without depending on an OS release. | v17.5.2 | v6.10.7 io.{{ $names.company.short }}.features.supervisor-api | false | Ensures that `{{ $names.company.allCaps }}_SUPERVISOR_HOST`, `{{ $names.company.allCaps }}_SUPERVISOR_PORT`, `{{ $names.company.allCaps }}_SUPERVISOR_ADDRESS`, and `{{ $names.company.allCaps }}_SUPERVISOR_API_KEY` are added to the container environment variables, so the supervisor API can be used. | v7.23.0 | v2.21.0 io.{{ $names.company.short }}.features.{{ $names.company.short }}-api | false | When enabled, it will make sure that `{{ $names.company.allCaps }}_API_KEY` is added to the container environment variables. | v7.23.0 | v2.21.0 io.{{ $names.company.short }}.update.strategy | download-then-kill | Set the fleet [update strategy][update-strategy]. | v7.23.0 | v2.21.0 @@ -26,6 +27,7 @@ labels: io.{{ $names.company.short }}.features.sysfs: '1' io.{{ $names.company.short }}.features.procfs: '1' io.{{ $names.company.short }}.features.journal-logs: '1' + io.{{ $names.company.short }}.features.extra-firmware: '1' io.{{ $names.company.short }}.features.supervisor-api: '1' io.{{ $names.company.short }}.features.{{ $names.company.short }}-api: '1' io.{{ $names.company.short }}.update.strategy: download-then-kill @@ -34,3 +36,4 @@ labels: [update-strategy]:/runtime/update-strategies [hand-over]:/runtime/update-strategies/#hand-over +[extra-firmware]:/learn/develop/extra-firmware/