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