DragonFly On-Line Manual Pages
FIRMWARE(9) DragonFly Kernel Developer's Manual FIRMWARE(9)
NAME
firmware_register, firmware_unregister, firmware_get, firmware_put -
firmware image loading and management
SYNOPSIS
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/linker.h>
#include <sys/firmware.h>
struct firmware {
const char *name; /* system-wide name */
const uint8_t *data; /* location of image */
size_t datasize; /* size of image in bytes */
unsigned int version; /* version of the image */
};
const struct firmware *
firmware_register(const char *imagename, const void *data,
size_t datasize, unsigned int version,
const struct firmware *parent);
int
firmware_unregister(const char *imagename);
const struct firmware *
firmware_get(const char *imagename);
void
firmware_put(const struct firmware *fp, int flags);
DESCRIPTION
The firmware abstraction provides a convenient interface for loading
firmware images into the kernel, and for accessing such images from
kernel components.
A firmware image (or image for brevity) is an opaque block of data
residing in kernel memory. It is associated to a unique imagename which
constitutes a search key, and to an integer version number, which is also
an opaque piece of information for the firmware subsystem.
An image is registered with the firmware subsystem by calling the
function firmware_register(), and unregistered by calling
firmware_unregister(). These functions are usually (but not exclusively)
called by specially crafted kernel modules that contain the firmware
image. The modules can be statically compiled in the kernel, or loaded
by loader(8), manually at runtime, or on demand by the firmware
subsystem.
Clients of the firmware subsystem can request access to a given image by
calling the function firmware_get() with the imagename they want as an
argument. If a matching image is not already registered, the firmware
subsystem will try to load it using the mechanisms specified in the
FIRMWARE LOADING MECHANISMS section.
API DESCRIPTION
The kernel firmware API is made of the following functions:
firmware_register() registers with the kernel an image of size datasize
located at address data, under the name imagename. The caller must keep
the name and data valid until the image is unregistered. The function
returns NULL on error (e.g. because an image with the same name already
exists, or the image table is full), or a const struct firmware * pointer
to the image requested.
firmware_unregister() tries to unregister the firmware image imagename
from the system. The function is successful and returns 0 if there are
no pending references to the image, otherwise it does not unregister the
image and returns EBUSY.
firmware_get() returns the requested firmware image. If the image is not
yet registered with the system, the function tries to load it. This can
involve the linker subsystem and filesystem I/O, so firmware_get() must
not be called with any locks (except for Giant). Note also that the
filesystem holding the firmware image must already be mounted. A driver
may need to defer requests until that filesystem is available, or use an
image preloaded by loader(8). On success, firmware_get() returns a
pointer to the image description and increases the reference count for
this image. On failure, the function returns NULL.
firmware_put() drops a reference to a firmware image. The flags argument
may be set to FIRMWARE_UNLOAD to indicate that the function is free to
reclaim resources associated with the firmware image if this is the last
reference. Reclamation is deferred to a taskqueue(9) thread and is not
guaranteed to have completed when the call returns. Other references can
prevent reclamation. Without FIRMWARE_UNLOAD, the call only drops the
caller's reference.
FIRMWARE LOADING MECHANISMS
Any component of the system can register firmware images at any time by
calling firmware_register(). This is typically done when a module
containing a firmware image is given control, whether compiled in, or
preloaded by loader(8), or manually loaded with kldload(8).
When firmware_get() does not find the image already registered, it tries
the following sources in order:
Preloaded Images Images already in memory, including those
needed before the root filesystem is
available.
Firmware Files Images read from a mounted filesystem.
Loadable Kernel Modules Images registered by loadable modules.
Preloaded Images
An image the loader(8) was told to preload is already in memory and is
thus searched first.
This is the only source that works before the root filesystem is mounted.
Firmware Files
A firmware image named foo is looked up as a regular file named foo under
each directory listed in the sysctl variable hw.firmware_path, a
semicolon-separated list of directories which defaults to
/usr/local/lib/firmware;/usr/lib/firmware. The variable is also a
tunable and may be set from loader.conf(5).
The image name is used as a path relative to each directory in turn, and
the first readable regular file wins. For example, a driver requesting
the image amdgpu/raven_vcn.bin is served from
/usr/local/lib/firmware/amdgpu/raven_vcn.bin when that file exists and is
readable.
Images larger than the sysctl variable hw.firmware_max_size, which
defaults to 256 MB, are refused.
Loadable Kernel Modules
If no file was found, the image is looked up by trying to load the module
named foo.ko, using the facilities described in kld(4). In particular,
modules are looked up in the directories specified by the sysctl variable
kern.module_path.
Note that in case a module contains multiple images, the caller should
first request a firmware_get() for the first image contained in the
module, followed by requests for the other images.
Some firmware modules require license acknowledgement before loading; see
urtwn(4) and iwi(4). These checks remain part of the module-loading
path.
BUILDING FIRMWARE LOADABLE MODULES
A firmware module is built by embedding the firmware image into a
suitable loadable kernel module that calls firmware_register() on
loading, and firmware_unregister() on unloading.
Various system scripts and makefiles let you build a module by simply
writing a Makefile with the following entries:
KMOD= imagename
FIRMWS= image_file:imagename[:version]
FIRMWARE_LICENSE= license
.include <bsd.kmod.mk>
where KMOD is the basename of the module; FIRMWS is a list of colon-
separated tuples indicating the image_file's to be embedded in the
module, the imagename and version of each firmware image.
The FIRMWARE_LICENSE is optional. When it is set, the module refuses to
register anything until legal.NAME.license_ack is set, and directs the
reader to the matching directory under /usr/share/doc/legal. It exists
because a firmware image built this way arrives with the system source,
so the user receives it without having been shown any terms. An firmware
image that comes from a package does not have that problem, and no such
check is made.
If you need to embed firmware images into a system, you should write
appropriate entries in the files file. This example is from wpi(4)'s
firmware.
wpifw.c optional wpifw \
dependency "$S/contrib/dev/wpi/iwlwifi-3945-2.14.4.fw.uu" \
compile-with "${AWK} -f $S/tools/fw_stub.awk wpi.fw:wpifw:2144 -mwpifw -c${.TARGET}" \
no-implicit-rule before-depend local \
clean "wpifw.c"
wpifw.fwo optional wpifw \
dependency "wpi.fw" \
compile-with "${LD} -b binary -d -warn-common -r -d -o ${.TARGET} wpi.fw" \
no-implicit-rule \
clean "wpifw.fwo"
wpi.fw optional wpifw \
dependency "$S/contrib/dev/wpi/iwlwifi-3945-2.14.4.fw.uu" \
compile-with "uudecode -o ${.TARGET} $S/contrib/dev/wpi/iwlwifi-3945-2.14.4.fw.uu" \
no-obj no-implicit-rule \
clean "wpi.fw"
Note that generating the firmware modules in this way requires the
availability of the following tools: awk(1), make(1), the compiler and
the linker.
SEE ALSO
kld(4), loader.conf(5), kldload(8), loader(8), sysctl(8), module(9)
/usr/share/examples/kld/firmware
HISTORY
The firmware system was introduced in FreeBSD 6.1.
Support for loading firmware images from the filesystem first appeared in
DragonFly 6.5.
AUTHORS
This manual page was written by Max Laier <mlaier@FreeBSD.org>.
DragonFly 6.5-DEVELOPMENT September 29, 2026 DragonFly 6.5-DEVELOPMENT