| Commit | Line | Data |
|---|---|---|
| d83c779a SW |
1 | .\" Copyright (c) 2006 Max Laier <mlaier@FreeBSD.org> |
| 2 | .\" All rights reserved. | |
| 39c15c2b SW |
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: | |
| 39c15c2b SW |
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 | |
| d83c779a SW |
10 | .\" notice, this list of conditions and the following disclaimer in the |
| 11 | .\" documentation and/or other materials provided with the distribution. | |
| 39c15c2b | 12 | .\" |
| d83c779a SW |
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. | |
| 39c15c2b | 23 | .\" |
| d83c779a | 24 | .\" $FreeBSD: src/share/man/man9/firmware.9,v 1.9 2010/04/14 19:08:06 uqs Exp $ |
| 39c15c2b | 25 | .\" |
| d83c779a | 26 | .Dd April 14, 2010 |
| 39c15c2b SW |
27 | .Dt FIRMWARE 9 |
| 28 | .Os | |
| 29 | .Sh NAME | |
| d83c779a SW |
30 | .Nm firmware_register , |
| 31 | .Nm firmware_unregister , | |
| 32 | .Nm firmware_get , | |
| 33 | .Nm firmware_put | |
| 34 | .Nd firmware image loading and management | |
| 39c15c2b | 35 | .Sh SYNOPSIS |
| d83c779a SW |
36 | .In sys/param.h |
| 37 | .In sys/systm.h | |
| 38 | .In sys/linker.h | |
| 39c15c2b | 39 | .In sys/firmware.h |
| d83c779a SW |
40 | .Bd -literal |
| 41 | struct firmware { | |
| 42 | const char *name; /* system-wide name */ | |
| 43 | const void *data; /* location of image */ | |
| 44 | size_t datasize; /* size of image in bytes */ | |
| 45 | unsigned int version; /* version of the image */ | |
| 46 | }; | |
| 47 | .Ed | |
| 48 | .Ft "const struct firmware *" | |
| 49 | .Fo firmware_register | |
| 50 | .Fa "const char *imagename" | |
| 51 | .Fa "const void *data" | |
| 52 | .Fa "size_t datasize" | |
| 53 | .Fa "unsigned int version" | |
| 54 | .Fa "const struct firmware *parent" | |
| 55 | .Fc | |
| 56 | .Ft int | |
| 57 | .Fn firmware_unregister "const char *imagename" | |
| 58 | .Ft "const struct firmware *" | |
| 59 | .Fn firmware_get "const char *imagename" | |
| 39c15c2b | 60 | .Ft void |
| d83c779a | 61 | .Fn firmware_put "const struct firmware *fp" "int flags" |
| 39c15c2b SW |
62 | .Sh DESCRIPTION |
| 63 | The | |
| 64 | .Nm firmware | |
| d83c779a SW |
65 | abstraction provides a convenient interface for loading |
| 66 | .Nm firmware images | |
| 67 | into the kernel, and for accessing such images from kernel components. | |
| 39c15c2b | 68 | .Pp |
| d83c779a SW |
69 | A |
| 70 | .Nm firmware image | |
| 71 | (or | |
| 72 | .Nm image | |
| 73 | for brevity) | |
| 74 | is an opaque block of data residing in kernel memory. | |
| 75 | It is associated to a unique | |
| 76 | .Nm imagename | |
| 77 | which constitutes a search key, and to an integer | |
| 78 | .Nm version | |
| 79 | number, which is also an opaque piece of information for the | |
| 80 | firmware subsystem. | |
| 81 | .Pp | |
| 82 | An image is registered with the | |
| 83 | .Nm firmware | |
| 84 | subsystem by calling the function | |
| 85 | .Fn firmware_register , | |
| 86 | and unregistered by calling | |
| 87 | .Fn firmware_unregister . | |
| 88 | These functions are usually (but not exclusively) called by | |
| 89 | specially crafted kernel modules that contain the firmware image. | |
| 90 | The modules can be statically compiled in the kernel, or loaded by | |
| 91 | .Nm /boot/loader , | |
| 92 | manually at runtime, or on demand by the firmware subsystem. | |
| 93 | .Pp | |
| 94 | .Nm Clients | |
| 95 | of the firmware subsystem can request access to a given image | |
| 96 | by calling the function | |
| 97 | .Fn firmware_get | |
| 98 | with the | |
| 99 | .Nm imagename | |
| 100 | they want as an argument. If a matching image is not already registered, | |
| 101 | the firmware subsystem will try to load it using the | |
| 102 | mechanisms specified below (typically, a kernel module | |
| 103 | with | |
| 104 | .Nm the same name | |
| 105 | as the image). | |
| 106 | .Sh API DESCRIPTION | |
| 107 | The kernel | |
| 108 | .Nm firmware API | |
| 109 | is made of the following functions: | |
| 110 | .Pp | |
| 111 | .Fn firmware_register | |
| 112 | registers with the kernel an image of size | |
| 113 | .Nm datasize | |
| 114 | located at address | |
| 115 | .Nm data , | |
| 116 | under the name | |
| 117 | .Nm imagename . | |
| 118 | .Pp | |
| 119 | The function returns NULL on error (e.g. because an | |
| 120 | image with the same name already exists, or the image | |
| 121 | table is full), or a | |
| 122 | .Ft const struct firmware * | |
| 123 | pointer to the image requested. | |
| 124 | .Pp | |
| 125 | .Fn firmware_unregister | |
| 126 | tries to unregister the firmware image | |
| 127 | .Nm imagename | |
| 128 | from the system. The function is successful and returns 0 | |
| 129 | if there are no pending references to the image, otherwise | |
| 1f3e7f4c SW |
130 | it does not unregister the image and returns |
| 131 | .Er EBUSY . | |
| d83c779a SW |
132 | .Pp |
| 133 | .Fn firmware_get | |
| 134 | returns the requested firmware image. | |
| 135 | If the image is not yet registered with the system, | |
| 136 | the function tries to load it. | |
| 137 | This involves the linker subsystem and disk access, so | |
| 138 | .Fn firmware_get | |
| 139 | must not be called with any locks (except for | |
| 140 | .Va Giant ) . | |
| 141 | Note also that if the firmware image is loaded from a filesystem | |
| 142 | it must already be mounted. | |
| 143 | In particular this means that it may be necessary to defer requests | |
| 144 | from a driver attach method unless it is known the root filesystem is | |
| 145 | already mounted. | |
| 146 | .Pp | |
| 147 | On success, | |
| 148 | .Fn firmware_get | |
| 149 | returns a pointer to the image description and increases the reference count | |
| 150 | for this image. On failure, the function returns NULL. | |
| 151 | .Pp | |
| 152 | .Fn firmware_put | |
| 153 | drops a reference to a firmware image. | |
| 39c15c2b | 154 | The |
| d83c779a SW |
155 | .Fa flags |
| 156 | argument may be set to | |
| 157 | .Dv FIRMWARE_UNLOAD | |
| 158 | to indicate that | |
| 159 | firmware_put is free to reclaim resources associated with | |
| 160 | the firmware image if this is the last reference. | |
| 161 | By default a firmware image will be deferred to a | |
| 162 | .Xr taskqueue 9 | |
| 163 | thread so the call may be done while holding a lock. | |
| 164 | In certain cases, such as on driver detach, this cannot be allowed. | |
| 165 | .Sh FIRMWARE LOADING MECHANISMS | |
| 166 | As mentioned before, any component of the system can register | |
| 167 | firmware images at any time by simply calling | |
| 168 | .Fn firmware_register . | |
| 169 | .Pp | |
| 170 | This is typically done when a module containing | |
| 171 | a firmware image is given control, | |
| 172 | whether compiled in, or preloaded by | |
| 173 | .Nm /boot/loader , | |
| 174 | or manually loaded with | |
| 175 | .Xr kldload 8 . | |
| 176 | However, a system can implement additional mechanisms to bring | |
| 177 | these images in memory before calling | |
| 178 | .Fn firmware_register . | |
| 179 | .Pp | |
| 180 | When | |
| 181 | .Fn firmware_get | |
| 182 | does not find the requested image, it tries to load it using | |
| 183 | one of the available loading mechanisms. | |
| 184 | At the moment, there is only one, namely | |
| 185 | .Nm Loadable kernel modules : | |
| 186 | .Pp | |
| 187 | A firmware image named | |
| 188 | .Nm foo | |
| 189 | is looked up by trying to load the module named | |
| 190 | .Nm foo.ko , | |
| 191 | using the facilities described in | |
| 192 | .Xr kld 4 . | |
| 193 | In particular, images are looked up in the directories specified | |
| 194 | by the sysctl variable | |
| 195 | .Nm kern.module_path | |
| 196 | which on most systems defaults to | |
| 197 | .Nm /boot/kernel;/boot/modules . | |
| 198 | .Pp | |
| 199 | Note that in case a module contains multiple images, | |
| 200 | the caller should first request a | |
| 201 | .Fn firmware_get | |
| 202 | for the first image contained in the module, followed by requests | |
| 203 | for the other images. | |
| 204 | .Sh BUILDING FIRMWARE LOADABLE MODULES | |
| 205 | A firmware module is built by embedding the | |
| 206 | .Nm firmware image | |
| 207 | into a suitable loadable kernel module that calls | |
| 208 | .Fn firmware_register | |
| 209 | on loading, and | |
| 210 | .Fn firmware_unregister | |
| 211 | on unloading. | |
| 212 | .Pp | |
| 213 | Various system scripts and makefiles let you build a module | |
| 214 | by simply writing a Makefile with the following entries: | |
| 215 | .Bd -literal | |
| 216 | ||
| 217 | KMOD= imagename | |
| 218 | FIRMWS= image_file:imagename[:version] | |
| 219 | .include <bsd.kmod.mk> | |
| 220 | ||
| 221 | .Ed | |
| 222 | where KMOD is the basename of the module; FIRMWS is a list of | |
| 223 | colon-separated tuples indicating the image_file's to be embedded | |
| 224 | in the module, the imagename and version of each firmware image. | |
| 225 | .Pp | |
| 226 | If you need to embed firmware images into a system, you should write | |
| 227 | appropriate entries in the <files.arch> file, e.g. this example is | |
| 228 | from | |
| 229 | .Nm sys/arm/xscale/ixp425/files.ixp425: | |
| 230 | .Bd -literal | |
| 231 | ixp425_npe_fw.c optional npe_fw \\ | |
| 232 | compile-with "${AWK} -f $S/tools/fw_stub.awk \\ | |
| 233 | IxNpeMicrocode.dat:npe_fw -mnpe -c${.TARGET}" \\ | |
| 234 | no-implicit-rule before-depend local \\ | |
| 235 | clean "ixp425_npe_fw.c" | |
| 236 | # | |
| 237 | # NB: ld encodes the path in the binary symbols generated for the | |
| 238 | # firmware image so link the file to the object directory to | |
| 239 | # get known values for reference in the _fw.c file. | |
| 240 | # | |
| 241 | IxNpeMicrocode.fwo optional npe_fw \\ | |
| 242 | dependency "IxNpeMicrocode.dat" \\ | |
| 243 | compile-with "${LD} -b binary -d -warn-common \\ | |
| 244 | -r -d -o ${.TARGET} IxNpeMicrocode.dat" \\ | |
| 245 | no-implicit-rule \\ | |
| 246 | clean "IxNpeMicrocode.fwo" | |
| 247 | IxNpeMicrocode.dat optional npe_fw \\ | |
| 248 | dependency ".PHONY" \\ | |
| 249 | compile-with "uudecode < $S/contrib/dev/npe/IxNpeMicrocode.dat.uu" \\ | |
| 250 | no-obj no-implicit-rule \\ | |
| 251 | clean "IxNpeMicrocode.dat" | |
| 252 | .Ed | |
| 253 | .Pp | |
| 254 | Note that generating the firmware modules in this way requires | |
| 255 | the availability of the following tools: | |
| 1f3e7f4c SW |
256 | .Xr awk 1 , |
| 257 | .Xr make 1 , | |
| d83c779a SW |
258 | the compiler and the linker. |
| 259 | .Sh SEE ALSO | |
| 260 | .Xr module 9 , | |
| 261 | .Xr kld 4 | |
| 262 | .Pp | |
| 263 | .Pa /usr/share/examples/kld/firmware | |
| 39c15c2b SW |
264 | .Sh HISTORY |
| 265 | The | |
| 266 | .Nm firmware | |
| d83c779a SW |
267 | system was introduced in |
| 268 | .Fx 6.1 . | |
| 39c15c2b | 269 | .Sh AUTHORS |
| d83c779a SW |
270 | This manual page was written by |
| 271 | .An Max Laier Aq mlaier@FreeBSD.org . |