xref: /freebsd/share/man/man9/firmware.9 (revision ddb53abcd978e2cb048625da4d3aedbe6b26e1ea)
16aec1278SMax Laier.\" Copyright (c) 2006 Max Laier <mlaier@FreeBSD.org>
26aec1278SMax Laier.\" All rights reserved.
36aec1278SMax Laier.\"
46aec1278SMax Laier.\" Redistribution and use in source and binary forms, with or without
56aec1278SMax Laier.\" modification, are permitted provided that the following conditions
66aec1278SMax Laier.\" are met:
76aec1278SMax Laier.\" 1. Redistributions of source code must retain the above copyright
86aec1278SMax Laier.\"    notice, this list of conditions and the following disclaimer.
96aec1278SMax Laier.\" 2. Redistributions in binary form must reproduce the above copyright
106aec1278SMax Laier.\"    notice, this list of conditions and the following disclaimer in the
116aec1278SMax Laier.\"    documentation and/or other materials provided with the distribution.
126aec1278SMax Laier.\"
136aec1278SMax Laier.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
146aec1278SMax Laier.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
156aec1278SMax Laier.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
166aec1278SMax Laier.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
176aec1278SMax Laier.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
186aec1278SMax Laier.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
196aec1278SMax Laier.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
206aec1278SMax Laier.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
216aec1278SMax Laier.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
226aec1278SMax Laier.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
236aec1278SMax Laier.\"
246aec1278SMax Laier.\" $FreeBSD$
256aec1278SMax Laier.\"
266aec1278SMax Laier.Dd January 6, 2006
276aec1278SMax Laier.Os
286aec1278SMax Laier.Dt FIRMWARE 9
296aec1278SMax Laier.Sh NAME
306aec1278SMax Laier.Nm firmware_register ,
316aec1278SMax Laier.Nm firmware_unregister ,
326aec1278SMax Laier.Nm firmware_get ,
336aec1278SMax Laier.Nm firmware_put
346aec1278SMax Laier.Nd firmware image loading and management
356aec1278SMax Laier.Sh SYNOPSIS
366aec1278SMax Laier.In sys/param.h
37dad5bb64SMax Laier.In sys/systm.h
386aec1278SMax Laier.In sys/linker.h
396aec1278SMax Laier.In sys/firmware.h
406aec1278SMax Laier.Bd -literal
416aec1278SMax Laierstruct firmware {
426aec1278SMax Laier	const char	*name;		/* system-wide name */
436aec1278SMax Laier	const void	*data;		/* location of image */
446aec1278SMax Laier	size_t		datasize;	/* size of image in bytes */
456aec1278SMax Laier	unsigned int	version;	/* version of the image */
466aec1278SMax Laier};
476aec1278SMax Laier.Ed
48ddb53abcSLuigi Rizzo.Ft "const struct firmware *"
496aec1278SMax Laier.Fo firmware_register
506aec1278SMax Laier.Fa "const char *imagename"
516aec1278SMax Laier.Fa "const void *data"
526aec1278SMax Laier.Fa "size_t datasize"
536aec1278SMax Laier.Fa "unsigned int version"
54ddb53abcSLuigi Rizzo.Fa "const struct firmware *parent"
556aec1278SMax Laier.Fc
566aec1278SMax Laier.Ft int
576aec1278SMax Laier.Fn firmware_unregister "const char *imagename"
58ddb53abcSLuigi Rizzo.Ft "const struct firmware *"
596aec1278SMax Laier.Fn firmware_get "const char *imagename"
606aec1278SMax Laier.Ft void
61ddb53abcSLuigi Rizzo.Fn firmware_put "const struct firmware *fp" "int flags"
626aec1278SMax Laier.Sh DESCRIPTION
63bd84dd2fSRuslan ErmilovThe
64bd84dd2fSRuslan Ermilov.Nm firmware
6597070dd5SLuigi Rizzoabstraction provides a convenient interface for loading
6697070dd5SLuigi Rizzo.Nm firmware images
6797070dd5SLuigi Rizzointo the kernel, and for accessing such images from kernel components.
686aec1278SMax Laier.Pp
6997070dd5SLuigi RizzoA
7097070dd5SLuigi Rizzo.Nm firmware image
7197070dd5SLuigi Rizzo(or
7297070dd5SLuigi Rizzo.Nm image
7397070dd5SLuigi Rizzofor brevity)
7497070dd5SLuigi Rizzois an opaque block of data residing in kernel memory.
7597070dd5SLuigi RizzoIt is associated to a unique
7697070dd5SLuigi Rizzo.Nm imagename
7797070dd5SLuigi Rizzowhich constitutes a search key, and to an integer
7897070dd5SLuigi Rizzo.Nm version
7997070dd5SLuigi Rizzonumber, which is also an opaque piece of information for the
8097070dd5SLuigi Rizzofirmware subsystem.
8197070dd5SLuigi Rizzo.Pp
8297070dd5SLuigi RizzoAn image is registered with the
83bd84dd2fSRuslan Ermilov.Nm firmware
8497070dd5SLuigi Rizzosubsystem by calling the function
8597070dd5SLuigi Rizzo.Fn firmware_register ,
8697070dd5SLuigi Rizzoand unregistered by calling
8797070dd5SLuigi Rizzo.Fn firmware_unregister .
88ddb53abcSLuigi RizzoThese functions are usually (but not exclusively) called by
8997070dd5SLuigi Rizzospecially crafted kernel modules that contain the firmware image.
9097070dd5SLuigi RizzoThe modules can be statically compiled in the kernel, or loaded by
9197070dd5SLuigi Rizzo.Nm /boot/loader ,
9297070dd5SLuigi Rizzomanually at runtime, or on demand by the firmware subsystem.
936aec1278SMax Laier.Pp
9497070dd5SLuigi Rizzo.Nm Clients
9597070dd5SLuigi Rizzoof the firmware subsystem can request access to a given image
9697070dd5SLuigi Rizzoby calling the function
9797070dd5SLuigi Rizzo.Fn firmware_get
9897070dd5SLuigi Rizzowith the
9997070dd5SLuigi Rizzo.Nm imagename
10097070dd5SLuigi Rizzothey want as an argument. If a matching image is not already registered,
10197070dd5SLuigi Rizzothe firmware subsystem will try to load it using the
10297070dd5SLuigi Rizzomechanisms specified below (typically, a kernel module
10397070dd5SLuigi Rizzowith
10497070dd5SLuigi Rizzo.Nm the same name
10597070dd5SLuigi Rizzoas the image).
10697070dd5SLuigi Rizzo.Sh API DESCRIPTION
10797070dd5SLuigi RizzoThe kernel
10897070dd5SLuigi Rizzo.Nm firmware API
10997070dd5SLuigi Rizzois made of the following functions:
11097070dd5SLuigi Rizzo.Pp
11197070dd5SLuigi Rizzo.Fn firmware_register
11297070dd5SLuigi Rizzoregisters with the kernel an image of size
11397070dd5SLuigi Rizzo.Nm datasize
11497070dd5SLuigi Rizzolocated at address
11597070dd5SLuigi Rizzo.Nm data ,
11697070dd5SLuigi Rizzounder the name
11797070dd5SLuigi Rizzo.Nm imagename .
11897070dd5SLuigi Rizzo.Pp
11997070dd5SLuigi RizzoThe function returns NULL on error (e.g. because an
12097070dd5SLuigi Rizzoimage with the same name already exists, or the image
12197070dd5SLuigi Rizzotable is full), or a
12297070dd5SLuigi Rizzo.Ft const struct firmware *
12397070dd5SLuigi Rizzopointer to the image requested.
12497070dd5SLuigi Rizzo.Pp
1256aec1278SMax Laier.Fn firmware_unregister
12697070dd5SLuigi Rizzotries to unregister the firmware image
12797070dd5SLuigi Rizzo.Nm imagename
12897070dd5SLuigi Rizzofrom the system. The function is successful and returns 0
12997070dd5SLuigi Rizzoif there are no pending references to the image, otherwise
13097070dd5SLuigi Rizzoit does not unregister the image and returns EBUSY.
1316aec1278SMax Laier.Pp
1326aec1278SMax Laier.Fn firmware_get
1336aec1278SMax Laierreturns the requested firmware image.
134bd84dd2fSRuslan ErmilovIf the image is not yet registered with the system,
13597070dd5SLuigi Rizzothe function tries to load it.
13697070dd5SLuigi RizzoThis involves the linker subsystem and disk access, so
1376aec1278SMax Laier.Fn firmware_get
138bd84dd2fSRuslan Ermilovmust not be called with any locks (except for
139bd84dd2fSRuslan Ermilov.Va Giant ) .
14097070dd5SLuigi RizzoThe caller must also have a process context so filesystem state such as
14197070dd5SLuigi Rizzothe root vnode is defined (e.g. you cannot load from a taskqueue thread).
14297070dd5SLuigi Rizzo.Pp
143bd84dd2fSRuslan ErmilovOn success,
1446aec1278SMax Laier.Fn firmware_get
1456aec1278SMax Laierreturns a pointer to the image description and increases the reference count
14697070dd5SLuigi Rizzofor this image. On failure, the function returns NULL.
1476aec1278SMax Laier.Pp
1486aec1278SMax Laier.Fn firmware_put
14997070dd5SLuigi Rizzodrops a reference to a firmware image.
150bd84dd2fSRuslan ErmilovThe
151bd84dd2fSRuslan Ermilov.Fa flags
152bd84dd2fSRuslan Ermilovargument may be set to
1536aec1278SMax Laier.Dv FIRMWARE_UNLOAD
15497070dd5SLuigi Rizzoto indicate that
15597070dd5SLuigi Rizzofirmware_put is free to reclaim resources associated with
15697070dd5SLuigi Rizzothe firmware image if this is the last reference.
15797070dd5SLuigi Rizzo.Sh FIRMWARE LOADING MECHANISMS
15897070dd5SLuigi RizzoAs mentioned before, any component of the system can register
15997070dd5SLuigi Rizzofirmware images at any time by simply calling
16097070dd5SLuigi Rizzo.Fn firmware_register .
1616aec1278SMax Laier.Pp
16297070dd5SLuigi RizzoThis is typically done when a module containing
16397070dd5SLuigi Rizzoa firmware image is given control,
16497070dd5SLuigi Rizzowhether compiled in, or preloaded by
16597070dd5SLuigi Rizzo.Nm /boot/loader ,
16697070dd5SLuigi Rizzoor manually loaded with
16797070dd5SLuigi Rizzo.Xr kldload 8 .
16897070dd5SLuigi RizzoHowever, a system can implement additional mechanisms to bring
16997070dd5SLuigi Rizzothese images in memory before calling
17097070dd5SLuigi Rizzo.Fn firmware_register .
17197070dd5SLuigi Rizzo.Pp
17297070dd5SLuigi RizzoWhen
17397070dd5SLuigi Rizzo.Fn firmware_get
17497070dd5SLuigi Rizzodoes not find the requested image, it tries to load it using
17597070dd5SLuigi Rizzoone of the available loading mechanisms.
17697070dd5SLuigi RizzoAt the moment, there is only one, namely
17797070dd5SLuigi Rizzo.Nm Loadable kernel modules :
17897070dd5SLuigi Rizzo.Pp
17997070dd5SLuigi RizzoA firmware image named
18097070dd5SLuigi Rizzo.Nm foo
18197070dd5SLuigi Rizzois looked up by trying to load the module named
18297070dd5SLuigi Rizzo.Nm foo.ko ,
18397070dd5SLuigi Rizzousing the facilities described in
18497070dd5SLuigi Rizzo.Xr kld 4 .
18597070dd5SLuigi RizzoIn particular, images are looked up in the directories specified
18697070dd5SLuigi Rizzoby the sysctl variable
18797070dd5SLuigi Rizzo.Nm kern.module_path
18897070dd5SLuigi Rizzowhich on most systems defaults to
18997070dd5SLuigi Rizzo.Nm /boot/kernel;/boot/modules .
19097070dd5SLuigi Rizzo.Pp
19197070dd5SLuigi RizzoNote that in case a module contains multiple images,
19297070dd5SLuigi Rizzothe caller should first request a
19397070dd5SLuigi Rizzo.Fn firmware_get
19497070dd5SLuigi Rizzofor the first image contained in the module, followed by requests
19597070dd5SLuigi Rizzofor the other images.
19697070dd5SLuigi Rizzo.Sh BUILDING FIRMWARE LOADABLE MODULES
19797070dd5SLuigi RizzoA firmware module is built by embedding the
19897070dd5SLuigi Rizzo.Nm firmware image
19997070dd5SLuigi Rizzointo a suitable loadable kernel module that calls
20097070dd5SLuigi Rizzo.Fn firmware_register
20197070dd5SLuigi Rizzoon loading, and
20297070dd5SLuigi Rizzo.Fn firmware_unregister
20397070dd5SLuigi Rizzoon unloading.
20497070dd5SLuigi Rizzo.Pp
20597070dd5SLuigi RizzoVarious system scripts and makefiles let you build a module
20697070dd5SLuigi Rizzoby simply writing a Makefile with the following entries:
20797070dd5SLuigi Rizzo.Bd -literal
20897070dd5SLuigi Rizzo
20997070dd5SLuigi Rizzo        KMOD=   imagename
21097070dd5SLuigi Rizzo        FIRMWS= image_file:imagename[:version]
21197070dd5SLuigi Rizzo        .include <bsd.kmod.mk>
21297070dd5SLuigi Rizzo
21397070dd5SLuigi Rizzo.Ed
21497070dd5SLuigi Rizzowhere KMOD is the basename of the module; FIRMWS is a list of
21597070dd5SLuigi Rizzocolon-separated tuples indicating the image_file's to be embedded
21697070dd5SLuigi Rizzoin the module, the imagename and version of each firmware image.
21797070dd5SLuigi Rizzo.Pp
21897070dd5SLuigi RizzoIf you need to embed firmware images into a system, you should write
21997070dd5SLuigi Rizzoappropriate entries in the <files.arch> file, e.g. this example is
22097070dd5SLuigi Rizzofrom
22197070dd5SLuigi Rizzo.Nm sys/arm/xscale/ixp425/files.ixp425:
22297070dd5SLuigi Rizzo.Bd -literal
22397070dd5SLuigi Rizzoixp425_npe_fw.c                         optional npe_fw                 \\
22497070dd5SLuigi Rizzo        compile-with    "${AWK} -f $S/tools/fw_stub.awk			\\
22597070dd5SLuigi Rizzo			IxNpeMicrocode.dat:npe_fw -mnpe -c${.TARGET}"	\\
22697070dd5SLuigi Rizzo        no-implicit-rule before-depend local                            \\
22797070dd5SLuigi Rizzo        clean           "ixp425_npe_fw.c"
22897070dd5SLuigi Rizzo#
22997070dd5SLuigi Rizzo# NB: ld encodes the path in the binary symbols generated for the
23097070dd5SLuigi Rizzo#     firmware image so link the file to the object directory to
23197070dd5SLuigi Rizzo#     get known values for reference in the _fw.c file.
23297070dd5SLuigi Rizzo#
23397070dd5SLuigi RizzoIxNpeMicrocode.fwo  optional npe_fw					\\
23497070dd5SLuigi Rizzo        dependency      "IxNpeMicrocode.dat"				\\
23597070dd5SLuigi Rizzo        compile-with    "${LD} -b binary -d -warn-common		\\
23697070dd5SLuigi Rizzo			    -r -d -o ${.TARGET} IxNpeMicrocode.dat"	\\
23797070dd5SLuigi Rizzo        no-implicit-rule                                                \\
23897070dd5SLuigi Rizzo        clean           "IxNpeMicrocode.fwo"
23997070dd5SLuigi RizzoIxNpeMicrocode.dat                      optional npe_fw                 \\
24097070dd5SLuigi Rizzo        dependency      ".PHONY"                                        \\
24197070dd5SLuigi Rizzo        compile-with    "if [ -e $S/arm/xscale/ixp425/IxNpeMicrocode.dat ]; \\
24297070dd5SLuigi Rizzo			then						\\
24397070dd5SLuigi Rizzo			ln -sf $S/arm/xscale/ixp425/IxNpeMicrocode.dat .; \\
24497070dd5SLuigi Rizzo			else echo 'WARNING, no IxNpeMicrocode.dat file; you must obtain this from the Intel web site'; false; \\
24597070dd5SLuigi Rizzo			fi" \\
24697070dd5SLuigi Rizzo        no-obj no-implicit-rule                                         \\
24797070dd5SLuigi Rizzo        clean           "IxNpeMicrocode.dat"
24897070dd5SLuigi Rizzo.Ed
24997070dd5SLuigi Rizzo.Pp
25097070dd5SLuigi RizzoNote that generating the firmware modules in this way requires
25197070dd5SLuigi Rizzothe availability of the following tools:
25297070dd5SLuigi Rizzo.Xr awk ,
25397070dd5SLuigi Rizzo.Xr Make ,
25497070dd5SLuigi Rizzothe compiler and the linker.
25597070dd5SLuigi Rizzo.Sh SEE ALSO
25697070dd5SLuigi Rizzo.Xr module 9 ,
25797070dd5SLuigi Rizzo.Xr kld 4
25897070dd5SLuigi Rizzo.Pp
25997070dd5SLuigi Rizzo.Pa /usr/share/examples/kld/firmware
2606aec1278SMax Laier.Sh HISTORY
261bd84dd2fSRuslan ErmilovThe
262bd84dd2fSRuslan Ermilov.Nm firmware
263bd84dd2fSRuslan Ermilovsystem was introduced in
264999b97c5SHiroki Sato.Fx 6.1 .
2656aec1278SMax Laier.Sh AUTHORS
2666aec1278SMax LaierThis manual page was written by
2676aec1278SMax Laier.An Max Laier Aq mlaier@FreeBSD.org .
268