1d83c779aSSascha Wildner.\" Copyright (c) 2006 Max Laier <mlaier@FreeBSD.org> 2d83c779aSSascha Wildner.\" All rights reserved. 339c15c2bSSascha Wildner.\" 439c15c2bSSascha Wildner.\" Redistribution and use in source and binary forms, with or without 539c15c2bSSascha Wildner.\" modification, are permitted provided that the following conditions 639c15c2bSSascha Wildner.\" are met: 739c15c2bSSascha Wildner.\" 1. Redistributions of source code must retain the above copyright 839c15c2bSSascha Wildner.\" notice, this list of conditions and the following disclaimer. 939c15c2bSSascha Wildner.\" 2. Redistributions in binary form must reproduce the above copyright 10d83c779aSSascha Wildner.\" notice, this list of conditions and the following disclaimer in the 11d83c779aSSascha Wildner.\" documentation and/or other materials provided with the distribution. 1239c15c2bSSascha Wildner.\" 13d83c779aSSascha Wildner.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR 14d83c779aSSascha Wildner.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 15d83c779aSSascha Wildner.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 16d83c779aSSascha Wildner.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, 17d83c779aSSascha Wildner.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 18d83c779aSSascha Wildner.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 19d83c779aSSascha Wildner.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 20d83c779aSSascha Wildner.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21d83c779aSSascha Wildner.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22d83c779aSSascha Wildner.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2339c15c2bSSascha Wildner.\" 24d83c779aSSascha Wildner.\" $FreeBSD: src/share/man/man9/firmware.9,v 1.9 2010/04/14 19:08:06 uqs Exp $ 2539c15c2bSSascha Wildner.\" 26e42abaa5SSascha Wildner.Dd July 4, 2013 2739c15c2bSSascha Wildner.Dt FIRMWARE 9 2839c15c2bSSascha Wildner.Os 2939c15c2bSSascha Wildner.Sh NAME 30d83c779aSSascha Wildner.Nm firmware_register , 31d83c779aSSascha Wildner.Nm firmware_unregister , 32d83c779aSSascha Wildner.Nm firmware_get , 33d83c779aSSascha Wildner.Nm firmware_put 34d83c779aSSascha Wildner.Nd firmware image loading and management 3539c15c2bSSascha Wildner.Sh SYNOPSIS 36d83c779aSSascha Wildner.In sys/param.h 37d83c779aSSascha Wildner.In sys/systm.h 38d83c779aSSascha Wildner.In sys/linker.h 3939c15c2bSSascha Wildner.In sys/firmware.h 40d83c779aSSascha Wildner.Bd -literal 41d83c779aSSascha Wildnerstruct firmware { 42d83c779aSSascha Wildner const char *name; /* system-wide name */ 43*9d2642a2SFrançois Tigeot const uint8_t *data; /* location of image */ 44d83c779aSSascha Wildner size_t datasize; /* size of image in bytes */ 45d83c779aSSascha Wildner unsigned int version; /* version of the image */ 46d83c779aSSascha Wildner}; 47d83c779aSSascha Wildner.Ed 48d83c779aSSascha Wildner.Ft "const struct firmware *" 49d83c779aSSascha Wildner.Fo firmware_register 50d83c779aSSascha Wildner.Fa "const char *imagename" 51d83c779aSSascha Wildner.Fa "const void *data" 52d83c779aSSascha Wildner.Fa "size_t datasize" 53d83c779aSSascha Wildner.Fa "unsigned int version" 54d83c779aSSascha Wildner.Fa "const struct firmware *parent" 55d83c779aSSascha Wildner.Fc 56d83c779aSSascha Wildner.Ft int 57d83c779aSSascha Wildner.Fn firmware_unregister "const char *imagename" 58d83c779aSSascha Wildner.Ft "const struct firmware *" 59d83c779aSSascha Wildner.Fn firmware_get "const char *imagename" 6039c15c2bSSascha Wildner.Ft void 61d83c779aSSascha Wildner.Fn firmware_put "const struct firmware *fp" "int flags" 6239c15c2bSSascha Wildner.Sh DESCRIPTION 6339c15c2bSSascha WildnerThe 6439c15c2bSSascha Wildner.Nm firmware 65d83c779aSSascha Wildnerabstraction provides a convenient interface for loading 66d83c779aSSascha Wildner.Nm firmware images 67d83c779aSSascha Wildnerinto the kernel, and for accessing such images from kernel components. 6839c15c2bSSascha Wildner.Pp 69d83c779aSSascha WildnerA 70d83c779aSSascha Wildner.Nm firmware image 71d83c779aSSascha Wildner(or 72d83c779aSSascha Wildner.Nm image 73d83c779aSSascha Wildnerfor brevity) 74d83c779aSSascha Wildneris an opaque block of data residing in kernel memory. 75d83c779aSSascha WildnerIt is associated to a unique 76d83c779aSSascha Wildner.Nm imagename 77d83c779aSSascha Wildnerwhich constitutes a search key, and to an integer 78d83c779aSSascha Wildner.Nm version 79d83c779aSSascha Wildnernumber, which is also an opaque piece of information for the 80d83c779aSSascha Wildnerfirmware subsystem. 8139c15c2bSSascha Wildner.Pp 82d83c779aSSascha WildnerAn image is registered with the 83d83c779aSSascha Wildner.Nm firmware 84d83c779aSSascha Wildnersubsystem by calling the function 85d83c779aSSascha Wildner.Fn firmware_register , 86d83c779aSSascha Wildnerand unregistered by calling 87d83c779aSSascha Wildner.Fn firmware_unregister . 88d83c779aSSascha WildnerThese functions are usually (but not exclusively) called by 89d83c779aSSascha Wildnerspecially crafted kernel modules that contain the firmware image. 90d83c779aSSascha WildnerThe modules can be statically compiled in the kernel, or loaded by 91d83c779aSSascha Wildner.Nm /boot/loader , 92d83c779aSSascha Wildnermanually at runtime, or on demand by the firmware subsystem. 93d83c779aSSascha Wildner.Pp 94d83c779aSSascha Wildner.Nm Clients 95d83c779aSSascha Wildnerof the firmware subsystem can request access to a given image 96d83c779aSSascha Wildnerby calling the function 97d83c779aSSascha Wildner.Fn firmware_get 98d83c779aSSascha Wildnerwith the 99d83c779aSSascha Wildner.Nm imagename 100d83c779aSSascha Wildnerthey want as an argument. If a matching image is not already registered, 101d83c779aSSascha Wildnerthe firmware subsystem will try to load it using the 102d83c779aSSascha Wildnermechanisms specified below (typically, a kernel module 103d83c779aSSascha Wildnerwith 104d83c779aSSascha Wildner.Nm the same name 105d83c779aSSascha Wildneras the image). 106d83c779aSSascha Wildner.Sh API DESCRIPTION 107d83c779aSSascha WildnerThe kernel 108d83c779aSSascha Wildner.Nm firmware API 109d83c779aSSascha Wildneris made of the following functions: 110d83c779aSSascha Wildner.Pp 111d83c779aSSascha Wildner.Fn firmware_register 112d83c779aSSascha Wildnerregisters with the kernel an image of size 113d83c779aSSascha Wildner.Nm datasize 114d83c779aSSascha Wildnerlocated at address 115d83c779aSSascha Wildner.Nm data , 116d83c779aSSascha Wildnerunder the name 117d83c779aSSascha Wildner.Nm imagename . 118d83c779aSSascha Wildner.Pp 119d83c779aSSascha WildnerThe function returns NULL on error (e.g. because an 120d83c779aSSascha Wildnerimage with the same name already exists, or the image 121d83c779aSSascha Wildnertable is full), or a 122d83c779aSSascha Wildner.Ft const struct firmware * 123d83c779aSSascha Wildnerpointer to the image requested. 124d83c779aSSascha Wildner.Pp 125d83c779aSSascha Wildner.Fn firmware_unregister 126d83c779aSSascha Wildnertries to unregister the firmware image 127d83c779aSSascha Wildner.Nm imagename 128d83c779aSSascha Wildnerfrom the system. The function is successful and returns 0 129d83c779aSSascha Wildnerif there are no pending references to the image, otherwise 1301f3e7f4cSSascha Wildnerit does not unregister the image and returns 1311f3e7f4cSSascha Wildner.Er EBUSY . 132d83c779aSSascha Wildner.Pp 133d83c779aSSascha Wildner.Fn firmware_get 134d83c779aSSascha Wildnerreturns the requested firmware image. 135d83c779aSSascha WildnerIf the image is not yet registered with the system, 136d83c779aSSascha Wildnerthe function tries to load it. 137d83c779aSSascha WildnerThis involves the linker subsystem and disk access, so 138d83c779aSSascha Wildner.Fn firmware_get 139d83c779aSSascha Wildnermust not be called with any locks (except for 140d83c779aSSascha Wildner.Va Giant ) . 141d83c779aSSascha WildnerNote also that if the firmware image is loaded from a filesystem 142d83c779aSSascha Wildnerit must already be mounted. 143d83c779aSSascha WildnerIn particular this means that it may be necessary to defer requests 144d83c779aSSascha Wildnerfrom a driver attach method unless it is known the root filesystem is 145d83c779aSSascha Wildneralready mounted. 146d83c779aSSascha Wildner.Pp 147d83c779aSSascha WildnerOn success, 148d83c779aSSascha Wildner.Fn firmware_get 149d83c779aSSascha Wildnerreturns a pointer to the image description and increases the reference count 150d83c779aSSascha Wildnerfor this image. On failure, the function returns NULL. 151d83c779aSSascha Wildner.Pp 152d83c779aSSascha Wildner.Fn firmware_put 153d83c779aSSascha Wildnerdrops a reference to a firmware image. 154d83c779aSSascha WildnerThe 155d83c779aSSascha Wildner.Fa flags 156d83c779aSSascha Wildnerargument may be set to 157d83c779aSSascha Wildner.Dv FIRMWARE_UNLOAD 158d83c779aSSascha Wildnerto indicate that 159d83c779aSSascha Wildnerfirmware_put is free to reclaim resources associated with 160d83c779aSSascha Wildnerthe firmware image if this is the last reference. 161d83c779aSSascha WildnerBy default a firmware image will be deferred to a 162d83c779aSSascha Wildner.Xr taskqueue 9 163d83c779aSSascha Wildnerthread so the call may be done while holding a lock. 164d83c779aSSascha WildnerIn certain cases, such as on driver detach, this cannot be allowed. 165d83c779aSSascha Wildner.Sh FIRMWARE LOADING MECHANISMS 166d83c779aSSascha WildnerAs mentioned before, any component of the system can register 167d83c779aSSascha Wildnerfirmware images at any time by simply calling 168d83c779aSSascha Wildner.Fn firmware_register . 169d83c779aSSascha Wildner.Pp 170d83c779aSSascha WildnerThis is typically done when a module containing 171d83c779aSSascha Wildnera firmware image is given control, 172d83c779aSSascha Wildnerwhether compiled in, or preloaded by 173d83c779aSSascha Wildner.Nm /boot/loader , 174d83c779aSSascha Wildneror manually loaded with 175d83c779aSSascha Wildner.Xr kldload 8 . 176d83c779aSSascha WildnerHowever, a system can implement additional mechanisms to bring 177d83c779aSSascha Wildnerthese images in memory before calling 178d83c779aSSascha Wildner.Fn firmware_register . 179d83c779aSSascha Wildner.Pp 180d83c779aSSascha WildnerWhen 181d83c779aSSascha Wildner.Fn firmware_get 182d83c779aSSascha Wildnerdoes not find the requested image, it tries to load it using 183d83c779aSSascha Wildnerone of the available loading mechanisms. 184d83c779aSSascha WildnerAt the moment, there is only one, namely 185d83c779aSSascha Wildner.Nm Loadable kernel modules : 186d83c779aSSascha Wildner.Pp 187d83c779aSSascha WildnerA firmware image named 188d83c779aSSascha Wildner.Nm foo 189d83c779aSSascha Wildneris looked up by trying to load the module named 190d83c779aSSascha Wildner.Nm foo.ko , 191d83c779aSSascha Wildnerusing the facilities described in 192d83c779aSSascha Wildner.Xr kld 4 . 193d83c779aSSascha WildnerIn particular, images are looked up in the directories specified 194d83c779aSSascha Wildnerby the sysctl variable 195d83c779aSSascha Wildner.Nm kern.module_path 196d83c779aSSascha Wildnerwhich on most systems defaults to 197d83c779aSSascha Wildner.Nm /boot/kernel;/boot/modules . 198d83c779aSSascha Wildner.Pp 199d83c779aSSascha WildnerNote that in case a module contains multiple images, 200d83c779aSSascha Wildnerthe caller should first request a 201d83c779aSSascha Wildner.Fn firmware_get 202d83c779aSSascha Wildnerfor the first image contained in the module, followed by requests 203d83c779aSSascha Wildnerfor the other images. 204d83c779aSSascha Wildner.Sh BUILDING FIRMWARE LOADABLE MODULES 205d83c779aSSascha WildnerA firmware module is built by embedding the 206d83c779aSSascha Wildner.Nm firmware image 207d83c779aSSascha Wildnerinto a suitable loadable kernel module that calls 208d83c779aSSascha Wildner.Fn firmware_register 209d83c779aSSascha Wildneron loading, and 210d83c779aSSascha Wildner.Fn firmware_unregister 211d83c779aSSascha Wildneron unloading. 212d83c779aSSascha Wildner.Pp 213d83c779aSSascha WildnerVarious system scripts and makefiles let you build a module 214d83c779aSSascha Wildnerby simply writing a Makefile with the following entries: 215d83c779aSSascha Wildner.Bd -literal 216d83c779aSSascha Wildner 217d83c779aSSascha Wildner KMOD= imagename 218d83c779aSSascha Wildner FIRMWS= image_file:imagename[:version] 219d83c779aSSascha Wildner .include <bsd.kmod.mk> 220d83c779aSSascha Wildner 221d83c779aSSascha Wildner.Ed 222d83c779aSSascha Wildnerwhere KMOD is the basename of the module; FIRMWS is a list of 223d83c779aSSascha Wildnercolon-separated tuples indicating the image_file's to be embedded 224d83c779aSSascha Wildnerin the module, the imagename and version of each firmware image. 225d83c779aSSascha Wildner.Pp 226d83c779aSSascha WildnerIf you need to embed firmware images into a system, you should write 227e42abaa5SSascha Wildnerappropriate entries in the 228e42abaa5SSascha Wildner.Li files 229e42abaa5SSascha Wildnerfile. 230e42abaa5SSascha WildnerThis example is from 231e42abaa5SSascha Wildner.Xr wpi 4 Ap s 232e42abaa5SSascha Wildnerfirmware. 233d83c779aSSascha Wildner.Bd -literal 234e42abaa5SSascha Wildnerwpifw.c optional wpifw \\ 235e42abaa5SSascha Wildner dependency "$S/contrib/dev/wpi/iwlwifi-3945-2.14.4.fw.uu" \\ 236e42abaa5SSascha Wildner compile-with "${AWK} -f $S/tools/fw_stub.awk wpi.fw:wpifw:2144 -mwpifw -c${.TARGET}" \\ 237d83c779aSSascha Wildner no-implicit-rule before-depend local \\ 238e42abaa5SSascha Wildner clean "wpifw.c" 239e42abaa5SSascha Wildnerwpifw.fwo optional wpifw \\ 240e42abaa5SSascha Wildner dependency "wpi.fw" \\ 241e42abaa5SSascha Wildner compile-with "${LD} -b binary -d -warn-common -r -d -o ${.TARGET} wpi.fw" \\ 242d83c779aSSascha Wildner no-implicit-rule \\ 243e42abaa5SSascha Wildner clean "wpifw.fwo" 244e42abaa5SSascha Wildnerwpi.fw optional wpifw \\ 245e42abaa5SSascha Wildner dependency "$S/contrib/dev/wpi/iwlwifi-3945-2.14.4.fw.uu" \\ 246e42abaa5SSascha Wildner compile-with "uudecode -o ${.TARGET} $S/contrib/dev/wpi/iwlwifi-3945-2.14.4.fw.uu" \\ 247d83c779aSSascha Wildner no-obj no-implicit-rule \\ 248e42abaa5SSascha Wildner clean "wpi.fw" 249d83c779aSSascha Wildner.Ed 250d83c779aSSascha Wildner.Pp 251d83c779aSSascha WildnerNote that generating the firmware modules in this way requires 252d83c779aSSascha Wildnerthe availability of the following tools: 2531f3e7f4cSSascha Wildner.Xr awk 1 , 2541f3e7f4cSSascha Wildner.Xr make 1 , 255d83c779aSSascha Wildnerthe compiler and the linker. 256d83c779aSSascha Wildner.Sh SEE ALSO 2573cd583efSSascha Wildner.Xr kld 4 , 2583cd583efSSascha Wildner.Xr module 9 259d83c779aSSascha Wildner.Pp 260d83c779aSSascha Wildner.Pa /usr/share/examples/kld/firmware 26139c15c2bSSascha Wildner.Sh HISTORY 26239c15c2bSSascha WildnerThe 26339c15c2bSSascha Wildner.Nm firmware 264d83c779aSSascha Wildnersystem was introduced in 265d83c779aSSascha Wildner.Fx 6.1 . 26639c15c2bSSascha Wildner.Sh AUTHORS 267d83c779aSSascha WildnerThis manual page was written by 268c616d378SFranco Fichtner.An Max Laier Aq Mt mlaier@FreeBSD.org . 269