source: postlfs/filesystems/initramfs.xml

trunk
Last change on this file was ab4fdfc, checked in by Pierre Labastie <pierre.labastie@…>, 3 months ago

Change all xml decl to encoding=utf-8

  • Property mode set to 100644
File size: 15.3 KB
Line 
1<?xml version="1.0" encoding="UTF-8"?>
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
448
449 <para>
450 To build an initramfs, run the following as the <systemitem
451 class="username">root</systemitem> user:
452 </para>
453
454 <screen role="nodump"><userinput>mkinitramfs [KERNEL VERSION]</userinput></screen>
455
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>
466
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>
474
475 <para>
476 After generating the initrd, copy it to the <filename
477 class='directory'>/boot</filename> directory.
478 </para>
479
480 <para>
481 Now edit <filename>/boot/grub/grub.cfg</filename> and add a new
482 menuentry. Below are several examples.
483 </para>
484
485 <screen role="nodump"><userinput># Generic initramfs and root fs identified by UUID
486menuentry "LFS Dev (LFS-7.0-Feb14) initrd, Linux 3.0.4"
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
492 <screen role="nodump"><userinput># Generic initramfs and root fs on LVM partition
493menuentry "LFS Dev (LFS-7.0-Feb18) initrd lvm, Linux 3.0.4"
494{
495 linux /vmlinuz-3.0.4-lfs-20120218 root=/dev/mapper/myroot ro
496 initrd /initrd.img-no-kmods
497}</userinput></screen>
498
499 <screen role="nodump"><userinput># Specific initramfs and root fs identified by LABEL
500menuentry "LFS Dev (LFS-7.1-Feb20) initrd label, Linux 3.2.6"
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
506 <para>
507 Finally, reboot the system and select the desired system.
508 </para>
509
510 </sect2>
511
512</sect1>
Note: See TracBrowser for help on using the repository browser.