This section describes how to create an initramfs from scratch. We assume we are working in a dedicated directory:
mkdir /tmp/initrd cd /tmp/initrd
for dynamically linked programs:
LD_TRACE_LOADED_OBJECTS=1 /lib/ld-linux.so.2 /sbin/lvm
for statically linked programs:
LANG=C readelf -e /usr/lib/klibc/bin/run-init | grep 'interpreter:'
mkdir -p bin sbin dev etc etc/udev/rules.d lib lib/udev/rules.d \ lib/modules/3.10.1 root usr/share
We mainly use busybox for our initrd, but instead of using pivot_root and chroot to run the init file on the new root filesystem, we use run-init from the klibc project:
cp /usr/lib/klibc/bin/run-init bin
It needs the klibc interpreter:
cp /lib/klibc-HD4lPOAFFcrZF9wKjmJlHFIQD-4.so lib
for p in /bin/busybox /bin/ksh /bin/disp /usr/bin/loadkeys /bin/bc do cp $p bin done for p in /sbin/lvm /sbin/udevd /sbin/udevadm do cp $p sbin done
for l in libc.so.6 ld-linux.so.2 libdl.so.2 libm.so.6 \ libdevmapper.so.1.02 libreadline.so.5 librt.so.1 libncurses.so.5 \ libncursesw.so.5 libpthread.so.0 libnss_files.so.2 do cp /lib/$l lib done
busybox:
cd bin ./busybox --list | while read p; do ln -s busybox $p; done rm modprobe cd ../sbin ln -s ../bin/busybox modprobe cd ..
lvm:
cd sbin ./lvm help 2>&1 | grep '^ [^ ]' | sed 1,2d | grep -v '^ help ' | \ awk '{ print $1 }' | while read p; do ln -s lvm $p; done cd ..
selective copy:
for m in fs/ext4/ext4.ko lib/crc16.ko fs/jbd2/jbd2.ko \ fs/mbcache.ko drivers/scsi/sg.ko drivers/scsi/sr_mod.ko \ drivers/scsi/sd_mod.ko drivers/cdrom/cdrom.ko drivers/ata/ata_piix.ko \ drivers/ata/libata.ko drivers/scsi/scsi_mod.ko md/dm-mod.ko do cp /lib/modules/3.10.1/kernel/$m lib/modules/3.10.1 done
global copy:
rsync -a /lib/modules/3.10.1 lib/modules
depmod:
cd lib/modules/3.10.1 depmod -b $(pwd)/../../.. 3.10.1 cd ../../..
#!/bin/ksh shell_escape () { export PATH=/bin:/sbin [ -d /dev ] || mkdir -m 0755 /dev [ -d /root ] || mkdir --mode=0700 /root [ -d /sys ] || mkdir /sys [ -d /proc ] || mkdir /proc [ -d /tmp ] || mkdir /tmp mountpoint -q /sys || mount -t sysfs none /sys -onodev,noexec,nosuid mountpoint -q /proc || mount -t proc none /proc -onodev,noexec,nosuid [ -d /dev/pts ] || mkdir /dev/pts [ -e /dev/console ] || mknod /dev/console c 5 1 [ -e /dev/null ] || mknod /dev/null c 1 3 /sbin/udevd --daemon udevadm trigger udevadm settle for mod in dm_mod ext4 iso9660 do modprobe -q $mod done } print ' __ __ _ \ \ / / | | \ \ /\ / /_ _| | _____ ___ \ \/ \/ / _` | |/ / _ \/ __| \ /\ / (_| | < __/\__ \ \/ \/ \__,_|_|\_\___||___/ A GNU/Linux operating system. ' print ' ############################################################################## # # # Starting initramfs boot scripts # # # ############################################################################## ' export PATH=/bin:/sbin [ -d /dev ] || mkdir -m 0755 /dev [ -d /root ] || mkdir --mode=0700 /root [ -d /sys ] || mkdir /sys [ -d /proc ] || mkdir /proc [ -d /tmp ] || mkdir /tmp disp "Mounting /sys" \ mount -t sysfs none /sys -onodev,noexec,nosuid disp "Mounting /proc" \ mount -t proc none /proc -onodev,noexec,nosuid mkdir /dev/pts [ -e /dev/console ] || mknod /dev/console c 5 1 [ -e /dev/null ] || mknod /dev/null c 1 3 disp "Starting udev" /sbin/udevd --daemon rc=$? udevadm trigger udevadm settle disp $rc for mod in dm_mod ext4 iso9660 do disp "Loading $mod" modprobe -q $mod done for x in $(</proc/cmdline) do case $x in lang=*) lang=${x#lang=} disp "Setting $lang keyboard layout" loadkeys $lang ;; root=*) root=${x#root=} ;; esac done disp "Stopping udevd" for f in /proc/*/exe do l=$(readlink $f) if [ "$l" == /sbin/udevd ] then pid=$(print $f | cut -d'/' -f3) kill $pid rc=$? break fi done disp $rc case $root in /dev/*/*) vg=$(print $root | cut -d'/' -f3) if vgdisplay | grep "VG Name" | awk '{ print $NF }' | grep -qw $vg then disp "Activate $vg" vgchange -a y $vg disp "Mounting $root" mount $root /root else print "" print "error: vg $vg not found, exiting to shell." . /etc/profile shell_escape exec /bin/ksh fi ;; esac if [ -n "$root" ] then disp "Unmounting /sys" umount /sys disp "Unmounting /proc" umount /proc print "" exec run-init /root /sbin/init else print "" . /etc/profile shell_escape exec /bin/ksh fi
chmod 755 init
find . | cpio --quiet -H newc -o | gzip -9 -n > /boot/initrd-3.10.1