source: postlfs/filesystems/initramfs.xml@ c9aa980

11.0 qt5new trunk
Last change on this file since c9aa980 was c9aa980, checked in by Xi Ruoyao <xry111@…>, 5 months ago

secure LFS url

  • Property mode set to 100644
File size: 15.1 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; /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=/lib:/usr/lib type -p $1)
79 else
80 file=$(type -p $1)
81 fi
82
83 if [ -n "$file" ] ; then
84 cp $file $WDIR/$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 "/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 /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 /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 /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/{bin,dev,lib/firmware,run,sbin,sys,proc,usr}
134mkdir -p $WDIR/etc/{modprobe.d,udev/rules.d}
135touch $WDIR/etc/modprobe.d/modprobe.conf
136ln -s lib $WDIR/lib64
137ln -s ../bin $WDIR/usr/bin
138
139# Create necessary device nodes
140mknod -m 640 $WDIR/dev/console c 5 1
141mknod -m 664 $WDIR/dev/null c 1 3
142
143# Install the udev configuration files
144if [ -f /etc/udev/udev.conf ]; then
145 cp /etc/udev/udev.conf $WDIR/etc/udev/udev.conf
146fi
147
148for file in $(find /etc/udev/rules.d/ -type f) ; do
149 cp $file $WDIR/etc/udev/rules.d
150done
151
152# Install any firmware present
153cp -a /lib/firmware $WDIR/lib
154
155# Copy the RAID configuration file if present
156if [ -f /etc/mdadm.conf ] ; then
157 cp /etc/mdadm.conf $WDIR/etc
158fi
159
160# Install the init file
161install -m0755 $DATADIR/$INITIN $WDIR/init
162
163if [ -n "$KERNEL_VERSION" ] ; then
164 if [ -x /bin/kmod ] ; then
165 binfiles="$binfiles kmod"
166 else
167 binfiles="$binfiles lsmod"
168 sbinfiles="$sbinfiles insmod"
169 fi
170fi
171
172# Install basic binaries
173for f in $binfiles ; do
174 if [ -e /bin/$f ]; then d="/bin"; else d="/usr/bin"; fi
175 ldd $d/$f | sed "s/\t//" | cut -d " " -f1 &gt;&gt; $unsorted
176 copy $d/$f bin
177done
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
184# Add udevd libraries if not in /sbin
185if [ -x /lib/udev/udevd ] ; then
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
189fi
190
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
197# Add lvm symlinks if appropriate
198# Also copy the lvm.conf file
199if [ -x /sbin/lvm ] ; then
200 ln -s lvm $WDIR/sbin/lvchange
201 ln -s lvm $WDIR/sbin/lvrename
202 ln -s lvm $WDIR/sbin/lvextend
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
213 ln -s lvm $WDIR/sbin/vgchange
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
218 # Conf file(s)
219 cp -a /etc/lvm $WDIR/etc
220fi
221
222# Install libraries
223sort $unsorted | uniq | while read library ; do
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
230 continue
231 fi
232
233 copy $library lib
234done
235
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
242if [ -d /lib/elogind ]; then
243 cp -a /lib/elogind $WDIR/lib
244fi
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
255 cp /lib/modules/$KERNEL_VERSION/modules.{builtin,order} \
256 $WDIR/lib/modules/$KERNEL_VERSION
257
258 depmod -b $WDIR $KERNEL_VERSION
259fi
260
261( cd $WDIR ; find . | cpio -o -H newc --quiet | gzip -9 ) &gt; $INITRAMFS_FILE
262
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
288rm -rf $WDIR $unsorted
289printf "done.\n"
290</literal>
291EOF
292
293chmod 0755 /sbin/mkinitramfs</userinput></screen>
294
295 <screen role="root"><userinput>mkdir -p /usr/share/mkinitramfs &amp;&amp;
296cat &gt; /usr/share/mkinitramfs/init.in &lt;&lt; "EOF"
297<literal>#!/bin/sh
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" ;;
334 PARTUUID=*) eval $root; device="/dev/disk/by-partuuid/$PARTUUID" ;;
335 LABEL=* ) eval $root; device="/dev/disk/by-label/$LABEL" ;;
336 "" ) echo "No root device specified." ; problem ;;
337 esac
338
339 while [ ! -b "$device" ] ; do
340 no_device $device
341 problem
342 done
343
344 if ! mount -n -t "$rootfstype" -o "$rootflags" "$device" /.root ; then
345 no_mount $device
346 cat /proc/partitions
347 while true ; do sleep 10000 ; done
348 else
349 echo "Successfully mounted device $root"
350 fi
351}
352
353do_try_resume()
354{
355 case "$resume" in
356 UUID=* ) eval $resume; resume="/dev/disk/by-uuid/$UUID" ;;
357 LABEL=*) eval $resume; resume="/dev/disk/by-label/$LABEL" ;;
358 esac
359
360 if $noresume || ! [ -b "$resume" ]; then return; fi
361
362 ls -lH "$resume" | ( read x x x x maj min x
363 echo -n ${maj%,}:$min &gt; /sys/power/resume )
364}
365
366init=/sbin/init
367root=
368rootdelay=
369rootfstype=auto
370ro="ro"
371rootflags=
372device=
373resume=
374noresume=false
375
376mount -n -t devtmpfs devtmpfs /dev
377mount -n -t proc proc /proc
378mount -n -t sysfs sysfs /sys
379mount -n -t tmpfs tmpfs /run
380
381read -r cmdline &lt; /proc/cmdline
382
383for param in $cmdline ; do
384 case $param in
385 init=* ) init=${param#init=} ;;
386 root=* ) root=${param#root=} ;;
387 rootdelay=* ) rootdelay=${param#rootdelay=} ;;
388 rootfstype=*) rootfstype=${param#rootfstype=} ;;
389 rootflags=* ) rootflags=${param#rootflags=} ;;
390 resume=* ) resume=${param#resume=} ;;
391 noresume ) noresume=true ;;
392 ro ) ro="ro" ;;
393 rw ) ro="rw" ;;
394 esac
395done
396
397# udevd location depends on version
398if [ -x /sbin/udevd ]; then
399 UDEVD=/sbin/udevd
400elif [ -x /lib/udev/udevd ]; then
401 UDEVD=/lib/udev/udevd
402elif [ -x /lib/systemd/systemd-udevd ]; then
403 UDEVD=/lib/systemd/systemd-udevd
404else
405 echo "Cannot find udevd nor systemd-udevd"
406 problem
407fi
408
409${UDEVD} --daemon --resolve-names=never
410udevadm trigger
411udevadm settle
412
413if [ -f /etc/mdadm.conf ] ; then mdadm -As ; fi
414if [ -x /sbin/vgchange ] ; then /sbin/vgchange -a y &gt; /dev/null ; fi
415if [ -n "$rootdelay" ] ; then sleep "$rootdelay" ; fi
416
417do_try_resume # This function will not return if resuming from disk
418do_mount_root
419
420killall -w ${UDEVD##*/}
421
422exec switch_root /.root "$init" "$@"
423</literal>
424EOF</userinput></screen>
425
426 </sect2>
427
428 <sect2 id="initramfs-install">
429 <title>Using an initramfs</title>
430
431 <bridgehead renderas="sect3">Required Runtime Dependency</bridgehead>
432
433 <para role="required">
434 <xref role="runtime" linkend="cpio"/>
435 </para>
436
437 <bridgehead renderas="sect3">Other Runtime Dependencies</bridgehead>
438
439 <para role="optional">
440 <xref role="runtime" linkend="lvm2"/> and/or
441 <xref role="runtime" linkend="mdadm"/> must be installed before
442 generating the initramfs, if the system partition uses them.
443 </para>
444
445 <para condition="html" role="usernotes">User Notes:
446 <ulink url="&blfs-wiki;/initramfs"/>
447 </para>
448
449
450 <para>
451 To build an initramfs, run the following as the <systemitem
452 class="username">root</systemitem> user:
453 </para>
454
455 <screen role="nodump"><userinput>mkinitramfs [KERNEL VERSION]</userinput></screen>
456
457 <para>
458 The optional argument is the directory where the appropriate kernel
459 modules are located. This must be a subdirectory of <filename
460 class='directory'> /lib/modules</filename>. If no modules are specified,
461 then the initramfs is named <emphasis>initrd.img-no-kmods</emphasis>.
462 If a kernel version is specified, the initrd is named
463 <emphasis>initrd.img-$KERNEL_VERSION</emphasis> and is only appropriate
464 for the specific kernel specified. The output file will be placed in the
465 current directory.
466 </para>
467
468 <para>
469 If early loading of microcode is needed (see <xref
470 linkend="cpu-microcode"/>), you can install the appropriate blob or
471 container in <filename class="directory">/lib/firmware</filename>.
472 It will be automatically added to the initrd when running
473 <command>mkinitramfs</command>.
474 </para>
475
476 <para>
477 After generating the initrd, copy it to the <filename
478 class='directory'>/boot</filename> directory.
479 </para>
480
481 <para>
482 Now edit <filename>/boot/grub/grub.cfg</filename> and add a new
483 menuentry. Below are several examples.
484 </para>
485
486 <screen role="nodump"><userinput># Generic initramfs and root fs identified by UUID
487menuentry "LFS Dev (LFS-7.0-Feb14) initrd, Linux 3.0.4"
488{
489 linux /vmlinuz-3.0.4-lfs-20120214 root=UUID=54b934a9-302d-415e-ac11-4988408eb0a8 ro
490 initrd /initrd.img-no-kmods
491}</userinput></screen>
492
493 <screen role="nodump"><userinput># Generic initramfs and root fs on LVM partition
494menuentry "LFS Dev (LFS-7.0-Feb18) initrd lvm, Linux 3.0.4"
495{
496 linux /vmlinuz-3.0.4-lfs-20120218 root=/dev/mapper/myroot ro
497 initrd /initrd.img-no-kmods
498}</userinput></screen>
499
500 <screen role="nodump"><userinput># Specific initramfs and root fs identified by LABEL
501menuentry "LFS Dev (LFS-7.1-Feb20) initrd label, Linux 3.2.6"
502{
503 linux /vmlinuz-3.2.6-lfs71-120220 root=LABEL=lfs71 ro
504 initrd /initrd.img-3.2.6-lfs71-120220
505}</userinput></screen>
506
507 <para>
508 Finally, reboot the system and select the desired system.
509 </para>
510
511 </sect2>
512
513</sect1>
Note: See TracBrowser for help on using the repository browser.