source: postlfs/config/firmware.xml@ 2b2de3bd

10.0 10.1 11.0 11.1 11.2 11.3 12.0 12.1 8.1 8.2 8.3 8.4 9.0 9.1 basic bdubbs/svn elogind kea ken/TL2024 ken/inkscape-core-mods ken/tuningfonts lazarus lxqt perl-modules 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 2b2de3bd was a7c5f47, checked in by Ken Moffat <ken@…>, 7 years ago

microcode: mention two initrds where people already use an initrd and now want to add microcode.

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

  • Property mode set to 100644
File size: 23.1 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 only
60 apply to ATI devices : Radeons require firmware to be able to use KMS
61 (kernel modesetting - the preferred option) as well as for Xorg. For
62 earlier radeon chips (before the R600), the firmware is still in the
63 kernel.</para>
64 </listitem>
65 <listitem>
66 <para>Firmware updates for wired network ports. Mostly they work even
67 without the updates, but one must assume that they will work better with
68 the updated firmware.</para>
69 </listitem>
70 <listitem>
71 <para>Firmware for other devices, such as wifi. These devices are not
72 required for the PC to boot, but need the firmware before these devices
73 can be used.</para>
74 </listitem>
75 </itemizedlist>
76
77 <note><para>Although not needed to load a firmware blob, the following
78 tools may be useful for determining, obtaining, or preparing the needed
79 firmware in order to load it into the system:
80 <xref linkend="cpio"/>,
81 <xref linkend="git"/>,
82 <xref linkend="pciutils"/>, and
83 <xref linkend="wget"/></para></note>
84
85 <para condition="html" role="usernotes">User Notes:
86 <ulink url="&blfs-wiki;/aboutfirmware"/></para>
87
88 <sect2 id="cpu-microcode">
89 <title>Microcode updates for CPUs</title>
90
91 <para>In general, microcode can be loaded by the BIOS or UEFI, and it might
92 be updated by upgrading to a newer version of those. On linux, you can also
93 load the microcode from the kernel if you are using an AMD family 10h or
94 later processor (first introduced late 2007), or an Intel processor from
95 1998 and later (Pentium4, Core, etc), if updated microcode has been
96 released. These updates only last until the machine is powered off, so they
97 need to be applied on every boot.</para>
98
99 <para>Intel provide frequent updates of their microcode. It is not uncommon
100 to find a newer version of microcode for an Intel processor even two years
101 after its release. New versions of AMD firmware are less common.</para>
102
103 <para>There used to be two ways of loading the microcode, described as 'early'
104 and 'late'. Early loading happens before userspace has been started, late
105 loading happens after userspace has started. Not surprisingly, early loading
106 was preferred, (see e.g. an explanatory comment in a kernel commit noted at
107 <ulink url="https://lwn.net/Articles/530346/">x86/microcode: Early load
108 microcode </ulink> on LWN.) Indeed, it is needed to work around one
109 particular erratum in early Intel Haswell processors which had TSX enabled.
110 (See <ulink
111 url="http://www.anandtech.com/show/8376/intel-disables-tsx-instructions-erratum-found-in-haswell-haswelleep-broadwellyi/">
112 Intel Disables TSX Instructions: Erratum Found in Haswell, Haswell-E/EP,
113 Broadwell-Y</ulink>.) Without this update glibc can do the wrong thing in
114 uncommon situations. </para>
115
116 <para>As a result, early loading is now expected, although for the moment
117 (4.9 kernels) it is still possible to manually force late loading of
118 microcode for testing. You will need to reconfigure your kernel for either
119 method. The instructions here will create a kernel
120 <filename>.config</filename> to suite early loading, before forcing late
121 loading to see if there is any microcode. If there is, the instructions
122 then show you how to create an initrd for early loading.</para>
123
124 <para>To confirm what processor(s) you have (if more than one, they will be
125 identical) look in /proc/cpuinfo.</para>
126
127 <sect3 id="intel-microcode">
128 <title>Intel Microcode for the CPU</title>
129
130 <bridgehead renderas="sect4">Required File</bridgehead>
131 <para role='required'>
132 <ulink url='&sources-anduin-http;/intel-microcode/intel-microcode2ucode.c'/>
133 </para>
134
135 <para>For Intel CPUs an extra program, intel-microcode2ucode, is required.
136 This is done a little differently since it is only a single source
137 code file. The reason for this is that there are different versions
138 available, but most are specific to commercial distributions.</para>
139
140 <para>This program reformats the microcode supplied by Intel into a
141 format which the kernel can apply. The program
142 <userinput>intel-microcode2ucode</userinput> is used to create the
143 individual firmware blobs </para>
144
145 <para>Create the program by downloading the source file and running:</para>
146
147<screen><userinput>gcc -g -Wall -O2 -o intel-microcode2ucode intel-microcode2ucode.c</userinput></screen>
148
149 <para>Now install the program as the <systemitem class="username">root</systemitem> user:</para>
150
151<screen><userinput>install intel-microcode2ucode /usr/bin</userinput></screen>
152
153 <para>The next step is to get the most recent version of the Intel
154 microcode. This must be done by navigating to
155 <ulink url='https://downloadcenter.intel.com/download/26400/Linux-Processor-Microcode-Data-File'/>
156 and following the instructions there. As of this writing the most recent
157 version of the microcode is <filename>microcode-20161104.tgz</filename>.
158 This file is a tar file, but expands to <filename>microcode.dat</filename>
159 in the current directory.</para>
160
161 <para>Next, create various blobs with names in the form XX-YY-ZZ in a
162 subdirectory named <filename class="directory">intel-ucode/</filename>:
163 </para>
164
165<screen><userinput>intel-microcode2ucode microcode.dat</userinput></screen>
166
167 <para>Now you need to determine your processor's identity to see if there
168 is any microcode for it. Determine the decimal values of the cpu family,
169 model and stepping by running:</para>
170
171<screen><userinput>head -n7 /proc/cpuinfo</userinput></screen>
172
173 <para>Convert the cpu family, model and stepping to pairs of hexadecimal
174 digits. For a Haswell i7-4790 (described as Intel(R) Core(TM) i7-4790
175 CPU) the relevant values are cpu family 6, model 60, stepping 3 so in
176 this case the required identification is 06-3c-03. A look at the blobs
177 will show that there is one for this CPU (although it might
178 have already been applied by the BIOS). If there is a blob for your
179 system then test if it will be applied by copying it (replace &lt;XX-YY-ZZ&gt;
180 by the identifier for your machine) to where the kernel can find it:</para>
181
182<screen><userinput>mkdir -pv /lib/firmware/intel-ucode
183cp -v intel-ucode/&lt;XX-YY-ZZ&gt; /lib/firmware/intel-ucode</userinput></screen>
184
185 <para>Now that the Intel microcode has been prepared, use the following
186 options when you configure the kernel to load Intel
187 microcode:</para>
188
189<screen><literal>General Setup ---&gt;
190 [y] Initial RAM filesystem and RAM disk (initramfs/initrd) support [CONFIG_BLK_DEV_INITRD]
191Processor type and features ---&gt;
192 [y] CPU microcode loading support [CONFIG_MICROCODE]
193 [y] Intel microcode loading support [CONFIG_MICROCODE_INTEL]</literal></screen>
194
195 <para>After you have successfully booted the new system, force late loading by
196 using the command:</para>
197
198<screen><userinput>echo 1 > /sys/devices/system/cpu/microcode/reload</userinput></screen>
199
200 <para>Then use the following command to see if anything was loaded:</para>
201
202<screen><userinput>dmesg | grep -e 'microcode' -e 'Linux version' -e 'Command line'</userinput></screen>
203
204 <para>This example from the Haswell i7 which was released in Q2 2014 and is
205 not affected by the TSX errata shows it has been updated from revision 0x19
206 in the BIOS/UEFI to revision 0x20. Unlike in older kernels, the individual
207 CPUs are not separately reported:</para>
208
209<screen><literal>[ 0.000000] Linux version 4.9.12 (ken@plexi) (gcc version 6.3.0 (GCC) )
210 #3 SMP PREEMPT Mon Mar 6 03:29:27 GMT 2017
211[ 0.000000] Command line: BOOT_IMAGE=/vmlinuz-4.9.12-sda8 root=/dev/sda8 ro
212[ 0.913685] microcode: sig=0x306c3, pf=0x2, revision=0x19
213[ 0.913905] microcode: Microcode Update Driver: v2.01 &lt;tigran@aivazian.fsnet.co.uk&gt;, Peter Oruba
214[ 148.723932] microcode: updated to revision 0x20, date = 2016-03-16</literal></screen>
215
216 <para>If the microcode was not updated, there is no new microcode for
217 this system's processor. If it did get updated, you can now proceed to <xref
218 linkend='early-microcode'/>.</para>
219
220 </sect3>
221
222 <sect3 id="and-microcode">
223 <title>AMD Microcode for the CPU</title>
224
225 <para>Begin by downloading a container of firmware for your CPU family
226 from <ulink
227 url='&sources-anduin-http;/linux-firmware/amd-ucode/'/>.
228 The family is always specified in hex. Families 10h to 14h (16 to 20)
229 are in microcode_amd.bin. Families 15h and 16h have their own containers.
230 Create the required directory and put the firmware you downloaded into
231 it as the <systemitem class="username">root</systemitem> user:</para>
232
233<screen><userinput>mkdir -pv /lib/firmware/amd-ucode
234cp -v microcode_amd* /lib/firmware/amd-ucode</userinput></screen>
235
236 <para>When you configure the kernel, use the following options when you
237 configure the kernel to load AMD microcode:</para>
238
239<screen><literal>General Setup ---&gt;
240 [y] Initial RAM filesystem and RAM disk (initramfs/initrd) support [CONFIG_BLK_DEV_INITRD]
241Processor type and features ---&gt;
242 [y] CPU microcode loading support [CONFIG_MICROCODE]
243 [y] AMD microcode loading support [CONFIG_MICROCODE_AMD]</literal></screen>
244
245 <para>After you have successfully booted the new system, force late loading by
246 using the command:</para>
247
248<screen><userinput>echo 1 > /sys/devices/system/cpu/microcode/reload</userinput></screen>
249
250 <para>Then use the following command to see if anything was loaded:</para>
251
252<screen><userinput>dmesg | grep -e 'microcode' -e 'Linux version' -e 'Command line'</userinput></screen>
253 <para>This example from an old Athlon(tm) II X2 shows it has been updated.
254 For the moment, all CPUs are still reported in the microcode details on AMD
255 machines:</para>
256
257<screen><literal>[ 0.000000] Linux version 4.9.8 (ken@testserver) (gcc version 6.3.0 (GCC) )
258 #1 SMP Mon Mar 6 22:27:18 GMT 2017
259[ 0.000000] Command line: BOOT_IMAGE=/vmlinuz-4.9.8-sdc6 root=/dev/sdc6 ro
260[ 0.907752] microcode: CPU0: patch_level=0x010000b6
261[ 0.907788] microcode: CPU1: patch_level=0x010000b6
262[ 0.907844] microcode: Microcode Update Driver: v2.01 &lt;tigran@aivazian.fsnet.co.uk&gt;, Peter Oruba
263[ 121.952667] microcode: CPU0: new patch_level=0x010000c8
264[ 121.952687] microcode: CPU1: new patch_level=0x010000c8</literal></screen>
265
266 <para>If the microcode was not updated, there is no new microcode for
267 this system's processor. If it did get updated, you can now proceed to <xref
268 linkend='early-microcode'/>.</para>
269
270 </sect3>
271
272 <sect3 id="early-microcode">
273 <title>Early loading of microcode</title>
274
275 <para>If you have established that updated microcode is available for
276 your system, it is time to prepare it for early loading. This requires
277 an additional package, <xref linkend='cpio'/> and the creation of an
278 initrd which will need to be added to grub.cfg.</para>
279
280 <para>It does not matter where you prepare the initrd, and once it is
281 working you can apply the same initrd to later LFS systems or newer
282 kernels on this same machine, at least until any newer microcode is
283 released. Use the following commands:</para>
284
285<screen><userinput>mkdir -p initrd/kernel/x86/microcode
286cd initrd</userinput></screen>
287
288 <para>For an AMD machine, use the following command (replace
289 &lt;MYCONTAINER&gt; with the name of the container for your CPU's
290 family):</para>
291
292<screen><userinput>cp -v /lib/firmware/amd_ucode/&lt;MYCONTAINER&gt; kernel/x86/microcode/AuthenticAMD.bin</userinput></screen>
293
294 <para>Or for an Intel machine copy the appropriate blob using this command:</para>
295
296<screen><userinput>cp -v /lib/firmware/intel-ucode/&lt;XX-YY-ZZ&gt; kernel/x86/microcode/GenuineIntel.bin</userinput></screen>
297
298 <para>Now prepare the initrd:</para>
299
300<screen><userinput>find . | cpio -o -H newc &gt; /boot/microcode.img</userinput></screen>
301
302 <para>You now need to add a new entry to /boot/grub/grub.cfg and
303 here you should add a new line after the linux line within the stanza.
304 If /boot is a separate mountpoint: </para>
305
306<screen><userinput>initrd /microcode.img</userinput></screen>
307
308 <para>or this if it is not:</para>
309
310<screen><userinput>initrd /boot/microcode.img</userinput></screen>
311
312 <para>If you are already booting with an initrd (see <xref
313 linkend="initramfs"/>) you must specify the microcode initrd first, using
314 a line such as <userinput>initrd /microcode.img
315 /other-initrd.img</userinput> (adapt that as above if /boot is not a
316 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>The places and times where early loading happens are very different
324 in AMD and Intel machines. First, an Intel example from an updated stable
325 kernel, showing that the first notification comes before the kernel version
326 is mentioned:</para>
327
328<screen><literal>[ 0.000000] microcode: microcode updated early to revision 0x20, date = 2016-03-16
329[ 0.000000] Linux version 4.9.14 (ken@plexi) (gcc version 6.3.0 (GCC) )
330 #6 SMP PREEMPT Mon Mar 13 16:19:11 GMT 2017
331[ 0.000000] Command line: BOOT_IMAGE=/vmlinuz-4.9.14-sda8 root=/dev/sda8 ro
332[ 0.920217] microcode: sig=0x306c3, pf=0x2, revision=0x20
333[ 0.920514] microcode: Microcode Update Driver: v2.01 &lt;tigran@aivazian.fsnet.co.uk&gt;, Peter Oruba</literal></screen>
334
335 <para>An AMD example for the same kernel version:</para>
336
337<screen><literal>[ 0.000000] Linux version 4.9.14 (ken@testserver) (gcc version 6.3.0 (GCC) )
338 #2 SMP Mon Mar 13 22:23:44 GMT 2017
339[ 0.000000] Command line: BOOT_IMAGE=/vmlinuz-4.9.14-sdc6 root=/dev/sdc6 ro
340[ 0.907648] microcode: microcode updated early to new patch_level=0x010000c8
341[ 0.907690] microcode: CPU0: patch_level=0x010000c8
342[ 0.907733] microcode: CPU1: patch_level=0x010000c8
343[ 0.907808] microcode: Microcode Update Driver: v2.01 &lt;tigran@aivazian.fsnet.co.uk&gt;, Peter Oruba</literal></screen>
344
345 </sect3>
346
347 </sect2>
348
349 <sect2 id="video-firmware">
350 <title>Firmware for Video Cards</title>
351
352 <sect3 id="ati-video-firmware">
353 <title>Firmware for ATI video chips (R600 and later)</title>
354
355 <para>These instructions do NOT apply to old radeons before the R600
356 family. For those, the firmware is in the kernel's <filename
357 class='directory'>/lib/firmware/</filename> directory. Nor do they apply if
358 you intend to avoid a graphical setup such as Xorg and are content to use
359 the default 80x25 display rather than a framebuffer. </para>
360
361 <para> Early radeon devices only needed a single 2K blob of firmware.
362 Recent devices need several different blobs, and some of them are much
363 bigger. The total size of the radeon firmware directory is over 500K &mdash; on a
364 large modern system you can probably spare the space, but it is still
365 redundant to install all the unused files each time you build a system.</para>
366
367 <para>A better approach is to install <xref linkend='pciutils'/> and then
368 use <userinput>lspci</userinput> to identify which VGA controller is
369 installed.</para>
370
371 <para>With that information, check the RadeonFeature page of the Xorg wiki
372 for <ulink url="http://wiki.x.org/wiki/RadeonFeature/#index5h2">Decoder
373 ring for engineering vs marketing names</ulink> to identify the family (you
374 may need to know this for the Xorg driver in BLFS &mdash; Southern Islands and
375 Sea Islands use the radeonsi driver) and the specific model.</para>
376
377 <para>Now that you know which controller you are using, consult the
378 <ulink url="https://wiki.gentoo.org/wiki/Radeon#Firmware">Radeon</ulink> page
379 of the Gentoo wiki which has a table listing the required firmware blobs
380 for the various chipsets. Note that Southern Islands and Sea Islands chips
381 use different firmware for kernel 3.17 and later compared to earlier
382 kernels. Identify and download the required blobs then install them:</para>
383
384<screen><userinput>mkdir -pv /lib/firmware/radeon
385cp -v &lt;YOUR_BLOBS&gt; /lib/firmware/radeon</userinput></screen>
386
387 <para>There are actually two ways of installing this firmware. BLFS, in the
388 'Kernel Configuration for additional firmware' section part of the <xref
389 linkend="xorg-ati-driver"/> section gives an example of compiling the
390 firmware into the kernel - that is slightly faster to load, but uses more
391 kernel memory. Here we will use the alternative method of making the radeon
392 driver a module. In your kernel config set the following: </para>
393
394<screen><literal>Device Drivers ---&gt;
395 Graphics support ---&gt;
396 Direct Rendering Manager ---&gt;
397 &lt;*&gt; Direct Rendering Manager (XFree86 ... support) [CONFIG_DRM]
398 &lt;m&gt; ATI Radeon [CONFIG_DRM_RADEON]</literal></screen>
399
400 <para>Loading several large blobs from /lib/firmware takes a noticeable
401 time, during which the screen will be blank. If you do not enable the
402 penguin framebuffer logo, or change the console size by using a bigger
403 font, that probably does not matter. If desired, you can slightly
404 reduce the time if you follow the alternate method of specifying 'y' for
405 CONFIG_DRM_RADEON covered in BLFS at the link above &mdash; you must specify each
406 needed radeon blob if you do that.</para>
407
408 </sect3>
409
410 <sect3 id="nvidia-video-firmware">
411 <title>Firmware for Nvidia video chips</title>
412
413 <para>Some Nvidia graphics chips need firmware updates to take advantage
414 of all the card's capability. These are generally the GeForce 8, 9, 9300,
415 and 200-900 series chips. For more exact information, see <ulink
416 url="https://nouveau.freedesktop.org/wiki/VideoAcceleration/#firmware">
417 https://nouveau.freedesktop.org/wiki/VideoAcceleration/#firmware</ulink>.</para>
418
419 <para>First, the kernel Nvidia driver must be activated:</para>
420
421<screen><literal>Device Drivers ---&gt;
422 Graphics support ---&gt;
423 Direct Rendering Manager ---&gt;
424 &lt;*&gt; Direct Rendering Manager (XFree86 ... support) [CONFIG_DRM]
425 &lt;*/m&gt; Nouveau (NVIDIA) cards [CONFIG_DRM_NOUVEAU]</literal></screen>
426
427 <para>The steps to install the Nvidia firmware are:</para>
428
429<screen><userinput>wget https://raw.github.com/imirkin/re-vp2/master/extract_firmware.py
430wget http://us.download.nvidia.com/XFree86/Linux-x86/325.15/NVIDIA-Linux-x86-325.15.run
431sh NVIDIA-Linux-x86-325.15.run --extract-only
432python extract_firmware.py
433mkdir -p /lib/firmware/nouveau
434cp -d nv* vuc-* /lib/firmware/nouveau/</userinput></screen>
435
436 </sect3>
437 </sect2>
438
439 <sect2 id="nic-firmware">
440 <title>Firmware for Network Interfaces</title>
441
442 <para>The kernel likes to load firmware for some network drivers,
443 particularly those from Realtek (the /lib/linux-firmware/rtl_nic/) directory,
444 but they generally appear to work without it. Therefore, you can boot the
445 kernel, check dmesg for messages about this missing firmware, and if
446 necessary download the firmware and put it in the specified directory in
447 /lib/firmware so that it will be found on subsequent boots. Note that with
448 current kernels this works whether or not the driver is compiled in or
449 built as a module, there is no need to build this firmware into the kernel.
450 Here is an example where the R8169 driver has been compiled in but the
451 firmware was not made available. Once the firmware had been provided, there
452 was no mention of it on later boots. </para>
453
454<screen><literal>dmesg | grep firmware | grep r8169
455[ 7.018028] r8169 0000:01:00.0: Direct firmware load for rtl_nic/rtl8168g-2.fw failed with error -2
456[ 7.018036] r8169 0000:01:00.0 eth0: unable to load firmware patch rtl_nic/rtl8168g-2.fw (-2)</literal></screen>
457
458 </sect2>
459
460 <sect2 id="other-firmware">
461 <title>Firmware for Other Devices</title>
462
463 <para> Identifying the correct firmware will typically require you to
464 install <xref linkend='pciutils'/>, and then use
465 <userinput>lspci</userinput> to identify the device. You should then search
466 online to check which module it uses, which firmware, and where to obtain
467 the firmware &mdash; not all of it is in linux-firmware.</para>
468
469 <para>If possible, you should begin by using a wired connection when you
470 first boot your LFS system. To use a wireless connection you will need to
471 use a network tools such as <xref linkend='wireless_tools'/> and <xref
472 linkend='wpa_supplicant'/>.</para>
473
474 <para>Firmware may also be needed for other devices such as some SCSI
475 controllers, bluetooth adaptors, or TV recorders. The same principles
476 apply.</para>
477
478 </sect2>
479
480</sect1>
Note: See TracBrowser for help on using the repository browser.