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