source: postlfs/config/firmware.xml@ fa3edfef

10.0 10.1 11.0 11.1 11.2 11.3 12.0 12.1 kea ken/TL2024 ken/inkscape-core-mods ken/tuningfonts lazarus lxqt plabs/newcss plabs/python-mods python3.11 qt5new rahul/power-profiles-daemon renodr/vulkan-addition trunk upgradedb xry111/intltool xry111/llvm18 xry111/soup3 xry111/test-20220226 xry111/xf86-video-removal
Last change on this file since fa3edfef was 6e493187, checked in by Pierre Labastie <pieere@…>, 4 years ago

Add early loading of microcode to the initramfs
Fix a bug in mkinitramfs, leading to a "cp" error

git-svn-id: svn://svn.linuxfromscratch.org/BLFS/trunk/BOOK@22557 af4574ff-66df-0310-9fd7-8a98e5e911e0

  • Property mode set to 100644
File size: 23.6 KB
Line 
1<?xml version="1.0" encoding="ISO-8859-1"?>
2<!DOCTYPE sect1 PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
3 "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
4 <!ENTITY % general-entities SYSTEM "../../general.ent">
5 %general-entities;
6]>
7
8<sect1 id="postlfs-firmware" xreflabel="About Firmware">
9 <?dbhtml filename="firmware.html"?>
10
11 <sect1info>
12 <othername>$LastChangedBy$</othername>
13 <date>$Date$</date>
14 </sect1info>
15
16 <title>About Firmware</title>
17
18 <indexterm zone="postlfs-firmware">
19 <primary sortas="e-lib-firmware">/lib/firmware</primary>
20 </indexterm>
21
22 <para> On some recent PCs it can be necessary, or desirable, to load firmware
23 to make them work at their best. There is a directory, <filename
24 class="directory">/lib/firmware</filename>, where the kernel or kernel
25 drivers look for firmware images.</para>
26
27 <para>Preparing firmware for multiple different machines, as a distro would
28 do, is outside the scope of this book.</para>
29
30 <para>Currently, most firmware can be found at a <userinput>git</userinput>
31 repository: <ulink
32 url="http://git.kernel.org/cgit/linux/kernel/git/firmware/linux-firmware.git/tree/"/>.
33 For convenience, the LFS Project has created a mirror, updated daily, where
34 these firmware files can be accessed via <userinput>wget</userinput> or a web
35 browser at <ulink
36 url="&sources-anduin-http;/linux-firmware/"/>.</para>
37
38 <para>To get the firmware, either point a browser to one of the above
39 repositories and then download the item(s) which you need, or install
40 <userinput>git</userinput> and clone that repository.</para>
41
42 <para>For some other firmware, particularly for Intel microcode and certain
43 wifi devices, the needed firmware is not available in the above repository.
44 Some of this will be addressed below, but a search of the Internet for needed
45 firmware is sometimes necessary.</para>
46
47 <para>Firmware files are conventionally referred to as blobs because you cannot
48 determine what they will do. Note that firmware is distributed under various
49 different licenses which do not permit disassembly or reverse-engineering.</para>
50
51 <para>Firmware for PCs falls into four categories:</para>
52
53 <itemizedlist spacing="compact">
54 <listitem>
55 <para>Updates to the CPU to work around errata, usually referred to as
56 microcode.</para>
57 </listitem>
58 <listitem>
59 <para>Firmware for video controllers. On x86 machines this seems to mostly
60 apply to ATI devices (Radeon and AMDGPU chips) and Nvidia
61 Maxwell and Pascal cards which all require firmware to be able to use KMS
62 (kernel modesetting - the preferred option) as well as for Xorg. For
63 earlier radeon chips (before the R600), the firmware is still in the
64 kernel.</para>
65 </listitem>
66 <listitem>
67 <para>Firmware updates for wired network ports. Mostly they work even
68 without the updates, but probably they will work better with
69 the updated firmware. For some modern laptops, firmware for both
70 wired ethernet (e.g. rtl_nic) and also for bluetooth devices (e.g. qca)
71 is <emphasis>required</emphasis> before the wired network can be used.
72 </para>
73 </listitem>
74 <listitem>
75 <para>Firmware for other devices, such as wifi. These devices are not
76 required for the PC to boot, but need the firmware before these devices
77 can be used.</para>
78 </listitem>
79 </itemizedlist>
80
81 <note><para>Although not needed to load a firmware blob, the following
82 tools may be useful for determining, obtaining, or preparing the needed
83 firmware in order to load it into the system:
84 <xref linkend="cpio"/>,
85 <xref linkend="git"/>,
86 <xref linkend="pciutils"/>, and
87 <xref linkend="wget"/></para></note>
88
89 <para condition="html" role="usernotes">User Notes:
90 <ulink url="&blfs-wiki;/aboutfirmware"/></para>
91
92 <sect2 id="cpu-microcode">
93 <title>Microcode updates for CPUs</title>
94
95 <para>In general, microcode can be loaded by the BIOS or UEFI, and it might
96 be updated by upgrading to a newer version of those. On linux, you can also
97 load the microcode from the kernel if you are using an AMD family 10h or
98 later processor (first introduced late 2007), or an Intel processor from
99 1998 and later (Pentium4, Core, etc), if updated microcode has been
100 released. These updates only last until the machine is powered off, so they
101 need to be applied on every boot.</para>
102
103 <para>Intel provide updates of their microcode for SandyBridge and later
104 processors as new vulnerabilities come to light. New versions of AMD
105 firmware are rare and usually only apply to a few models, although
106 motherboard manufacturers get extra updates which maybe update microcode
107 along with the changes to support newer CPUs and faster memory.</para>
108
109 <para>There are two ways of loading the microcode, described as 'early'
110 and 'late'. Early loading happens before userspace has been started, late
111 loading happens after userspace has started. Not surprisingly, early loading
112 is preferred, (see e.g. an explanatory comment in a kernel commit noted at
113 <ulink url="https://lwn.net/Articles/530346/">x86/microcode: Early load
114 microcode </ulink> on LWN.) Indeed, it is needed to work around one
115 particular erratum in early Intel Haswell processors which had TSX enabled.
116 (See <ulink
117 url="http://www.anandtech.com/show/8376/intel-disables-tsx-instructions-erratum-found-in-haswell-haswelleep-broadwellyi/">
118 Intel Disables TSX Instructions: Erratum Found in Haswell, Haswell-E/EP,
119 Broadwell-Y</ulink>.) Without this update glibc can do the wrong thing in
120 uncommon situations. </para>
121
122 <para>It is still possible to manually force late loading of microcode,
123 either for testing or to prevent having to reboot. You will need to
124 reconfigure your kernel for either method. The instructions here will
125 create a kernel <filename>.config</filename> to suite early loading, before
126 forcing late loading to see if there is any microcode. If there is, the
127 instructions then show you how to create an initrd for early loading.</para>
128
129 <para>To confirm what processor(s) you have (if more than one, they will be
130 identical) look in /proc/cpuinfo.</para>
131
132 <sect3 id="intel-microcode">
133 <title>Intel Microcode for the CPU</title>
134
135 <para>The first step is to get the most recent version of the Intel
136 microcode. This must be done by navigating to <ulink
137 url='https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/releases/'/>
138 and downloading the latest file there. As of this writing the most recent
139 version of the microcode is microcode-20191115.
140 Extract this file in the normal way, the microcode is in the <filename>intel-ucode</filename>
141 directory, containing various blobs with names in the form XX-YY-ZZ.
142 There are also various other files, and a releasenote.</para>
143
144 <para>In the past, intel did not provide any details of which blobs had
145 changed versions, but now the release note details this.</para>
146
147 <para>The recent firmware for older processors is provided to deal with
148 vulnerabilities which have now been made public, and for some of these such
149 as Microarchitectural Data Sampling (MDS) you might wish to increase the
150 protection by disabling hyperthreading, or alternatively to disable the
151 kernel's default mitigation because of its impact on compile times. Please
152 read the online documentation at <ulink
153 url='https://www.kernel.org/doc/html/latest/admin-guide/hw-vuln/index.html'/>.
154 </para>
155
156 <para>To be able to use this latest microcode to provide mitigation on all
157 the affected processors, the kernel version needs to be at least 5.3.11 (or
158 4.19.84 if you are using the 4.19 long term support series).</para>
159
160 <para>Now you need to determine your processor's identity to see if there
161 is any microcode for it. Determine the decimal values of the cpu family,
162 model and stepping by running the following command (it will also report
163 the current microcode version):</para>
164
165<screen><userinput>head -n7 /proc/cpuinfo</userinput></screen>
166
167 <para>Convert the cpu family, model and stepping to pairs of hexadecimal
168 digits. For a Skylake i3 6100 (described as Intel(R) Core(TM) i3-6100
169 CPU) the relevant values are cpu family 6, model 94, stepping 3 so in
170 this case the required identification is 06-5e-03. A look at the blobs
171 will show that there is one for this CPU (although for older issues it
172 might have already been applied by the BIOS). If there is a blob for your
173 system then test if it will be applied by copying it (replace &lt;XX-YY-ZZ&gt;
174 by the identifier for your machine) to where the kernel can find it:</para>
175
176<screen><userinput>mkdir -pv /lib/firmware/intel-ucode
177cp -v intel-ucode/&lt;XX-YY-ZZ&gt; /lib/firmware/intel-ucode</userinput></screen>
178
179 <para>Now that the Intel microcode has been prepared, use the following
180 options when you configure the kernel to load Intel
181 microcode:</para>
182
183<screen><literal>General Setup ---&gt;
184 [y] Initial RAM filesystem and RAM disk (initramfs/initrd) support [CONFIG_BLK_DEV_INITRD]
185Processor type and features ---&gt;
186 [y] CPU microcode loading support [CONFIG_MICROCODE]
187 [y] Intel microcode loading support [CONFIG_MICROCODE_INTEL]</literal></screen>
188
189 <para>After you have successfully booted the new system, force late loading by
190 using the command:</para>
191
192<screen><userinput>echo 1 > /sys/devices/system/cpu/microcode/reload</userinput></screen>
193
194 <para>Then use the following command to see if anything was loaded:</para>
195
196<screen><userinput>dmesg | grep -e 'microcode' -e 'Linux version' -e 'Command line'</userinput></screen>
197
198 <para>This reformatted example was created by temporarily booting without
199 microcode, to show the current Firmware Bug message, then the late load
200 shows it being updated to revision 0xd6.</para>
201
202<screen><literal>[ 0.000000] Linux version 5.4.2 (lfs@leshp) (gcc version 9.2.0 (GCC))
203 #1 SMP PREEMPT Wed Dec 18 11:52:13 GMT 2019
204[ 0.000000] Command line: BOOT_IMAGE=/vmlinuz-5.4.2-sda11 root=/dev/sda11 ro
205[ 0.020218] [Firmware Bug]: TSC_DEADLINE disabled due to Errata; please update microcode
206 to version: 0xb2 (or later)
207[ 0.153861] MDS: Vulnerable: Clear CPU buffers attempted, no microcode
208[ 0.550009] microcode: sig=0x506e3, pf=0x2, revision=0x74
209[ 0.550036] microcode: Microcode Update Driver: v2.2.
210[ 277.673064] microcode: updated to revision 0xd6, date = 2019-10-03
211[ 277.674231] x86/CPU: CPU features have changed after loading microcode, but might not take effect</literal></screen>
212
213 <para>If the microcode was not updated, there is no new microcode for
214 this system's processor. If it did get updated, you can now proceed to <xref
215 linkend='early-microcode'/>.</para>
216
217 </sect3>
218
219 <sect3 id="and-microcode">
220 <title>AMD Microcode for the CPU</title>
221
222 <para>Begin by downloading a container of firmware for your CPU family
223 from <ulink
224 url='&sources-anduin-http;/linux-firmware/amd-ucode/'/>.
225 The family is always specified in hex. Families 10h to 14h (16 to 20)
226 are in microcode_amd.bin. Families 15h, 16h and 17h have their own containers.
227 Create the required directory and put the firmware you downloaded into
228 it as the <systemitem class="username">root</systemitem> user:</para>
229
230<screen><userinput>mkdir -pv /lib/firmware/amd-ucode
231cp -v microcode_amd* /lib/firmware/amd-ucode</userinput></screen>
232
233 <para>When you configure the kernel, use the following options
234 to load AMD microcode:</para>
235
236<screen><literal>General Setup ---&gt;
237 [y] Initial RAM filesystem and RAM disk (initramfs/initrd) support [CONFIG_BLK_DEV_INITRD]
238Processor type and features ---&gt;
239 [y] CPU microcode loading support [CONFIG_MICROCODE]
240 [y] AMD microcode loading support [CONFIG_MICROCODE_AMD]</literal></screen>
241
242 <para>After you have successfully booted the new system, force late loading by
243 using the command:</para>
244
245<screen><userinput>echo 1 > /sys/devices/system/cpu/microcode/reload</userinput></screen>
246
247 <para>Then use the following command to see if anything was loaded:</para>
248
249<screen><userinput>dmesg | grep -e 'microcode' -e 'Linux version' -e 'Command line'</userinput></screen>
250 <para>This historic example from an old Athlon(tm) II X2 shows it has been
251 updated. At that time, all CPUs were still reported in the microcode details on
252 AMD machines (the current position for AMD machines where newer microcode is
253 available is unknown) :</para>
254
255<screen><literal>[ 0.000000] Linux version 4.15.3 (ken@testserver) (gcc version 7.3.0 (GCC))
256 #1 SMP Sun Feb 18 02:08:12 GMT 2018
257[ 0.000000] Command line: BOOT_IMAGE=/vmlinuz-4.15.3-sda5 root=/dev/sda5 ro
258[ 0.307619] microcode: CPU0: patch_level=0x010000b6
259[ 0.307671] microcode: CPU1: patch_level=0x010000b6
260[ 0.307743] microcode: Microcode Update Driver: v2.2.
261[ 187.928891] microcode: CPU0: new patch_level=0x010000c8
262[ 187.928899] microcode: CPU1: new patch_level=0x010000c8</literal></screen>
263
264 <para>If the microcode was not updated, there is no new microcode for
265 this system's processor. If it did get updated, you can now proceed to <xref
266 linkend='early-microcode'/>.</para>
267
268 </sect3>
269
270 <sect3 id="early-microcode">
271 <title>Early loading of microcode</title>
272
273 <para>If you have established that updated microcode is available for
274 your system, it is time to prepare it for early loading. This requires
275 an additional package, <xref linkend='cpio'/> and the creation of an
276 initrd which will need to be added to grub.cfg.</para>
277
278 <para>It does not matter where you prepare the initrd, and once it is
279 working you can apply the same initrd to later LFS systems or newer
280 kernels on this same machine, at least until any newer microcode is
281 released. Use the following commands:</para>
282
283<screen><userinput>mkdir -p initrd/kernel/x86/microcode
284cd initrd</userinput></screen>
285
286 <para>For an AMD machine, use the following command (replace
287 &lt;MYCONTAINER&gt; with the name of the container for your CPU's
288 family):</para>
289
290<screen><userinput>cp -v /lib/firmware/amd-ucode/&lt;MYCONTAINER&gt; kernel/x86/microcode/AuthenticAMD.bin</userinput></screen>
291
292 <para>Or for an Intel machine copy the appropriate blob using this command:</para>
293
294<screen><userinput>cp -v /lib/firmware/intel-ucode/&lt;XX-YY-ZZ&gt; kernel/x86/microcode/GenuineIntel.bin</userinput></screen>
295
296 <para>Now prepare the initrd:</para>
297
298<screen><userinput>find . | cpio -o -H newc &gt; /boot/microcode.img</userinput></screen>
299
300 <para>You now need to add a new entry to /boot/grub/grub.cfg and
301 here you should add a new line after the linux line within the stanza.
302 If /boot is a separate mountpoint: </para>
303
304<screen><userinput>initrd /microcode.img</userinput></screen>
305
306 <para>or this if it is not:</para>
307
308<screen><userinput>initrd /boot/microcode.img</userinput></screen>
309
310 <para>If you are already booting with an initrd (see <xref
311 linkend="initramfs"/>), you should run <command>mkinitramfs</command>
312 again after putting the appropriate blob or container into <filename
313 class="directory">/lib/firmware</filename> as explained above.
314 Alternatively, you can have both initrd on the same line, such as
315 <userinput>initrd /microcode.img /other-initrd.img</userinput> (adapt
316 that as above if /boot is not a separate mountpoint).</para>
317
318 <para>You can now reboot with the added initrd, and then use the same
319 command to check that the early load worked.</para>
320
321<screen><userinput>dmesg | grep -e 'microcode' -e 'Linux version' -e 'Command line'</userinput></screen>
322
323 <para>If you updated to address vulnerabilities, you can look at <filename
324 class="directory">/sys/devices/system/cpu/vulnerabilities/</filename> to
325 see what is now reported.</para>
326
327 <para>The places and times where early loading happens are very different
328 in AMD and Intel machines. First, an Intel example with early loading:</para>
329
330<screen><literal>[ 0.000000] microcode: microcode updated early to revision 0xd6, date = 2019-10-03
331[ 0.000000] Linux version 5.4.6 (ken@leshp) (gcc version 9.2.0 (GCC))i
332 #4 SMP PREEMPT Sat Dec 21 21:41:03 GMT 2019
333[ 0.000000] Command line: BOOT_IMAGE=/vmlinuz-5.4.6-sda11 root=/dev/sda11 ro resume=/dev/sda10
334[ 0.579936] microcode: sig=0x506e3, pf=0x2, revision=0xd6
335[ 0.579961] microcode: Microcode Update Driver: v2.2.</literal></screen>
336
337 <para>A historic AMD example:</para>
338
339<screen><literal>[ 0.000000] Linux version 4.15.3 (ken@testserver) (gcc version 7.3.0 (GCC))
340 #2 SMP Sun Feb 18 02:32:03 GMT 2018
341[ 0.000000] Command line: BOOT_IMAGE=/vmlinuz-4.15.3-sda5 root=/dev/sda5 ro
342[ 0.307619] microcode: microcode updated early to new patch_level=0x010000c8
343[ 0.307678] microcode: CPU0: patch_level=0x010000c8
344[ 0.307723] microcode: CPU1: patch_level=0x010000c8
345[ 0.307795] microcode: Microcode Update Driver: v2.2.</literal></screen>
346
347 </sect3>
348
349 </sect2>
350
351 <sect2 id="video-firmware">
352 <title>Firmware for Video Cards</title>
353
354 <sect3 id="ati-video-firmware">
355 <title>Firmware for ATI video chips (R600 and later)</title>
356
357 <para>These instructions do NOT apply to old radeons before the R600
358 family. For those, the firmware is in the kernel's <filename
359 class='directory'>/lib/firmware/</filename> directory. Nor do they apply if
360 you intend to avoid a graphical setup such as Xorg and are content to use
361 the default 80x25 display rather than a framebuffer. </para>
362
363 <para> Early radeon devices only needed a single 2K blob of firmware.
364 Recent devices need several different blobs, and some of them are much
365 bigger. The total size of the radeon firmware directory is over 500K &mdash; on a
366 large modern system you can probably spare the space, but it is still
367 redundant to install all the unused files each time you build a system.</para>
368
369 <para>A better approach is to install <xref linkend='pciutils'/> and then
370 use <userinput>lspci</userinput> to identify which VGA controller is
371 installed.</para>
372
373 <para>With that information, check the RadeonFeature page of the Xorg wiki
374 for <ulink url="http://wiki.x.org/wiki/RadeonFeature/#index5h2">Decoder
375 ring for engineering vs marketing names</ulink> to identify the family (you
376 may need to know this for the Xorg driver in BLFS &mdash; Southern Islands and
377 Sea Islands use the radeonsi driver) and the specific model.</para>
378
379 <para>Now that you know which controller you are using, consult the
380 <ulink url="https://wiki.gentoo.org/wiki/Radeon#Firmware">Radeon</ulink> page
381 of the Gentoo wiki which has a table listing the required firmware blobs
382 for the various chipsets. Note that Southern Islands and Sea Islands chips
383 use different firmware for kernel 3.17 and later compared to earlier
384 kernels. Identify and download the required blobs then install them:</para>
385
386<screen><userinput>mkdir -pv /lib/firmware/radeon
387cp -v &lt;YOUR_BLOBS&gt; /lib/firmware/radeon</userinput></screen>
388
389 <para>There are actually two ways of installing this firmware. BLFS, in the
390 'Kernel Configuration for additional firmware' section part of the <xref
391 linkend="xorg-ati-driver"/> section gives an example of compiling the
392 firmware into the kernel - that is slightly faster to load, but uses more
393 kernel memory. Here we will use the alternative method of making the radeon
394 driver a module. In your kernel config set the following: </para>
395
396<screen><literal>Device Drivers ---&gt;
397 Graphics support ---&gt;
398 Direct Rendering Manager ---&gt;
399 &lt;*&gt; Direct Rendering Manager (XFree86 ... support) [CONFIG_DRM]
400 &lt;m&gt; ATI Radeon [CONFIG_DRM_RADEON]</literal></screen>
401
402 <para>Loading several large blobs from /lib/firmware takes a noticeable
403 time, during which the screen will be blank. If you do not enable the
404 penguin framebuffer logo, or change the console size by using a bigger
405 font, that probably does not matter. If desired, you can slightly
406 reduce the time if you follow the alternate method of specifying 'y' for
407 CONFIG_DRM_RADEON covered in BLFS at the link above &mdash; you must specify each
408 needed radeon blob if you do that.</para>
409
410 </sect3>
411
412 <sect3 id="nvidia-video-firmware">
413 <title>Firmware for Nvidia video chips</title>
414
415 <para>Some Nvidia graphics chips need firmware updates to take advantage
416 of all the card's capability. These are generally the GeForce 8, 9, 9300,
417 and 200-900 series chips. For more exact information, see <ulink
418 url="https://nouveau.freedesktop.org/wiki/VideoAcceleration/#firmware">
419 https://nouveau.freedesktop.org/wiki/VideoAcceleration/#firmware</ulink>.</para>
420
421 <para>First, the kernel Nvidia driver must be activated:</para>
422
423<screen><literal>Device Drivers ---&gt;
424 Graphics support ---&gt;
425 Direct Rendering Manager ---&gt;
426 &lt;*&gt; Direct Rendering Manager (XFree86 ... support) [CONFIG_DRM]
427 &lt;*/m&gt; Nouveau (NVIDIA) cards [CONFIG_DRM_NOUVEAU]</literal></screen>
428
429 <para>The steps to install the Nvidia firmware are:</para>
430
431<screen><userinput>wget https://raw.github.com/imirkin/re-vp2/master/extract_firmware.py
432wget http://us.download.nvidia.com/XFree86/Linux-x86/325.15/NVIDIA-Linux-x86-325.15.run
433sh NVIDIA-Linux-x86-325.15.run --extract-only
434python extract_firmware.py
435mkdir -p /lib/firmware/nouveau
436cp -d nv* vuc-* /lib/firmware/nouveau/</userinput></screen>
437
438 </sect3>
439 </sect2>
440
441 <sect2 id="nic-firmware">
442 <title>Firmware for Network Interfaces</title>
443
444 <para>The kernel likes to load firmware for some network drivers,
445 particularly those from Realtek (the /lib/linux-firmware/rtl_nic/) directory,
446 but they generally appear to work without it. Therefore, you can boot the
447 kernel, check dmesg for messages about this missing firmware, and if
448 necessary download the firmware and put it in the specified directory in
449 /lib/firmware so that it will be found on subsequent boots. Note that with
450 current kernels this works whether or not the driver is compiled in or
451 built as a module, there is no need to build this firmware into the kernel.
452 Here is an example where the R8169 driver has been compiled in but the
453 firmware was not made available. Once the firmware had been provided, there
454 was no mention of it on later boots. </para>
455
456<screen><literal>dmesg | grep firmware | grep r8169
457[ 7.018028] r8169 0000:01:00.0: Direct firmware load for rtl_nic/rtl8168g-2.fw failed with error -2
458[ 7.018036] r8169 0000:01:00.0 eth0: unable to load firmware patch rtl_nic/rtl8168g-2.fw (-2)</literal></screen>
459
460 </sect2>
461
462 <sect2 id="other-firmware">
463 <title>Firmware for Other Devices</title>
464
465 <para> Identifying the correct firmware will typically require you to
466 install <xref linkend='pciutils'/>, and then use
467 <userinput>lspci</userinput> to identify the device. You should then search
468 online to check which module it uses, which firmware, and where to obtain
469 the firmware &mdash; not all of it is in linux-firmware.</para>
470
471 <para>If possible, you should begin by using a wired connection when you
472 first boot your LFS system. To use a wireless connection you will need to
473 use a network tools such as <xref linkend='wireless_tools'/> and <xref
474 linkend='wpa_supplicant'/>.</para>
475
476 <para>Firmware may also be needed for other devices such as some SCSI
477 controllers, bluetooth adaptors, or TV recorders. The same principles
478 apply.</para>
479
480 </sect2>
481
482</sect1>
Note: See TracBrowser for help on using the repository browser.