xref: /dflybsd-src/share/man/man9/firmware.9 (revision d83c779ab2c938232fa7b53777cd18cc9c4fc8e4)
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