source: postlfs/filesystems/initramfs.xml@ 756a787

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 756a787 was 288c825, checked in by Pierre Labastie <pieere@…>, 4 years ago

mkinitramfs: remove the link of sh to bash

This link is not needed: the shell scripts all have #!/bin/sh
Also remove redundant additions of mdadm and udevd, which are added
to sbinfiles in a loop, and move all the additions to sbinfiles
to the same place so that it is easier to see what is in there.

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

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