Professional Documents
Culture Documents
About initramfs
The only purpose of an initramfs is to mount the root filesystem. The initramfs is a
complete set of directories that you would find on a normal root filesystem. It is
bundled into a single cpio archive and compressed with one of several
compression algorithms.
At boot time, the boot loader loads the kernel and the initramfs image into
memory and starts the kernel. The kernel checks for the presence of the initramfs
and, if found, mounts it as / and runs /init. The init program is typically a shell
script. Note that the boot process takes longer, possibly significantly longer, if an
initramfs is used.
For most distributions, kernel modules are the biggest reason to have an initramfs.
In a general distribution, there are many unknowns such as file system types and
disk layouts. In a way, this is the opposite of LFS where the system capabilities
and layout are known and a custom kernel is normally built. In this situation, an
initramfs is rarely needed.
There are only four primary reasons to have an initramfs in the LFS environment:
loading the rootfs from a network, loading it from an LVM logical volume, having
an encrypted rootfs where a password is required, or for the convenience of
specifying the rootfs as a LABEL or UUID. Anything else usually means that the
kernel was not configured properly.
Building an initramfs
If you do decide to build an initramfs, the following scripts will provide a basis to
do it. The scripts will allow specifying a rootfs via partition UUID or partition LABEL
or a rootfs on an LVM logical volume. They do not support an encrypted root file
system or mounting the rootfs over a network card. For a more complete
capability see the LFS Hints or dracut.
To install these scripts, run the following commands as the root user:
copy()
{
local file
if [ -n $file ] ; then
cp $file $WDIR/$2
else
echo "Missing required file: $1 for directory $2"
rm -rf $WDIR
exit 1
fi
}
if [ -z $1 ] ; then
INITRAMFS_FILE=initrd.img-no-kmods
else
KERNEL_VERSION=$1
INITRAMFS_FILE=initrd.img-$KERNEL_VERSION
fi
unsorted=$(mktemp /tmp/unsorted.XXXXXXXXXX)
DATADIR=/usr/share/mkinitramfs
INITIN=init.in
if [ -n "$KERNEL_VERSION" ] ; then
if [ -x /bin/kmod ] ; then
binfiles="$binfiles kmod"
else
binfiles="$binfiles lsmod"
sbinfiles="$sbinfiles insmod"
fi
fi
for f in $sbinfiles ; do
ldd /sbin/$f | sed "s/\t//" | cut -d " " -f1 >> $unsorted
copy $f sbin
done
ln -s lvm $WDIR/sbin/pvchange
ln -s lvm $WDIR/sbin/pvck
ln -s lvm $WDIR/sbin/pvcreate
ln -s lvm $WDIR/sbin/pvdisplay
ln -s lvm $WDIR/sbin/pvscan
ln -s lvm $WDIR/sbin/vgchange
ln -s lvm $WDIR/sbin/vgcreate
ln -s lvm $WDIR/sbin/vgscan
ln -s lvm $WDIR/sbin/vgrename
ln -s lvm $WDIR/sbin/vgck
# Conf file(s)
cp -a /etc/lvm $WDIR/etc
fi
# Install libraries
sort $unsorted | uniq | while read library ; do
if [ "$library" == "linux-vdso.so.1" ] ||
[ "$library" == "linux-gate.so.1" ]; then
continue
fi
cp /lib/modules/$KERNEL_VERSION/modules.{builtin,order} \
$WDIR/lib/modules/$KERNEL_VERSION
EOF
PATH=/bin:/usr/bin:/sbin:/usr/sbin
export PATH
problem()
{
printf "Encountered a problem!\n\nDropping you to a shell.\n\n"
sh
}
no_device()
{
printf "The device %s, which is supposed to contain the\n" $1
printf "root file system, does not exist.\n"
printf "Please fix this problem and exit this shell.\n\n"
}
no_mount()
{
printf "Could not mount device %s\n" $1
printf "Sleeping forever. Please reboot and fix the kernel command line.\n\n"
printf "Maybe the device is formatted with an unsupported file system?\n\n"
printf "Or maybe filesystem type autodetection went wrong, in which case\n"
printf "you should add the rootfstype=... parameter to the kernel command line.\n\n"
printf "Available partitions:\n"
}
do_mount_root()
{
mkdir /.root
[ -n "$rootflags" ] && rootflags="$rootflags,"
rootflags="$rootflags$ro"
case "$root" in
/dev/* ) device=$root ;;
UUID=* ) eval $root; device="/dev/disk/by-uuid/$UUID" ;;
LABEL=*) eval $root; device="/dev/disk/by-label/$LABEL" ;;
"" ) echo "No root device specified." ; problem ;;
esac
while [ ! -b "$device" ] ; do
no_device $device
problem
done
init=/sbin/init
root=
rootdelay=
rootfstype=auto
ro="ro"
rootflags=
device=
do_mount_root
killall -w ${UDEVD##*/}
EOF
Using an initramfs
Required Runtime Dependency
cpio-2.12
The optional argument is the directory where the appropriate kernel modules are
located. This must be a subdirectory of /lib/modules. If no modules are specified,
then the initramfs is named initrd.img-no-kmods. If a kernel version is specified,
the initrd is named initrd.img-$KERNEL_VERSION and is only appropriate for the
specific kernel specified. The output file will be placed in the current directory.
Now edit /boot/grub/grub.cfg and add a new menuentry. Below are several examples.