Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 113 additions & 0 deletions pages/learn/develop/extra-firmware.md
Original file line number Diff line number Diff line change
@@ -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
3 changes: 3 additions & 0 deletions shared/general/labels.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -34,3 +36,4 @@ labels:

[update-strategy]:/runtime/update-strategies
[hand-over]:/runtime/update-strategies/#hand-over
[extra-firmware]:/learn/develop/extra-firmware/