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
donebusybox:
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
doneglobal 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