source: postlfs/filesystems/initramfs.xml@ f350508

10.0 10.1 11.0 7.10 7.6 7.6-blfs 7.6-systemd 7.7 7.8 7.9 8.0 8.1 8.2 8.3 8.4 9.0 9.1 basic bdubbs/svn elogind gnome kde5-13430 kde5-14269 kde5-14686 ken/refactor-virt krejzi/svn lazarus nosym perl-modules qt5new systemd-11177 systemd-13485 trunk upgradedb xry111/git-date xry111/git-date-for-trunk xry111/git-date-test
Last change on this file since f350508 was f350508, checked in by Pierre Labastie <pieere@…>, 8 years ago

Improve detection and handling of udevd in mkinitramfs;
Put correct date in changelog.

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

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