source: postlfs/filesystems/initramfs.xml@ eede1a3

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 eede1a3 was 5804e5f, checked in by Xi Ruoyao <xry111@…>, 3 years ago

update mkinitramfs script (merge /usr)

  • Property mode set to 100644
File size: 15.3 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 <date>$Date$</date>
13 </sect1info>
14
15 <title>About initramfs</title>
16
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>
48
49 <sect2 id="initramfs-build">
50 <title>Building an initramfs</title>
51
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
58 <ulink url="https://www.linuxfromscratch.org/hints/read.html"> the LFS
59 Hints</ulink> or <ulink
60 url="http://fedoraproject.org/wiki/Dracut">dracut</ulink>.
61 </para>
62
63 <para>
64 To install these scripts, run the following commands as the
65 <systemitem class="username">root</systemitem> user:
66 </para>
67
68 <screen role="root"><userinput>cat &gt; /usr/sbin/mkinitramfs &lt;&lt; "EOF"
69<literal>#!/bin/bash
70# This file based in part on the mkinitramfs script for the LFS LiveCD
71# written by Alexander E. Patrakov and Jeremy Huntwork.
72
73copy()
74{
75 local file
76
77 if [ "$2" = "lib" ]; then
78 file=$(PATH=/usr/lib type -p $1)
79 else
80 file=$(type -p $1)
81 fi
82
83 if [ -n "$file" ] ; then
84 cp $file $WDIR/usr/$2
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
99if [ -n "$KERNEL_VERSION" ] &amp;&amp; [ ! -d "/usr/lib/modules/$1" ] ; then
100 echo "No modules directory named $1"
101 exit 1
102fi
103
104printf "Creating $INITRAMFS_FILE... "
105
106binfiles="sh cat cp dd killall ls mkdir mknod mount "
107binfiles="$binfiles umount sed sleep ln rm uname"
108binfiles="$binfiles readlink basename"
109
110# Systemd installs udevadm in /bin. Other udev implementations have it in /sbin
111if [ -x /usr/bin/udevadm ] ; then binfiles="$binfiles udevadm"; fi
112
113sbinfiles="modprobe blkid switch_root"
114
115# Optional files and locations
116for f in mdadm mdmon udevd udevadm; do
117 if [ -x /usr/sbin/$f ] ; then sbinfiles="$sbinfiles $f"; fi
118done
119
120# Add lvm if present (cannot be done with the others because it
121# also needs dmsetup
122if [ -x /usr/sbin/lvm ] ; then sbinfiles="$sbinfiles lvm dmsetup"; fi
123
124unsorted=$(mktemp /tmp/unsorted.XXXXXXXXXX)
125
126DATADIR=/usr/share/mkinitramfs
127INITIN=init.in
128
129# Create a temporary working directory
130WDIR=$(mktemp -d /tmp/initrd-work.XXXXXXXXXX)
131
132# Create base directory structure
133mkdir -p $WDIR/{dev,run,sys,proc,usr/{bin,lib/{firmware,modules},sbin}}
134mkdir -p $WDIR/etc/{modprobe.d,udev/rules.d}
135touch $WDIR/etc/modprobe.d/modprobe.conf
136ln -s usr/bin $WDIR/bin
137ln -s usr/lib $WDIR/lib
138ln -s usr/sbin $WDIR/sbin
139ln -s lib $WDIR/lib64
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
146if [ -f /etc/udev/udev.conf ]; then
147 cp /etc/udev/udev.conf $WDIR/etc/udev/udev.conf
148fi
149
150for file in $(find /etc/udev/rules.d/ -type f) ; do
151 cp $file $WDIR/etc/udev/rules.d
152done
153
154# Install any firmware present
155cp -a /usr/lib/firmware $WDIR/usr/lib
156
157# Copy the RAID configuration file if present
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
165if [ -n "$KERNEL_VERSION" ] ; then
166 if [ -x /usr/bin/kmod ] ; then
167 binfiles="$binfiles kmod"
168 else
169 binfiles="$binfiles lsmod"
170 sbinfiles="$sbinfiles insmod"
171 fi
172fi
173
174# Install basic binaries
175for f in $binfiles ; do
176 ldd /usr/bin/$f | sed "s/\t//" | cut -d " " -f1 &gt;&gt; $unsorted
177 copy /usr/bin/$f bin
178done
179
180for f in $sbinfiles ; do
181 ldd /usr/sbin/$f | sed "s/\t//" | cut -d " " -f1 &gt;&gt; $unsorted
182 copy $f sbin
183done
184
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
190fi
191
192# Add module symlinks if appropriate
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
196fi
197
198# Add lvm symlinks if appropriate
199# Also copy the lvm.conf file
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
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 /usr/lib/udev ]; then
238 cp -a /usr/lib/udev $WDIR/usr/lib
239fi
240if [ -d /usr/lib/systemd ]; then
241 cp -a /usr/lib/systemd $WDIR/usr/lib
242fi
243if [ -d /usr/lib/elogind ]; then
244 cp -a /usr/lib/elogind $WDIR/usr/lib
245fi
246
247# Install the kernel modules if requested
248if [ -n "$KERNEL_VERSION" ]; then
249 find \
250 /usr/lib/modules/$KERNEL_VERSION/kernel/{crypto,fs,lib} \
251 /usr/lib/modules/$KERNEL_VERSION/kernel/drivers/{block,ata,md,firewire} \
252 /usr/lib/modules/$KERNEL_VERSION/kernel/drivers/{scsi,message,pcmcia,virtio} \
253 /usr/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 /usr/lib/modules/$KERNEL_VERSION/modules.{builtin,order} \
257 $WDIR/usr/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 /usr/lib/firmware/intel-ucode/* &gt;/dev/null 2&gt;&amp;1 ||
266 ls /usr/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 /usr/lib/firmware/amd-ucode ]; then
275 cat /usr/lib/firmware/amd-ucode/microcode_amd*.bin &gt; $DSTDIR/AuthenticAMD.bin
276 fi
277
278 if [ -d /usr/lib/firmware/intel-ucode ]; then
279 cat /usr/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 /usr/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=/usr/bin:/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.