source: postlfs/filesystems/initramfs.xml@ a37e6b2

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/xf86-video-removal
Last change on this file since a37e6b2 was 3f2db3a6, checked in by Pierre Labastie <pierre.labastie@…>, 18 months ago

Remove sect1info tags

They only contain a date tag that is nowhere used.

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