source: postlfs/filesystems/initramfs.xml@ 29244b7

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

format filesystems chapter

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

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