source: postlfs/filesystems/initramfs.xml@ 99ff4fad

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 99ff4fad was 99ff4fad, checked in by Pierre Labastie <pieere@…>, 4 years ago

Various fixes in initramfs:

  • revert changes to the "copy" function from r23132
  • copy mdadm if it exists
  • add the PARTUUID case (patch by Alain Dumont)

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

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