source: postlfs/filesystems/initramfs.xml@ ef5367b

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 xry111/llvm18 xry111/soup3 xry111/xf86-video-removal
Last change on this file since ef5367b was 889d6c4, checked in by Thomas Trepl (Moody) <thomas@…>, 23 months ago

Fix mkinitramfs script

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