source: postlfs/filesystems/initramfs.xml@ 6e493187

10.0 10.1 11.0 11.1 11.2 11.3 12.0 12.1 9.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 6e493187 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: 14.8 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="initramfs">
9 <?dbhtml filename="initramfs.html"?>
10
11 <sect1info>
12 <othername>$LastChangedBy$</othername>
13 <date>$Date$</date>
14 </sect1info>
15
16 <title>About initramfs</title>
17
18 <para>The only purpose of an initramfs is to mount the root filesystem. The
19 initramfs is a complete set of directories that you would find on a normal
20 root filesystem. It is bundled into a single cpio archive and compressed
21 with one of several compression algorithms.</para>
22
23 <para>At boot time, the boot loader loads the kernel and the initramfs image
24 into memory and starts the kernel. The kernel checks for the presence of the
25 initramfs and, if found, mounts it as / and runs /init. The init program is
26 typically a shell script. Note that the boot process takes longer, possibly
27 significantly longer, if an initramfs is used.</para>
28
29 <para>For most distributions, kernel modules are the biggest reason to have an
30 initramfs. In a general distribution, there are many unknowns such as file
31 system types and disk layouts. In a way, this is the opposite of LFS where
32 the system capabilities and layout are known and a custom kernel is normally
33 built. In this situation, an initramfs is rarely needed.</para>
34
35 <para>There are only four primary reasons to have an initramfs in the LFS
36 environment: loading the rootfs from a network, loading it from an LVM
37 logical volume, having an encrypted rootfs where a password is required, or
38 for the convenience of specifying the rootfs as a LABEL or UUID. Anything
39 else usually means that the kernel was not configured properly.</para>
40
41 <sect2 id="initramfs-build">
42 <title>Building an initramfs</title>
43
44 <para>If you do decide to build an initramfs, the following scripts
45 will provide a basis to do it. The scripts will allow specifying a
46 rootfs via partition UUID or partition LABEL or a rootfs on an
47 LVM logical volume. They do not support an encrypted root file system
48 or mounting the rootfs over a network card. For a more complete
49 capability see <ulink url="http://www.linuxfromscratch.org/hints/read.html">
50 the LFS Hints</ulink> or <ulink url="http://fedoraproject.org/wiki/Dracut">
51 dracut</ulink>.</para>
52
53 <para>To install these scripts, run the following commands as the
54 <systemitem class="username">root</systemitem> user:</para>
55
56 <screen role="root"><userinput>cat &gt; /sbin/mkinitramfs &lt;&lt; "EOF"
57<literal>#!/bin/bash
58# This file based in part on the mkinitramfs script for the LFS LiveCD
59# written by Alexander E. Patrakov and Jeremy Huntwork.
60
61copy()
62{
63 local file
64
65 if [ "$2" == "lib" ]; then
66 file=$(PATH=/lib:/usr/lib type -p $1)
67 else
68 file=$(type -p $1)
69 fi
70
71 if [ -n "$file" ] ; then
72 cp $file $WDIR/$2
73 else
74 echo "Missing required file: $1 for directory $2"
75 rm -rf $WDIR
76 exit 1
77 fi
78}
79
80if [ -z $1 ] ; then
81 INITRAMFS_FILE=initrd.img-no-kmods
82else
83 KERNEL_VERSION=$1
84 INITRAMFS_FILE=initrd.img-$KERNEL_VERSION
85fi
86
87if [ -n "$KERNEL_VERSION" ] &amp;&amp; [ ! -d "/lib/modules/$1" ] ; then
88 echo "No modules directory named $1"
89 exit 1
90fi
91
92printf "Creating $INITRAMFS_FILE... "
93
94binfiles="sh cat cp dd killall ls mkdir mknod mount "
95binfiles="$binfiles umount sed sleep ln rm uname"
96binfiles="$binfiles readlink basename"
97
98# Systemd installs udevadm in /bin. Other udev implementations have it in /sbin
99if [ -x /bin/udevadm ] ; then binfiles="$binfiles udevadm"; fi
100
101sbinfiles="modprobe blkid switch_root"
102
103#Optional files and locations
104for f in mdadm mdmon udevd udevadm; do
105 if [ -x /sbin/$f ] ; then sbinfiles="$sbinfiles $f"; fi
106done
107
108unsorted=$(mktemp /tmp/unsorted.XXXXXXXXXX)
109
110DATADIR=/usr/share/mkinitramfs
111INITIN=init.in
112
113# Create a temporary working directory
114WDIR=$(mktemp -d /tmp/initrd-work.XXXXXXXXXX)
115
116# Create base directory structure
117mkdir -p $WDIR/{bin,dev,lib/firmware,run,sbin,sys,proc,usr}
118mkdir -p $WDIR/etc/{modprobe.d,udev/rules.d}
119touch $WDIR/etc/modprobe.d/modprobe.conf
120ln -s lib $WDIR/lib64
121ln -s ../bin $WDIR/usr/bin
122
123# Create necessary device nodes
124mknod -m 640 $WDIR/dev/console c 5 1
125mknod -m 664 $WDIR/dev/null c 1 3
126
127# Install the udev configuration files
128if [ -f /etc/udev/udev.conf ]; then
129 cp /etc/udev/udev.conf $WDIR/etc/udev/udev.conf
130fi
131
132for file in $(find /etc/udev/rules.d/ -type f) ; do
133 cp $file $WDIR/etc/udev/rules.d
134done
135
136# Install any firmware present
137cp -a /lib/firmware $WDIR/lib
138
139# Copy the RAID configuration file if present
140if [ -f /etc/mdadm.conf ] ; then
141 cp /etc/mdadm.conf $WDIR/etc
142fi
143
144# Install the init file
145install -m0755 $DATADIR/$INITIN $WDIR/init
146
147if [ -n "$KERNEL_VERSION" ] ; then
148 if [ -x /bin/kmod ] ; then
149 binfiles="$binfiles kmod"
150 else
151 binfiles="$binfiles lsmod"
152 sbinfiles="$sbinfiles insmod"
153 fi
154fi
155
156# Install basic binaries
157for f in $binfiles ; do
158 if [ -e /bin/$f ]; then d="/bin"; else d="/usr/bin"; fi
159 ldd $d/$f | sed "s/\t//" | cut -d " " -f1 &gt;&gt; $unsorted
160 copy $d/$f bin
161done
162
163# Add lvm if present
164if [ -x /sbin/lvm ] ; then sbinfiles="$sbinfiles lvm dmsetup"; fi
165
166for f in $sbinfiles ; do
167 ldd /sbin/$f | sed "s/\t//" | cut -d " " -f1 &gt;&gt; $unsorted
168 copy $f sbin
169done
170
171# Add udevd libraries if not in /sbin
172if [ -x /lib/udev/udevd ] ; then
173 ldd /lib/udev/udevd | sed "s/\t//" | cut -d " " -f1 &gt;&gt; $unsorted
174elif [ -x /lib/systemd/systemd-udevd ] ; then
175 ldd /lib/systemd/systemd-udevd | sed "s/\t//" | cut -d " " -f1 &gt;&gt; $unsorted
176fi
177
178# Add module symlinks if appropriate
179if [ -n "$KERNEL_VERSION" ] &amp;&amp; [ -x /bin/kmod ] ; then
180 ln -s kmod $WDIR/bin/lsmod
181 ln -s kmod $WDIR/bin/insmod
182fi
183
184# Add lvm symlinks if appropriate
185# Also copy the lvm.conf file
186if [ -x /sbin/lvm ] ; then
187 ln -s lvm $WDIR/sbin/lvchange
188 ln -s lvm $WDIR/sbin/lvrename
189 ln -s lvm $WDIR/sbin/lvextend
190 ln -s lvm $WDIR/sbin/lvcreate
191 ln -s lvm $WDIR/sbin/lvdisplay
192 ln -s lvm $WDIR/sbin/lvscan
193
194 ln -s lvm $WDIR/sbin/pvchange
195 ln -s lvm $WDIR/sbin/pvck
196 ln -s lvm $WDIR/sbin/pvcreate
197 ln -s lvm $WDIR/sbin/pvdisplay
198 ln -s lvm $WDIR/sbin/pvscan
199
200 ln -s lvm $WDIR/sbin/vgchange
201 ln -s lvm $WDIR/sbin/vgcreate
202 ln -s lvm $WDIR/sbin/vgscan
203 ln -s lvm $WDIR/sbin/vgrename
204 ln -s lvm $WDIR/sbin/vgck
205 # Conf file(s)
206 cp -a /etc/lvm $WDIR/etc
207fi
208
209# Install libraries
210sort $unsorted | uniq | while read library ; do
211# linux-vdso and linux-gate are pseudo libraries and do not correspond to a file
212# libsystemd-shared is in /lib/systemd, so it is not found by copy, and
213# it is copied below anyway
214 if [[ "$library" == linux-vdso.so.1 ]] ||
215 [[ "$library" == linux-gate.so.1 ]] ||
216 [[ "$library" == libsystemd-shared* ]]; then
217 continue
218 fi
219
220 copy $library lib
221done
222
223if [ -d /lib/udev ]; then
224 cp -a /lib/udev $WDIR/lib
225fi
226if [ -d /lib/systemd ]; then
227 cp -a /lib/systemd $WDIR/lib
228fi
229if [ -d /lib/elogind ]; then
230 cp -a /lib/elogind $WDIR/lib
231fi
232
233# Install the kernel modules if requested
234if [ -n "$KERNEL_VERSION" ]; then
235 find \
236 /lib/modules/$KERNEL_VERSION/kernel/{crypto,fs,lib} \
237 /lib/modules/$KERNEL_VERSION/kernel/drivers/{block,ata,md,firewire} \
238 /lib/modules/$KERNEL_VERSION/kernel/drivers/{scsi,message,pcmcia,virtio} \
239 /lib/modules/$KERNEL_VERSION/kernel/drivers/usb/{host,storage} \
240 -type f 2&gt; /dev/null | cpio --make-directories -p --quiet $WDIR
241
242 cp /lib/modules/$KERNEL_VERSION/modules.{builtin,order} \
243 $WDIR/lib/modules/$KERNEL_VERSION
244
245 depmod -b $WDIR $KERNEL_VERSION
246fi
247
248( cd $WDIR ; find . | cpio -o -H newc --quiet | gzip -9 ) &gt; $INITRAMFS_FILE
249
250# Prepare early loading of microcode if available
251if ls /lib/firmware/intel-ucode/* &gt;/dev/null 2&gt;&amp;1 ||
252 ls /lib/firmware/amd-ucode/* &gt;/dev/null 2&gt;&amp;1; then
253
254# first empty WDIR to reuse it
255 rm -r $WDIR/*
256
257 DSTDIR=$WDIR/kernel/x86/microcode
258 mkdir -p $DSTDIR
259
260 if [ -d /lib/firmware/amd-ucode ]; then
261 cat /lib/firmware/amd-ucode/microcode_amd*.bin &gt; $DSTDIR/AuthenticAMD.bin
262 fi
263
264 if [ -d /lib/firmware/intel-ucode ]; then
265 cat /lib/firmware/intel-ucode/* &gt; $DSTDIR/GenuineIntel.bin
266 fi
267
268 ( cd $WDIR; find . | cpio -o -H newc --quiet ) &gt; microcode.img
269 cat microcode.img $INITRAMFS_FILE &gt; tmpfile
270 mv tmpfile $INITRAMFS_FILE
271 rm microcode.img
272fi
273
274# Remove the temporary directories and files
275rm -rf $WDIR $unsorted
276printf "done.\n"
277</literal>
278EOF
279
280chmod 0755 /sbin/mkinitramfs</userinput></screen>
281
282 <screen role="root"><userinput>mkdir -p /usr/share/mkinitramfs &amp;&amp;
283cat &gt; /usr/share/mkinitramfs/init.in &lt;&lt; "EOF"
284<literal>#!/bin/sh
285
286PATH=/bin:/usr/bin:/sbin:/usr/sbin
287export PATH
288
289problem()
290{
291 printf "Encountered a problem!\n\nDropping you to a shell.\n\n"
292 sh
293}
294
295no_device()
296{
297 printf "The device %s, which is supposed to contain the\n" $1
298 printf "root file system, does not exist.\n"
299 printf "Please fix this problem and exit this shell.\n\n"
300}
301
302no_mount()
303{
304 printf "Could not mount device %s\n" $1
305 printf "Sleeping forever. Please reboot and fix the kernel command line.\n\n"
306 printf "Maybe the device is formatted with an unsupported file system?\n\n"
307 printf "Or maybe filesystem type autodetection went wrong, in which case\n"
308 printf "you should add the rootfstype=... parameter to the kernel command line.\n\n"
309 printf "Available partitions:\n"
310}
311
312do_mount_root()
313{
314 mkdir /.root
315 [ -n "$rootflags" ] &amp;&amp; rootflags="$rootflags,"
316 rootflags="$rootflags$ro"
317
318 case "$root" in
319 /dev/* ) device=$root ;;
320 UUID=* ) eval $root; device="/dev/disk/by-uuid/$UUID" ;;
321 LABEL=*) eval $root; device="/dev/disk/by-label/$LABEL" ;;
322 "" ) echo "No root device specified." ; problem ;;
323 esac
324
325 while [ ! -b "$device" ] ; do
326 no_device $device
327 problem
328 done
329
330 if ! mount -n -t "$rootfstype" -o "$rootflags" "$device" /.root ; then
331 no_mount $device
332 cat /proc/partitions
333 while true ; do sleep 10000 ; done
334 else
335 echo "Successfully mounted device $root"
336 fi
337}
338
339do_try_resume()
340{
341 case "$resume" in
342 UUID=* ) eval $resume; resume="/dev/disk/by-uuid/$UUID" ;;
343 LABEL=*) eval $resume; resume="/dev/disk/by-label/$LABEL" ;;
344 esac
345
346 if $noresume || ! [ -b "$resume" ]; then return; fi
347
348 ls -lH "$resume" | ( read x x x x maj min x
349 echo -n ${maj%,}:$min &gt; /sys/power/resume )
350}
351
352init=/sbin/init
353root=
354rootdelay=
355rootfstype=auto
356ro="ro"
357rootflags=
358device=
359resume=
360noresume=false
361
362mount -n -t devtmpfs devtmpfs /dev
363mount -n -t proc proc /proc
364mount -n -t sysfs sysfs /sys
365mount -n -t tmpfs tmpfs /run
366
367read -r cmdline &lt; /proc/cmdline
368
369for param in $cmdline ; do
370 case $param in
371 init=* ) init=${param#init=} ;;
372 root=* ) root=${param#root=} ;;
373 rootdelay=* ) rootdelay=${param#rootdelay=} ;;
374 rootfstype=*) rootfstype=${param#rootfstype=} ;;
375 rootflags=* ) rootflags=${param#rootflags=} ;;
376 resume=* ) resume=${param#resume=} ;;
377 noresume ) noresume=true ;;
378 ro ) ro="ro" ;;
379 rw ) ro="rw" ;;
380 esac
381done
382
383# udevd location depends on version
384if [ -x /sbin/udevd ]; then
385 UDEVD=/sbin/udevd
386elif [ -x /lib/udev/udevd ]; then
387 UDEVD=/lib/udev/udevd
388elif [ -x /lib/systemd/systemd-udevd ]; then
389 UDEVD=/lib/systemd/systemd-udevd
390else
391 echo "Cannot find udevd nor systemd-udevd"
392 problem
393fi
394
395${UDEVD} --daemon --resolve-names=never
396udevadm trigger
397udevadm settle
398
399if [ -f /etc/mdadm.conf ] ; then mdadm -As ; fi
400if [ -x /sbin/vgchange ] ; then /sbin/vgchange -a y &gt; /dev/null ; fi
401if [ -n "$rootdelay" ] ; then sleep "$rootdelay" ; fi
402
403do_try_resume # This function will not return if resuming from disk
404do_mount_root
405
406killall -w ${UDEVD##*/}
407
408exec switch_root /.root "$init" "$@"
409</literal>
410EOF</userinput></screen>
411
412 </sect2>
413
414 <sect2 id="initramfs-install">
415 <title>Using an initramfs</title>
416
417 <bridgehead renderas="sect3">Required Runtime Dependency</bridgehead>
418
419 <para role="required">
420 <xref role="runtime" linkend="cpio"/>
421 </para>
422
423 <bridgehead renderas="sect3">Other Runtime Dependencies</bridgehead>
424
425 <para role="optional">
426 <xref role="runtime" linkend="lvm2"/> and/or
427 <xref role="runtime" linkend="mdadm"/> must be installed before
428 generating the initramfs, if the system partition uses them.
429 </para>
430
431 <para condition="html" role="usernotes">User Notes:
432 <ulink url="&blfs-wiki;/initramfs"/>
433 </para>
434
435
436 <para>To build an initramfs, run the following as the <systemitem
437 class="username">root</systemitem> user:</para>
438
439 <screen role="nodump"><userinput>mkinitramfs [KERNEL VERSION]</userinput></screen>
440
441 <para>The optional argument is the directory where the appropriate kernel
442 modules are located. This must be a subdirectory of <filename
443 class='directory'> /lib/modules</filename>. If no modules are specified,
444 then the initramfs is named <emphasis>initrd.img-no-kmods</emphasis>. If a
445 kernel version is specified, the initrd is named
446 <emphasis>initrd.img-$KERNEL_VERSION</emphasis> and is only appropriate for
447 the specific kernel specified. The output file will be placed in the
448 current directory.</para>
449
450 <para>If early loading of microcode is needed (see <xref
451 linkend="cpu-microcode"/>), you can install the appropriate blob or
452 container in <filename class="directory">/lib/firmware</filename>.
453 It will be automatically added to the initrd when running
454 <command>mkinitramfs</command>.</para>
455
456 <para>After generating the initrd, copy it to the <filename
457 class='directory'>/boot</filename> directory.</para>
458
459 <para>Now edit <filename>/boot/grub/grub.cfg</filename> and add a new
460 menuentry. Below are several examples.</para>
461
462 <screen role="nodump"><userinput># Generic initramfs and root fs identified by UUID
463menuentry "LFS Dev (LFS-7.0-Feb14) initrd, Linux 3.0.4"
464{
465 linux /vmlinuz-3.0.4-lfs-20120214 root=UUID=54b934a9-302d-415e-ac11-4988408eb0a8 ro
466 initrd /initrd.img-no-kmods
467}</userinput></screen>
468
469 <screen role="nodump"><userinput># Generic initramfs and root fs on LVM partition
470menuentry "LFS Dev (LFS-7.0-Feb18) initrd lvm, Linux 3.0.4"
471{
472 linux /vmlinuz-3.0.4-lfs-20120218 root=/dev/mapper/myroot ro
473 initrd /initrd.img-no-kmods
474}</userinput></screen>
475
476 <screen role="nodump"><userinput># Specific initramfs and root fs identified by LABEL
477menuentry "LFS Dev (LFS-7.1-Feb20) initrd label, Linux 3.2.6"
478{
479 linux /vmlinuz-3.2.6-lfs71-120220 root=LABEL=lfs71 ro
480 initrd /initrd.img-3.2.6-lfs71-120220
481}</userinput></screen>
482
483 <para>Finally, reboot the system and select the desired system.</para>
484
485 </sect2>
486
487</sect1>
Note: See TracBrowser for help on using the repository browser.