1.\" Copyright (c) 2006 Max Laier <mlaier@FreeBSD.org> 2.\" All rights reserved. 3.\" 4.\" Redistribution and use in source and binary forms, with or without 5.\" modification, are permitted provided that the following conditions 6.\" are met: 7.\" 1. Redistributions of source code must retain the above copyright 8.\" notice, this list of conditions and the following disclaimer. 9.\" 2. Redistributions in binary form must reproduce the above copyright 10.\" notice, this list of conditions and the following disclaimer in the 11.\" documentation and/or other materials provided with the distribution. 12.\" 13.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR 14.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 15.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 16.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, 17.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 18.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 19.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 20.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23.\" 24.Dd January 25, 2024 25.Dt FIRMWARE 9 26.Os 27.Sh NAME 28.Nm firmware_register , 29.Nm firmware_unregister , 30.Nm firmware_get , 31.Nm firmware_get_flags , 32.Nm firmware_put 33.Nd firmware image loading and management 34.Sh SYNOPSIS 35.In sys/param.h 36.In sys/systm.h 37.In sys/linker.h 38.In sys/firmware.h 39.Bd -literal 40struct firmware { 41 const char *name; /* system-wide name */ 42 const void *data; /* location of image */ 43 size_t datasize; /* size of image in bytes */ 44 unsigned int version; /* version of the image */ 45}; 46.Ed 47.Ft "const struct firmware *" 48.Fo firmware_register 49.Fa "const char *imagename" 50.Fa "const void *data" 51.Fa "size_t datasize" 52.Fa "unsigned int version" 53.Fa "const struct firmware *parent" 54.Fc 55.Ft int 56.Fn firmware_unregister "const char *imagename" 57.Ft "const struct firmware *" 58.Fn firmware_get "const char *imagename" 59.Ft "const struct firmware *" 60.Fn firmware_get_flags "const char *imagename" "uint32_t flags" 61.Ft void 62.Fn firmware_put "const struct firmware *fp" "int flags" 63.Sh DESCRIPTION 64The 65.Nm firmware 66abstraction provides a convenient interface for loading 67.Nm firmware images 68into the kernel, and for accessing such images from kernel components. 69.Pp 70A 71.Nm firmware image 72(or 73.Nm image 74for brevity) 75is an opaque block of data residing in kernel memory. 76It is associated to a unique 77.Nm imagename 78which constitutes a search key, and to an integer 79.Nm version 80number, which is also an opaque piece of information for the 81firmware subsystem. 82.Pp 83An image is registered with the 84.Nm firmware 85subsystem by calling the function 86.Fn firmware_register , 87and unregistered by calling 88.Fn firmware_unregister . 89These functions are usually (but not exclusively) called by 90specially crafted kernel modules that contain the firmware image. 91The modules can be statically compiled in the kernel, or loaded by 92.Pa /boot/loader , 93manually at runtime, or on demand by the firmware subsystem. 94.Pp 95Firmware binary files may also be loaded directly rather than embedded into 96kernel modules. 97.Pp 98.Nm Clients 99of the firmware subsystem can request access to a given image 100by calling the function 101.Fn firmware_get 102with the 103.Nm imagename 104they want as an argument, or by calling 105.Fn firmware_get_flags 106with the 107.Nm imagename 108and 109.Nm flags 110they want as an arguments. 111If a matching image is not already registered, 112the firmware subsystem will try to load it using the 113mechanisms specified below (typically, a kernel module 114with 115.Nm 116the same name 117as the image). 118.Sh API DESCRIPTION 119The kernel 120.Nm 121firmware API 122is made of the following functions: 123.Pp 124.Fn firmware_register 125registers with the kernel an image of size 126.Nm datasize 127located at address 128.Nm data , 129under the name 130.Nm imagename . 131.Pp 132The function returns NULL on error (e.g. because an 133image with the same name already exists, or the image 134table is full), or a 135.Ft const struct firmware * 136pointer to the image requested. 137.Pp 138.Fn firmware_unregister 139tries to unregister the firmware image 140.Nm imagename 141from the system. 142The function is successful and returns 0 143if there are no pending references to the image, otherwise 144it does not unregister the image and returns EBUSY. 145.Pp 146.Fn firmware_get 147and 148.Fn firmware_get_flags 149return the requested firmware image. 150The 151.Fa flags 152argument may be set to 153.Dv FIRMWARE_GET_NOWARN 154to indicate that errors on firmware load or registration should 155only be logged in case of 156.Nm booverbose . 157If the image is not yet registered with the system, 158the functions try to load it. 159This involves the linker subsystem and disk access, so 160.Fn firmware_get 161or 162.Fn firmware_get_flags 163must not be called with any locks (except for 164.Va Giant ) . 165Note also that if the firmware image is loaded from a filesystem 166it must already be mounted. 167In particular this means that it may be necessary to defer requests 168from a driver attach method unless it is known the root filesystem is 169already mounted. 170.Pp 171On success, 172.Fn firmware_get 173and 174.Fn firmware_get_flags 175return a pointer to the image description and increase the reference count 176for this image. 177On failure, the functions return NULL. 178.Pp 179.Fn firmware_put 180drops a reference to a firmware image. 181The 182.Fa flags 183argument may be set to 184.Dv FIRMWARE_UNLOAD 185to indicate that 186firmware_put is free to reclaim resources associated with 187the firmware image if this is the last reference. 188By default a firmware image will be deferred to a 189.Xr taskqueue 9 190thread so the call may be done while holding a lock. 191In certain cases, such as on driver detach, this cannot be allowed. 192.Sh FIRMWARE LOADING VIA MODULES 193As mentioned before, any component of the system can register 194firmware images at any time by simply calling 195.Fn firmware_register . 196.Pp 197This is typically done when a module containing 198a firmware image is given control, 199whether compiled in, or preloaded by 200.Pa /boot/loader , 201or manually loaded with 202.Xr kldload 8 . 203However, a system can implement additional mechanisms to bring 204these images in memory before calling 205.Fn firmware_register . 206.Pp 207When 208.Fn firmware_get 209or 210.Fn firmware_get_flags 211does not find the requested image, it tries to load it using 212one of the available loading mechanisms. 213At the moment, there is only one, namely 214.Nm Loadable kernel modules . 215.Pp 216A firmware image named 217.Nm foo 218is looked up by trying to load the module named 219.Nm foo.ko , 220using the facilities described in 221.Xr kld 4 . 222In particular, images are looked up in the directories specified 223by the sysctl variable 224.Nm kern.module_path 225which on most systems defaults to 226.Pa /boot/kernel;/boot/modules . 227.Pp 228Note that in case a module contains multiple images, 229the caller should first request a 230.Fn firmware_get 231or 232.Fn firmware_get_flags 233for the first image contained in the module, followed by requests 234for the other images. 235.Sh BUILDING FIRMWARE LOADABLE MODULES 236A firmware module is built by embedding the 237.Nm firmware image 238into a suitable loadable kernel module that calls 239.Fn firmware_register 240on loading, and 241.Fn firmware_unregister 242on unloading. 243.Pp 244Various system scripts and makefiles let you build a module 245by simply writing a Makefile with the following entries: 246.Bd -literal 247 248 KMOD= imagename 249 FIRMWS= image_file:imagename[:version] 250 .include <bsd.kmod.mk> 251 252.Ed 253where KMOD is the basename of the module; FIRMWS is a list of 254colon-separated tuples indicating the image_file's to be embedded 255in the module, the imagename and version of each firmware image. 256.Pp 257If you need to embed firmware images into a system, you should write 258appropriate entries in the <files.arch> or <files> file, e.g. this example is 259from 260.Nm sys/conf/files 261.Bd -literal 262iwn1000fw.c optional iwn1000fw | iwnfw \\ 263 compile-with "${AWK} -f $S/tools/fw_stub.awk iwn1000.fw:iwn1000fw -miwn1000fw -c${.TARGET}" \\ 264 no-ctfconvert no-implicit-rule before-depend local \\ 265 clean "iwn1000fw.c" 266# 267# NB: ld encodes the path in the binary symbols generated for the 268# firmware image so link the file to the object directory to 269# get known values for reference in the _fw.c file. 270# 271iwn1000fw.fwo optional iwn1000fw | iwnfw \\ 272 dependency "iwn1000.fw" \\ 273 compile-with "${NORMAL_FWO}" \\ 274 no-implicit-rule \\ 275 clean "iwn1000fw.fwo" 276.Ed 277.Pp 278Firmware was previously committed to the source tree as uuencoded files, 279but this is no longer required; the binary firmware file should be committed 280to the tree as provided by the vendor. 281.Pp 282Note that generating the firmware modules in this way requires 283the availability of the following tools: 284.Xr awk 1 , 285.Xr make 1 , 286the compiler and the linker. 287.Sh LOADING BINARY FIRMWARE FILES 288.Ss Binary Firmware Format 289Binary firmware files can also be loaded, either from 290.Pa /boot/loader , 291or when 292.Nm firmware_get 293cannot find the registered firmware from a kernel module. 294Binary firmware files are raw binary files that the creator of the firmware 295made. 296They offer an easier way to load firmware, but one that lacks the full 297flexibility and generality of kernel modules with the following restrictions: 298.Bl -bullet -compact 299.It 300Binary firmware files only hold one set of firmware. 301.It 302They do not offer kernel module dependencies to ensure they are loaded 303automatically by the boot loader. 304.It 305They cannot be compiled into the kernel. 306.It 307The 308.Nm imagename 309is identical to the full path name used to load the module. 310.It 311The version number is assumed to be zero. 312.El 313.Ss Loading from Pa /boot/loader 314Binary firmware files may be loaded either from the command line with 315.Dq load -t firmware /boot/firmware/filename 316or using the 317.Xr loader.conf 5 318mechanism to load modules with a type of 319.Dq firmware 320For example 321.Bd -literal 322wififw_load="YES" 323wififw_name="/boot/firmware/wifi2034_fw.bin" 324wififw_type="firmware" 325.Ed 326.Ss On demand loading from Nm firmware_get 327If no kernel module with an embedded firmware image named 328.Nm imagename 329is loaded, then 330.Nm imagename 331will be appended to the module path (by default 332.Pa /boot/firmware/ ) 333and if that file exists, it will be loaded and registered using 334.Nm firmware_register 335using the full path to the filename as 336.Nm imagename . 337.Ss Searching for imagename 338.Nm firmware_get 339uses the following algorithm to find firmware images: 340.Bl -bullet -compact 341.It 342If an existing firmware image is registered for 343.Fa imagename, 344.that image is returned. 345.It 346If 347.Fa imagename 348matches the trailing subpath of a registered image with a full path, that image is returned. 349.It 350he kernel linker searches for a kernel module named 351.Fa imagename . 352If a kernel module is found, it is loaded, and 353the list of registered firmware images is searched again. 354If a match is found, the matching image is returned. 355.It 356The kernel searches for a file named 357.Fa imagename 358in the firmware image path 359(by default 360.Pa /boot/firmware/ ) . 361If that file exists and can be read, 362it contents are registered as a firmware image with the full path as the 363.Nm imagename 364and that firmware is returned. 365Currently, there is an 8MB limit on the size of the firmware image. 366This can be changed by by the sysctl variable 367.Nm debug.max_firmware_size . 368.El 369.Sh SEE ALSO 370.Xr kld 4 , 371.Xr module 9 372.Pp 373.Pa /boot/firmware 374.Pp 375.Pa /usr/share/examples/kld/firmware 376.Sh HISTORY 377The 378.Nm firmware 379system was introduced in 380.Fx 6.1 . 381Binary firmware loading was introduced in 382.Fx 15.0 . 383.Sh AUTHORS 384This manual page was written by 385.An Max Laier Aq Mt mlaier@FreeBSD.org . 386