TITLE: initrd for LFS LFS VERSION: any AUTHOR: Jim Gifford SYNOPSIS: How to setup initrd for LFS. HINT: $Revision: 1.1 $ Introduction to Initial RAMDisk This hint will help you configure an LFS system for Initial RAMDisk. Which will allow you to add modules at start-up instead of compiling them into the kernel. The script that is enclosed works with SCSI and USB modules only. IDE devices are recommened to be built-in the kernel. The script will auto-detect all SCSI and USB modules and add them to the initial ramdisk. It will also detect the root from the fstab file --- Assumptions Made in this document I have made the following assumptions in this document. Files have been downloaded. --- Kernel Configuration You will need to make sure the following items are configured in your kernel. With out these, the initrd will not work. Block Devices Select Loopback Device Support this can be a module or built-in. Select RAM Disk Support this needs to be compiled as built-in or the initrd will not show up. Set Default RAM Disk size is 4096 which is the default Select Initial RAM Disk (initrd) support needs be selected. --- Needed File System Changes You will need to create a directory for initrd to use. The default one that is looked for is /initrd. To Create this directory use mkdir /initrd Another change that needs to be made is due to a bug in busybox itself. You will need to create a symlink to init and call it linuxrc cd /sbin ln -sf init linuxrc --- Needed Static Modules In order for the initrd to work properly during boot up you will need to create to static programs. The first one being bash. busybox ---- Busybox has a Config.h file that needs the following options enabled to enable them remove the // #define BB_INSMOD #define BB_FEATURE_SH_STANDALONE_SHELL You can configure the rest as you need, but remember have at least the following enabled to make initrd to work properly. #define BB_ASH #define BB_CHROOT #define BB_ECHO #define BB_INSMOD #define BB_MKDIR #define BB_MODPROBE #define BB_MOUNT #define BB_PIVOT_ROOT #define BB_UMOUNT To create a static version of bash needed for initrd use the following commands. cd /usr/src tar zxvf /usr/src/busybox-*.tar.gz cd busy* make LDFLAGS=-static cp busybox /bin/busybox Busybox must be in the /bin directory or the links created during the initrid will fail. --- mkinitrd For those who do not want to type out the script. It is available on my CVS server at http://www.jg555.com/cvs/cvsweb.cgi/scripts/mkinitrd-lfs This script will create the initial RAM Disk image file. By default this script creates /boot/initrd.img The default location for this file is /sbin #!/bin/bash # mkinitrd for LFS by Jim Gifford # $Revision: 1.1 $ # Variables TEMP="$1" KERNEL_VERSION="" CONFIG_FILE="/etc/modules.conf" FSTAB="/etc/fstab" ROOT_DEVICE=$(awk '/^[ \t]*[^#]/ { if ($2 == "/") { print $1; }}' $FSTAB) SCSI_MODULES="`grep scsi_hostadapter $CONFIG_FILE | grep -v '^[ ]*#' | awk '{ print $3 }'`" NEEDED_SCSI="scsi_mod sd_mod" USB_MODULES="`grep usb-controller $CONFIG_FILE | grep -v '^[ ]*#' | awk '{ print $3 }'`" NEEDED_USB="usbcore" MODULES="$NEEDED_SCSI $SCSI_MODULES $NEEDED_USB $USB_MODULES" IMAGE_SIZE=3000 MOUNT_IMAGE="/tmp/initrd.$$" IMAGE="/tmp/initrd.img-$$" MOUNT_POINT="/tmp/initrd.mnt-$$" LINUXRC="$MOUNT_IMAGE/linuxrc" # Check for initrd Directory if ! [ -e /initrd ] then mkdir /initrd fi # Check for RAM Disk Device if [ -e /dev/.devfsd ] then RAM_DEVICE="rd" else RAM_DEVICE="ram0" fi # Check for input if [ "$TEMP" == "" ] then KERNEL_VERSION="`uname -r`" else KERNEL_VERSION="$TEMP" fi INITRD="/boot/initrd-$KERNEL_VERSION.img" if [ "$TEMP" == "-h" ] || [ "$TEMP" == "--h" ] || [ "$TEMP" == "-help" ] || [ "$TEMP" == "--help" ] then echo "usage: mkinitrd kernel_version" echo " : mkinitrd will automatically determin kernel version" exit 1 fi # Creating LoopBack Device dd if=/dev/zero of=$IMAGE bs=1k count=$IMAGE_SIZE 2> /dev/null for device_number in 0 1 2 3 4 5 6 7 8 do if losetup /dev/loop$device_number $IMAGE 2>/dev/null then break fi done if [ "$device_number" = "8" ] then rm -rf $MOUNT_POINT $IMAGE echo "All of your loopback devices are in use!" >&2 exit 1 fi LOOP_DEVICE=/dev/loop$device_number echo y | mke2fs $LOOP_DEVICE $IMAGE_SIZE > /dev/null 2> /dev/null echo "Using loopback device $LOOP_DEVICE" mkdir -p $MOUNT_POINT mount -t ext2 $LOOP_DEVICE $MOUNT_POINT || { echo "Can't get a loopback device" exit 1 } # Creating Directories mkdir -p $MOUNT_IMAGE mkdir -p $MOUNT_IMAGE/lib mkdir -p $MOUNT_IMAGE/bin mkdir -p $MOUNT_IMAGE/etc mkdir -p $MOUNT_IMAGE/dev mkdir -p $MOUNT_IMAGE/proc ln -s /bin $MOUNT_IMAGE/sbin rm -rf $MOUNT_POINT/lost+found # Copying Static Programs cp -a /bin/busybox $MOUNT_IMAGE/bin/busybox ln -s /bin/busybox $MOUNT_IMAGE/bin/echo ln -s /bin/busybox $MOUNT_IMAGE/bin/mount ln -s /bin/busybox $MOUNT_IMAGE/bin/modprobe ln -s /bin/busybox $MOUNT_IMAGE/bin/mkdir ln -s /bin/busybox $MOUNT_IMAGE/bin/sh ln -s /bin/busybox $MOUNT_IMAGE/bin/umount ln -s /bin/busybox $MOUNT_IMAGE/bin/insmod ln -s /bin/busybox $MOUNT_IMAGE/bin/pivot_root cp -a /etc/fstab $MOUNT_IMAGE/etc/fstab cp -a /etc/modules.conf $MOUNT_IMAGE/etc/modules.conf # Copying Modules for MODULE in $MODULES do echo "$MODULE" | { IFS=':' read module options module=$module options=$options DIR_SEARCH1="`ls -1 /lib/modules/$KERNEL_VERSION/kernel/drivers`" for DIR_1SEARCH in $DIR_SEARCH1 do cp /lib/modules/$KERNEL_VERSION/kernel/drivers/$DIR_1SEARCH/$module.o $MOUNT_IMAGE/lib > /dev/null 2>&1 DIR_SEARCH2="`ls -1 /lib/modules/$KERNEL_VERSION/kernel/drivers/$DIR_1SEARCH`" for DIR_2SEARCH in $DIR_SEARCH2 do cp /lib/modules/$KERNEL_VERSION/kernel/drivers/$DIR_1SEARCH/$DIR_2SEARCH/$module.o $MOUNT_IMAGE/lib > /dev/null 2>&1 done done } done for i in console null $RAM_DEVICE tty[1234] do cp -a /dev/$i $MOUNT_IMAGE/dev done # Creating linuxrc File echo "#!/bin/sh" > $LINUXRC echo "" >> $LINUXRC echo "echo \"Initial RAMDISK Loading Starting...\"" >> $LINUXRC for MODULE in $MODULES do echo "$MODULE" | { IFS=':' read module module=$module echo "Loading module $module" echo "insmod /lib/$module.o" >> $LINUXRC } done echo "echo \"Initial RAMDISK Loading Completed...\"" >> $LINUXRC echo "mkdir /new_root" >> $LINUXRC echo "echo \"Mounting proc...\"" >> $LINUXRC echo "mount -n -t proc none /proc" >> $LINUXRC echo "echo 0x0100 > /proc/sys/kernel/real-root-dev" >> $LINUXRC echo "echo \"Mounting real root dev...\"" >> $LINUXRC echo "mount -n -o ro $ROOT_DEVICE /new_root" >> $LINUXRC echo "umount /proc" >> $LINUXRC echo "cd /new_root" >> $LINUXRC echo "echo \"Running pivot_root...\"" >> $LINUXRC echo "pivot_root . initrd" >> $LINUXRC echo "if [ -c initrd/dev/.devfsd ]" >> $LINUXRC echo " then" >> $LINUXRC echo " echo \"Mounting devfs...\"" >> $LINUXRC echo " mount -n -t devfs none dev" >> $LINUXRC echo "fi" >> $LINUXRC echo "if [ \$\$ = 1 ]" >> $LINUXRC echo " then" >> $LINUXRC echo " echo \"Running init...\"" >> $LINUXRC echo " exec chroot . sbin/init dev/console 2>&1" >> $LINUXRC echo " else" >> $LINUXRC echo " echo \"Using bug circumvention for busybox...\"" >> $LINUXRC echo " exec chroot . linuxrc dev/console 2>&1" >> $LINUXRC echo "fi" >> $LINUXRC chmod +x $LINUXRC (cd $MOUNT_IMAGE; tar cf - .) | (cd $MOUNT_POINT; tar xf -) umount $MOUNT_POINT losetup -d $LOOP_DEVICE gzip -9 < $IMAGE > $INITRD rm -rf $MOUNT_IMAGE $MOUNT_POINT $IMAGE lilo -v --- initrd script The following script needs to placed in /etc/rc.d/init.d. You will then need to link it to rcsysinit.d. It is recommended that this script be run right after mountfs. To link the script change to the /etc/rc.d/rcsysinit.d directory and issue the following command. ln -sf ../init.d/initrd S41initrd #!/bin/bash # Begin $rc_base/init.d/initrd # Based on sysklogd script from LFS-3.1 and earlier. # Rewritten by Gerard Beekmans - gerard@linuxfromscratch.org source /etc/sysconfig/rc source $rc_functions echo "Clearing Initial RAM Disk..." if [ -e /initrd/dev/.devfsd ] then umount /initrd/dev fi umount /initrd /sbin/blockdev --flushbufs /dev/ram0 # End $rc_base/init.d/initrd --- For Lilo In order to use the initrd.img file is to add the following entry to you lilo.conf file. initrd=/boot/initrd.img So your lilo.conf should look something like this. image=/boot/vmlinuz-2.4.18 label=test initrd=/boot/initrd-2.4.18.img read-only append="root=/dev/ram0 init=/linuxrc rw" If you are just testing. You should make a separate entry in lilo.conf. This will still allow you to boot. --- For Grub In order to use the initrd.img file is to add the following entry to you menu.lst file. initrd /boot/initrd-2.4.18.img So your menu.lst should look something like this. title test root (hd0,1) kernel /boot/vmlinuz-2.4.18 initrd /boot/initrd-2.4.18.img --- For Syslinux In order to use the initrd.img file is to add the following to syslinux.cfg file. append root=/dev/ram0 initrd=initrd-2.4.18.img So your syslinux.cfg should look something like this. label test kernel vmlinuz append root=/dev/ram0 initrd=initrd.img --- Mail suggestions to giffordj@linkline.com New Version of this document can be viewed from http://www.jg555.com/cvs