diff options
Diffstat (limited to 'static/freebsd/man9/firmware.9')
| -rw-r--r-- | static/freebsd/man9/firmware.9 | 385 |
1 files changed, 385 insertions, 0 deletions
diff --git a/static/freebsd/man9/firmware.9 b/static/freebsd/man9/firmware.9 new file mode 100644 index 00000000..43f965a2 --- /dev/null +++ b/static/freebsd/man9/firmware.9 @@ -0,0 +1,385 @@ +.\" Copyright (c) 2006 Max Laier <mlaier@FreeBSD.org> +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd January 25, 2024 +.Dt FIRMWARE 9 +.Os +.Sh NAME +.Nm firmware_register , +.Nm firmware_unregister , +.Nm firmware_get , +.Nm firmware_get_flags , +.Nm firmware_put +.Nd firmware image loading and management +.Sh SYNOPSIS +.In sys/param.h +.In sys/systm.h +.In sys/linker.h +.In sys/firmware.h +.Bd -literal +struct firmware { + const char *name; /* system-wide name */ + const void *data; /* location of image */ + size_t datasize; /* size of image in bytes */ + unsigned int version; /* version of the image */ +}; +.Ed +.Ft "const struct firmware *" +.Fo firmware_register +.Fa "const char *imagename" +.Fa "const void *data" +.Fa "size_t datasize" +.Fa "unsigned int version" +.Fa "const struct firmware *parent" +.Fc +.Ft int +.Fn firmware_unregister "const char *imagename" +.Ft "const struct firmware *" +.Fn firmware_get "const char *imagename" +.Ft "const struct firmware *" +.Fn firmware_get_flags "const char *imagename" "uint32_t flags" +.Ft void +.Fn firmware_put "const struct firmware *fp" "int flags" +.Sh DESCRIPTION +The +.Nm firmware +abstraction provides a convenient interface for loading +.Nm firmware images +into the kernel, and for accessing such images from kernel components. +.Pp +A +.Nm firmware image +(or +.Nm image +for brevity) +is an opaque block of data residing in kernel memory. +It is associated to a unique +.Nm imagename +which constitutes a search key, and to an integer +.Nm version +number, which is also an opaque piece of information for the +firmware subsystem. +.Pp +An image is registered with the +.Nm firmware +subsystem by calling the function +.Fn firmware_register , +and unregistered by calling +.Fn 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 +.Pa /boot/loader , +manually at runtime, or on demand by the firmware subsystem. +.Pp +Firmware binary files may also be loaded directly rather than embedded into +kernel modules. +.Pp +.Nm Clients +of the firmware subsystem can request access to a given image +by calling the function +.Fn firmware_get +with the +.Nm imagename +they want as an argument, or by calling +.Fn firmware_get_flags +with the +.Nm imagename +and +.Nm flags +they want as an arguments. +If a matching image is not already registered, +the firmware subsystem will try to load it using the +mechanisms specified below (typically, a kernel module +with +.Nm +the same name +as the image). +.Sh API DESCRIPTION +The kernel +.Nm +firmware API +is made of the following functions: +.Pp +.Fn firmware_register +registers with the kernel an image of size +.Nm datasize +located at address +.Nm data , +under the name +.Nm imagename . +.Pp +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 +.Ft const struct firmware * +pointer to the image requested. +.Pp +.Fn firmware_unregister +tries to unregister the firmware image +.Nm 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. +.Pp +.Fn firmware_get +and +.Fn firmware_get_flags +return the requested firmware image. +The +.Fa flags +argument may be set to +.Dv FIRMWARE_GET_NOWARN +to indicate that errors on firmware load or registration should +only be logged in case of +.Nm booverbose . +If the image is not yet registered with the system, +the functions try to load it. +This involves the linker subsystem and disk access, so +.Fn firmware_get +or +.Fn firmware_get_flags +must not be called with any locks (except for +.Va Giant ) . +Note also that if the firmware image is loaded from a filesystem +it must already be mounted. +In particular this means that it may be necessary to defer requests +from a driver attach method unless it is known the root filesystem is +already mounted. +.Pp +On success, +.Fn firmware_get +and +.Fn firmware_get_flags +return a pointer to the image description and increase the reference count +for this image. +On failure, the functions return NULL. +.Pp +.Fn firmware_put +drops a reference to a firmware image. +The +.Fa flags +argument may be set to +.Dv FIRMWARE_UNLOAD +to indicate that +firmware_put is free to reclaim resources associated with +the firmware image if this is the last reference. +By default a firmware image will be deferred to a +.Xr taskqueue 9 +thread so the call may be done while holding a lock. +In certain cases, such as on driver detach, this cannot be allowed. +.Sh FIRMWARE LOADING VIA MODULES +As mentioned before, any component of the system can register +firmware images at any time by simply calling +.Fn firmware_register . +.Pp +This is typically done when a module containing +a firmware image is given control, +whether compiled in, or preloaded by +.Pa /boot/loader , +or manually loaded with +.Xr kldload 8 . +However, a system can implement additional mechanisms to bring +these images into memory before calling +.Fn firmware_register . +.Pp +When +.Fn firmware_get +or +.Fn firmware_get_flags +does not find the requested image, it tries to load it using +one of the available loading mechanisms. +At the moment, there is only one, namely +.Nm Loadable kernel modules . +.Pp +A firmware image named +.Nm foo +is looked up by trying to load the module named +.Nm foo.ko , +using the facilities described in +.Xr kld 4 . +In particular, images are looked up in the directories specified +by the sysctl variable +.Nm kern.module_path +which on most systems defaults to +.Pa /boot/kernel;/boot/modules . +.Pp +Note that in case a module contains multiple images, +the caller should first request a +.Fn firmware_get +or +.Fn firmware_get_flags +for the first image contained in the module, followed by requests +for the other images. +.Sh BUILDING FIRMWARE LOADABLE MODULES +A firmware module is built by embedding the +.Nm firmware image +into a suitable loadable kernel module that calls +.Fn firmware_register +on loading, and +.Fn firmware_unregister +on unloading. +.Pp +Various system scripts and makefiles let you build a module +by simply writing a Makefile with the following entries: +.Bd -literal + + KMOD= imagename + FIRMWS= image_file:imagename[:version] + .include <bsd.kmod.mk> + +.Ed +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. +.Pp +If you need to embed firmware images into a system, you should write +appropriate entries in the <files.arch> or <files> file, e.g. this example is +from +.Nm sys/conf/files +.Bd -literal +iwn1000fw.c optional iwn1000fw | iwnfw \\ + compile-with "${AWK} -f $S/tools/fw_stub.awk iwn1000.fw:iwn1000fw -miwn1000fw -c${.TARGET}" \\ + no-ctfconvert no-implicit-rule before-depend local \\ + clean "iwn1000fw.c" +# +# NB: ld encodes the path in the binary symbols generated for the +# firmware image so link the file to the object directory to +# get known values for reference in the _fw.c file. +# +iwn1000fw.fwo optional iwn1000fw | iwnfw \\ + dependency "iwn1000.fw" \\ + compile-with "${NORMAL_FWO}" \\ + no-implicit-rule \\ + clean "iwn1000fw.fwo" +.Ed +.Pp +Firmware was previously committed to the source tree as uuencoded files, +but this is no longer required; the binary firmware file should be committed +to the tree as provided by the vendor. +.Pp +Note that generating the firmware modules in this way requires +the availability of the following tools: +.Xr awk 1 , +.Xr make 1 , +the compiler and the linker. +.Sh LOADING BINARY FIRMWARE FILES +.Ss Binary Firmware Format +Binary firmware files can also be loaded, either from +.Pa /boot/loader , +or when +.Nm firmware_get +cannot find the registered firmware from a kernel module. +Binary firmware files are raw binary files that the creator of the firmware +made. +They offer an easier way to load firmware, but one that lacks the full +flexibility and generality of kernel modules with the following restrictions: +.Bl -bullet -compact +.It +Binary firmware files only hold one set of firmware. +.It +They do not offer kernel module dependencies to ensure they are loaded +automatically by the boot loader. +.It +They cannot be compiled into the kernel. +.It +The +.Nm imagename +is identical to the full path name used to load the module. +.It +The version number is assumed to be zero. +.El +.Ss Loading from Pa /boot/loader +Binary firmware files may be loaded either from the command line with +.Dq load -t firmware /boot/firmware/filename +or using the +.Xr loader.conf 5 +mechanism to load modules with a type of +.Dq firmware +For example +.Bd -literal +wififw_load="YES" +wififw_name="/boot/firmware/wifi2034_fw.bin" +wififw_type="firmware" +.Ed +.Ss On demand loading from Nm firmware_get +If no kernel module with an embedded firmware image named +.Nm imagename +is loaded, then +.Nm imagename +will be appended to the module path (by default +.Pa /boot/firmware/ ) +and if that file exists, it will be loaded and registered using +.Nm firmware_register +using the full path to the filename as +.Nm imagename . +.Ss Searching for imagename +.Nm firmware_get +uses the following algorithm to find firmware images: +.Bl -bullet -compact +.It +If an existing firmware image is registered for +.Fa imagename, +that image is returned. +.It +If +.Fa imagename +matches the trailing subpath of a registered image with a full path, that image is returned. +.It +The kernel linker searches for a kernel module named +.Fa imagename . +If a kernel module is found, it is loaded, and +the list of registered firmware images is searched again. +If a match is found, the matching image is returned. +.It +The kernel searches for a file named +.Fa imagename +in the firmware image path +(by default +.Pa /boot/firmware/ ) . +If that file exists and can be read, +it contents are registered as a firmware image with the full path as the +.Nm imagename +and that firmware is returned. +Currently, there is an 8MB limit on the size of the firmware image. +This can be changed by by the sysctl variable +.Nm debug.max_firmware_size . +.El +.Sh SEE ALSO +.Xr kld 4 , +.Xr module 9 +.Pp +.Pa /boot/firmware +.Pp +.Pa /usr/share/examples/kld/firmware +.Sh HISTORY +The +.Nm firmware +system was introduced in +.Fx 6.1 . +Binary firmware loading was introduced in +.Fx 15.0 . +.Sh AUTHORS +This manual page was written by +.An Max Laier Aq Mt mlaier@FreeBSD.org . |
