Difference between revisions of "Creating an Initramfs"

From CBLFS
Jump to navigationJump to search
(I wrote this script myself compiled from various information I found by googling)
 
Line 9: Line 9:
  
 
== Creating the mkinitramfs script ==
 
== Creating the mkinitramfs script ==
 
+
cat > /usr/sbin/mkinitramfs << "EOF"
  cat > /usr/sbin/mkinitramfs << "END"
+
#!/bin/bash
  #!/bin/bash
+
errmsg(){
  # This is a bash script to create a busybox
+
cat << EOT
   # based gzipped cpio archive to be used as
+
   [ERROR] $@
  # an initrd
+
EOT
  INITRAMFS_USE_KERNEL="$(uname -r)"
+
}
  INITRAMFS_OUTPUT="/boot/initramfs.igz"
+
killme(){
  until [ -z "${1}" ]; do
+
errmsg "$@"
    case ${1} in
+
errmsg "Exiting ..."
      -c) rm -rf /boot/initramfs-tree
+
exit 1
      ;;
+
}
      -k)
+
helpme(){
      INITRAMFS_USE_KERNEL="${2}"
+
cat << EOT
      shift
+
  $(basename ${0}) is a script to automagically make
      ;;
+
  a gzip compressed cpio archive containsing busybox
      -m)
+
  which can act as an initrd.
      INITRAMFS_USE_MODULES="${2}"
+
      shift
+
  -c - remove initramfs-tree before creating the
      ;;
+
  initramfs
      -v|--verbose)
+
      INITRAMFS_USE_VERBOSE="true"
+
  -v|--verbose - use verbose messages
      ;;
+
      -m)
+
  -k <version> - use modules from kernel <version>
      INITRAMFS_USE_MODULES="${2}"
+
      shift
+
  -m <arg1,arg2> - comma separated list of additional modules
      ;;
+
  besides the ones contained in the file
      -o)
+
  /etc/sysconfig/mkinitramfs.modules to add
      INITRAMFS_OUTPUT="${2}"
+
  to the initramfs archive
      shift
+
      ;;
+
  -o <arg> - output finished archive to <arg> instead
    esac
+
  of /boot/initramfs.igz
    shift
+
   done
+
   -r|--rootfs - use device as root device
   ermsg(){
+
    cat << EOF
+
   -f|--rootfstype - use filesystem type for root device
  [ERROR] $@
+
  EOF
+
Example:
  }
+
EOT
  killme(){
+
}
    ermsg "$@"
+
usage(){
    ermsg "Exiting ..."
+
cat << EOT
    exit 1
+
  $(basename ${0}) -c -k 2.6.30.2 -m ext3 -r /dev/hda3 -f ext3
  }
+
EOT
  vrbmsg(){
+
}
    if [ "${INITRAMFS_USE_VERBOSE}" = 'true' ]; then
+
vrbmsg(){
      cat << EOF
+
if [ "${initramfs_use_verbose}" ]; then
  $@
+
cat << EOT
  EOF
+
$@
    fi
+
EOT
  }
+
fi
  if [ ! -x /bin/busybox ]; then
+
}
    killme "The initramfs needs busybox ..."
+
fnd_mod(){
  fi
+
module="$(find /lib/modules/${initramfs_use_kernel} -name ${1}.ko)"
  if [ ! -x /usr/bin/cpio ]; then
+
if [ ! -n "${module}" ]; then
    killme "The initramfs needs cpio ..."
+
module="$(find /lib/modules/${initramfs_use_kernel} -name ${1}.ko.gz)"
  fi
+
fi
  if [ ! -x /bin/gzip ]; then
+
cat << EOT
    killme "The initramfs needs gzip ..."
+
${module}
  fi
+
EOT
  rm -f /tmp/mkinitramfs.modules
+
unset module
  rm -f /tmp/mkinitramfs.moddeps
+
}
  get_moddeps(){
+
initramfs_use_kernel="$(uname -r)"
    if [ -f /lib/modules/${INITRAMFS_USE_KERNEL}/modules.dep ]; then
+
initramfs_output="/boot/initramfs.igz"
      grep "${1}": /lib/modules/${INITRAMFS_USE_KERNEL}/modules.dep \
+
initramfs_use_rootfs="/dev/hda2"
  | sed -e "s|${1}:||"
+
initramfs_use_rootfstype="ext3"
    else
+
until [ -z "${1}" ]; do
      cat << EOF
+
case "${1}" in
  get_moddeps failure
+
-c)
  EOF
+
rm -rf /boot/initramfs-tree
    fi
+
;;
  }
+
-v|--verbose)
  fnd_module(){
+
initramfs_use_verbose='true'
    fnd_mod_outpt="$(find /lib/modules/${INITRAMFS_USE_KERNEL} -name ${1}.ko)"
+
;;
    if [ -z "${fnd_mod_oupt}" ]; then
+
-k)
      fnd_mod_outpt="$(find /lib/modules/${INITRAMFS_USE_KERNEL} -name ${1}.ko.gz)"
+
initramfs_use_kernel="${2}"
    fi
+
shift
    echo ${fnd_mod_outpt} | sed -e "s|/lib/modules/${INITRAMFS_USE_KERNEL}/||"
+
;;
  }
+
-m)
  if [ ! -d /boot/initramfs-tree ]; then
+
initramfs_use_modules="${2}"
    mkdir /boot/initramfs-tree &&
+
shift
    mkdir /boot/initramfs-tree/{etc,bin,sbin,lib} &&
+
;;
    mkdir /boot/initramfs-tree/{proc,root,mnt,sys}
+
-o)
    mkdir /boot/initramfs-tree/lib/modules \
+
initramfs_output="${2}"
  || killme "Problem making the initramfs-tree ..."
+
shift
    ln -s . /boot/initramfs-tree/usr
+
;;
  fi
+
-r|--rootfs)
  if [ -f /etc/sysconfig/initramfs.modules ]; then
+
initramfs_use_rootfs="${2}"
    cat /etc/sysconfig/initramfs.modules | while read line; do
+
shift
      if [ -n "${line}" -a "$(head -c1 <<<${line})" != "#" ]; then
+
;;
        if [ -n "$(fnd_module ${line})" ]; then
+
-f|--rootfstype)
          fnd_module ${line} >> /tmp/mkinitramfs.modules
+
initramfs_use_rootfstype="${2}"
        else
+
shift
          ermsg "Couldn't find module ${line}"
+
;;
        fi
+
-h|--help)
      fi
+
helpme
    done
+
usage
  fi
+
exit 0
  if [ -n "${INITRAMFS_USE_MODULES}" ]; then
+
;;
    for ITEM in $(echo ${INITRAMFS_USE_MODULES//,/ }); do
+
-u|--usage)
      if [ -n "$(fnd_module ${ITEM})" ]; then
+
usage
        fnd_module ${ITEM} >> /tmp/mkinitramfs.modules
+
exit 0
      else
+
;;
        ermsg "Couldn't find module ${ITEM}"
+
esac
      fi
+
shift
    done
+
done
    unset ITEM
+
for mkinitramfs_tool in /bin/busybox /usr/bin/cpio /bin/gzip; do
  fi
+
if [ ! -x "${mkinitramfs_tool}" ]; then
  touch /tmp/mkinitramfs.moddeps
+
killme "Required tool ${mkinitramfs_tool} missing!"
  if [ -f /tmp/mkinitramfs.modules ]; then
+
fi
    cat /tmp/mkinitramfs.modules | while read IMOD; do
+
done
      vrbmsg "generating module dependencies for ${IMOD}" &&
+
if [ ! -d "$(dirname ${initramfs_output})" ]; then
      if [ "$(get_moddeps ${IMOD})" != "get_moddeps failure" ]; then
+
killme "Can not create ${initramfs_output}"
        if [ -n "$(get_moddeps ${IMOD})" ]; then
+
fi
          for ITEM in $(get_moddeps ${IMOD}); do
+
if [ ! -d '/boot/initramfs-tree' ]; then
            if [ -z "$(grep ${IMOD} /tmp/mkinitramfs.moddeps)" ]; then
+
mkdir /boot/initramfs-tree
              echo "${ITEM}" >> /tmp/mkinitramfs.moddeps
+
mkdir /boot/initramfs-tree/{bin,sbin,lib,etc,proc}
            fi
+
mkdir /boot/initramfs-tree/{lib/modules,root,sys,mnt}
          done
+
ln -s . /boot/initramfs-tree/usr
          unset ITEM
+
fi
        fi
+
if [ -f /etc/sysconfig/initramfs.modules ]; then
      fi
+
cat /etc/sysconfig/initramfs.modules | while read line; do
      if [ -z "$(grep ${IMOD} /tmp/mkinitramfs.moddeps)" ]; then
+
if [ -n "${line}" -a "$(head -c1 <<<${line})" != "#" ]; then
        echo "${IMOD}" >> /tmp/mkinitramfs.moddeps
+
module="$(fnd_mod ${line})"
      fi
+
if [ -n "${module}" ]; then
    done
+
vrbmsg "Found ${module}"
  fi
+
case "${module}" in
  unset IMOD
+
*.ko)
  if [ -f /tmp/mkinitramfs.moddeps ]; then
+
cat ${module} > /boot/initramfs-tree/lib/modules/$(basename ${module})
    cat /tmp/mkinitramfs.moddeps | while read line; do
+
;;
      case ${line} in
+
*.ko.gz)
        *.ko.gz)
+
gzip -dc ${module} > /boot/initramfs-tree/lib/modules/$(basename ${module} .gz)
        gzip -dc /lib/modules/${INITRAMFS_USE_KERNEL}/${line} \
+
;;
  > /boot/initramfs-tree/lib/modules/$(basename ${line} .ko.gz).ko
+
esac
        echo "$(basename ${line} .ko.gz)" >> /boot/initramfs-tree/etc/modules
+
else
        ;;
+
errmsg "Couldn't find ${line}"
        *.ko)
+
fi
        cat /lib/modules/${MKINITRAMFS_USE_KERNEL}/${line} \
+
fi
  > /boot/initramfs-tree/lib/modules/$(basename ${line})
+
done
        echo "$(basename ${line} .ko)" >> /boot/initramfs-tree/etc/modules
+
fi
        ;;
+
if [ -n "${initramfs_use_modules}" ]; then
      esac
+
for line in ${initramfs_use_modules//,/ }; do
    done
+
module="$(fnd_mod ${line})"
  fi
+
if [ -n "${module}" ]; then
  # Now for the init
+
vrbmsg "Found ${module}"
  cat << "EOT" >/boot/initramfs-tree/init
+
case "${module}" in
  #!/bin/busybox sh
+
*.ko)
  # Mount things which are needed by this script
+
cat ${module} > /boot/initramfs-tree/lib/modules/$(basename ${module})
  /bin/busybox mount -t proc proc /proc
+
echo "$(basename ${module} .ko)" >> /boot/initramfs-tree/etc/modules
  /bin/busybox mount -t sysfs sysfs /sys
+
;;
  # Disable kernel messages from popping up on
+
*.ko.gz)
  # the screen
+
gzip -dc ${module} > /boot/initramfs-tree/lib/modules/$(basename ${module} .gz)
  /bin/busybox echo 0 > /proc/sys/kernel/printk
+
echo "$(basename ${module} .ko.gz)" >> /boot/initramfs-tree/etc/modules
  # Clear the screen
+
;;
  /bin/busybox clear
+
esac
  /bin/busybox cat << EOF
+
else
  This system is uses Community Beyond Linux From Scratch
+
errmsg "Couldn't find ${line}"
  <http://cblfs.cross-lfs.org/>
+
fi
  EOF
+
done
  # Create the symlinks to busybox
+
fi
  /bin/busybox --install -s
+
cat /bin/busybox > /boot/initramfs-tree/bin/busybox
  # Create device nodes
+
chmod 755 /boot/initramfs-tree/bin/busybox
  /bin/busybox mknod /dev/null c 1 3
+
cat > /boot/initramfs-tree/init << EOT
  /bin/busybox mknod /dev/tty c 5 0
+
#!/bin/busybox sh
  # Check for modules
+
# Mount things which are needed by this script
  if [ -f /etc/modules ]; then
+
/bin/busybox mount -t proc proc /proc
    /bin/busybox depmod /lib/modules
+
/bin/busybox mount -t sysfs sysfs /sys
    /bin/busybox cat /etc/modules | while read line; do
+
# Disable kernel messages from popping up on
      if [ -n "${line}" ]; then
+
# the screen
        /bin/busybox modprobe ${line/.ko/}
+
/bin/busybox echo 0 > /proc/sys/kernel/printk
      fi
+
# Clear the screen
    done
+
/bin/busybox clear
  fi
+
/bin/busybox cat << END
  # Sleep for devices to connect, like USB
+
  This system is uses Community Beyond Linux From Scratch
  /bin/busybox sleep 5
+
  <http://cblfs.cross-lfs.org/>
  /bin/busybox mdev -s
+
END
  # Function for parsing command line options with
+
# Create the symlinks to busybox
  # '=' in them. Ex. get_opt("init=/sbin/init")
+
/bin/busybox --install -s
  # would return "/sbin/init"
+
# Create device nodes
  get_opt() {
+
/bin/busybox mknod /dev/null c 1 3
  echo "$@" | /bin/busybox cut -d "=" -f 2
+
/bin/busybox mknod /dev/tty c 5 0
  }
+
# Check for modules
  # Defaults
+
if [ -f /etc/modules ]; then
  init="/sbin/init"
+
  /bin/busybox depmod /lib/modules
  root="/dev/hda1"
+
  /bin/busybox cat /etc/modules | while read line; do
  runlevel="3"
+
    if [ -n "\${line}" ]; then
  for i in $(cat /proc/cmdline); do
+
      /bin/busybox modprobe \${line/.ko/}
  case ${i} in
+
    fi
  root\=*)
+
  done
  root=$(get_opt ${i})
+
fi
  ;;
+
# Sleep for devices to connect, like USB
  init\=*)
+
/bin/busybox sleep 5
  init=$(get_opt ${i})
+
/bin/busybox mdev -s
  ;;
+
# Function for parsing command line options with
  runlevel\=*)
+
# '=' in them. Ex. get_opt("init=/sbin/init")
  runlevel=$(get_opt ${i})
+
# would return "/sbin/init"
  ;;
+
get_opt() {
  esac
+
echo "\$@" | /bin/busybox cut -d "=" -f 2
  done
+
}
  # Mount the root device
+
# Defaults
  mount -o ro "${root}" /root
+
init="/sbin/init"
  # Below is an example for loading a disk image from
+
root="${initramfs_use_rootfs}"
  # a linux partition
+
runlevel="3"
  if [ -f /root/lfs-root.img ]; then
+
for i in \$(cat /proc/cmdline); do
    BNROOT=$(/bin/busybox basename "${root}")
+
case \${i} in
    umount root
+
root\=*)
    mkdir -p /mnt/"${BNROOT}" &&
+
root=\$(get_opt \${i})
    mount "${root}" /mnt/"${BNROOT}" &&
+
;;
    mount -o loop /mnt/"${BNROOT}"/lfs-root.img /root &&
+
init\=*)
    # Make sure that we don't lose access to the partition
+
init=\$(get_opt \${i})
    # containing the disk image
+
;;
    mkdir -p /root/mnt/"${BNROOT}" &&
+
runlevel\=*)
    mount /mnt/"${BNROOT}" /root/mnt/"${BNROOT}"
+
runlevel=\$(get_opt \${i})
    unset BNROOT
+
;;
  fi
+
esac
  # Check if the $init exists, and is executable
+
done
  if [[ -x "/root/${init}" ]]; then
+
# Mount the root device
  # Unmount all other mounts so that the ram used by
+
mount -o ro -t ${initramfs_use_rootfstype} "\${root}" /root
  # the initramfs can be cleared after switch_root
+
if [ -f /root/lfs-root.img ]; then
  umount /sys /proc
+
  BNROOT=\$(/bin/busybox basename "\${root}")
 
+
  umount root
 +
  mkdir -p /mnt/"\${BNROOT}" &&
 +
  mount "\${root}" /mnt/"\${BNROOT}" &&
 +
  mount -o loop /mnt/"\${BNROOT}"/lfs-root.img /root &&
 +
  mkdir -p /root/mnt/"\${BNROOT}" &&
 +
  mount /mnt/"\${BNROOT}" /root/mnt/"\${BNROOT}"
 +
  unset BNROOT
 +
fi
 +
if [[ -x "/root/\${init}" ]]; then
 +
# Unmount all other mounts so that the ram used by
 +
# the initramfs can be cleared after switch_root
 +
umount /sys /proc
 
   # Switch to the new root and execute the init at
 
   # Switch to the new root and execute the init at
  # the specified runlevel
+
# the specified runlevel
  exec switch_root /root "${init}" "${runlevel}"
+
exec switch_root /root "\${init}" "\${runlevel}"
  fi
+
fi
 
+
echo "Failed 'exec switch_root /root \\"\${init}\\" \\"\${runlevel}\\"'"
  # This will only be run if the exec above failed
+
exec sh
  echo "Failed 'exec switch_root /root \"${init}\" \"${runlevel}\"'"
+
EOT
  exec sh
+
chmod 755 /boot/initramfs-tree/init
  EOT
+
EOF
  chmod 0755 /boot/initramfs-tree/init
+
chmod 755 /usr/sbin/mkinitramfs
  cat /bin/busybox > /boot/initramfs-tree/bin/busybox
 
  chmod 0755 /boot/initramfs-tree/bin/busybox
 
  if [ ! -d "$(dirname ${INITRAMFS_OUTPUT})" ]; then
 
    killme "Cannot create ${INITRAMFS_OUTPUT}"
 
  fi
 
  ( cd /boot/initramfs-tree &&
 
    find . | cpio -H newc -o | gzip -9c > ${INITRAMFS_OUTPUT} || exit 1
 
  ) || exit 1
 
  rm -f /tmp/mkinitramfs.modules
 
  rm -f /tmp/mkinitramfs.moddeps
 
  unset INITRAMFS_OUTPUT INITRAMFS_USE_KERNEL INITRAMFS_USE_MODULES INITRAMFS_USE_KERNEL
 
  END
 
  chmod 0755 /usr/sbin/mkinitramfs
 

Revision as of 23:45, 29 October 2009

Introduction to Creating an Initramfs

The mkinitramfs script creates a gzip compressed cpio archive using busybox and a simple shell init script, which can be used in place of an initrd to do such things as load kernel modules before the system boots, in order to access functionality that is not compiled into the kernel, and therefore must be loaded, such as usb disks, scsi disks, etc. This is different than loading modules automatically at boot time, because those are loaded after the root disk is mounted, fsck'd etc, and typically an initrd contains modules which are loaded into the kernel before anything else, to fascilitate mounting the root fs. IE kernel doesn't have reiserfs support compiled in, but your root fs is formatted reiserfs

Project Homepage: Unknown

Dependencies

Required

Caution.png

Note

The init script created for the initramfs will drop to the shell in busybox if there is an error, while only a few things are actually needed for the init to function, while compiling busybox you might want to keep in mind that it may need additional functionality to be able to work properly if the initramfs drops to the shell. Also this assumes that busybox is compiled statically linked, if that is not the case, additional libraries will be required to be added to the initramfs-tree. To test this run 'file /bin/busybox'. If file reports it as dynamically linked, running 'ldd /bin/busybox' should help you determine what libraries may be needed.

Creating the mkinitramfs script

cat > /usr/sbin/mkinitramfs << "EOF"
#!/bin/bash
errmsg(){
	cat << EOT
 [ERROR] $@
EOT
}
killme(){
	errmsg "$@"
	errmsg "Exiting ..."
	exit 1
}
helpme(){
	cat << EOT
 $(basename ${0}) is a script to automagically make
 a gzip compressed cpio archive containsing busybox
 which can act as an initrd.

 -c			- remove initramfs-tree before creating the
			  initramfs

 -v|--verbose		- use verbose messages

 -k <version>		- use modules from kernel <version>

 -m <arg1,arg2>		- comma separated list of additional modules
			  besides the ones contained in the file
			  /etc/sysconfig/mkinitramfs.modules to add
			  to the initramfs archive

 -o <arg>		- output finished archive to <arg> instead
			  of /boot/initramfs.igz

 -r|--rootfs		- use device as root device

 -f|--rootfstype	- use filesystem type for root device

Example:
EOT
}
usage(){
	cat << EOT
 $(basename ${0}) -c -k 2.6.30.2 -m ext3 -r /dev/hda3 -f ext3
EOT
}
vrbmsg(){
	if [ "${initramfs_use_verbose}" ]; then
		cat << EOT
$@
EOT
	fi
}
fnd_mod(){
	module="$(find /lib/modules/${initramfs_use_kernel} -name ${1}.ko)"
	if [ ! -n "${module}" ]; then
		module="$(find /lib/modules/${initramfs_use_kernel} -name ${1}.ko.gz)"
	fi
	cat << EOT
${module}
EOT
	unset module
}
initramfs_use_kernel="$(uname -r)"
initramfs_output="/boot/initramfs.igz"
initramfs_use_rootfs="/dev/hda2"
initramfs_use_rootfstype="ext3"
until [ -z "${1}" ]; do
	case "${1}" in
		-c)
			rm -rf /boot/initramfs-tree
			;;
		-v|--verbose)
			initramfs_use_verbose='true'
			;;
		-k)
			initramfs_use_kernel="${2}"
			shift
			;;
		-m)
			initramfs_use_modules="${2}"
			shift
			;;
		-o)
			initramfs_output="${2}"
			shift
			;;
		-r|--rootfs)
			initramfs_use_rootfs="${2}"
			shift
			;;
		-f|--rootfstype)
			initramfs_use_rootfstype="${2}"
			shift
			;;
		-h|--help)
			helpme
			usage
			exit 0
			;;
		-u|--usage)
			usage
			exit 0
			;;
	esac
	shift
done
for mkinitramfs_tool in /bin/busybox /usr/bin/cpio /bin/gzip; do
	if [ ! -x "${mkinitramfs_tool}" ]; then
		killme "Required tool ${mkinitramfs_tool} missing!"
	fi
done
if [ ! -d "$(dirname ${initramfs_output})" ]; then
	killme "Can not create ${initramfs_output}"
fi
if [ ! -d '/boot/initramfs-tree' ]; then
	mkdir /boot/initramfs-tree
	mkdir /boot/initramfs-tree/{bin,sbin,lib,etc,proc}
	mkdir /boot/initramfs-tree/{lib/modules,root,sys,mnt}
	ln -s . /boot/initramfs-tree/usr
fi
if [ -f /etc/sysconfig/initramfs.modules ]; then
	cat /etc/sysconfig/initramfs.modules | while read line; do
		if [ -n "${line}" -a "$(head -c1 <<<${line})" != "#" ]; then
			module="$(fnd_mod ${line})"
			if [ -n "${module}" ]; then
				vrbmsg "Found ${module}"
				case "${module}" in
					*.ko)
						cat ${module} > /boot/initramfs-tree/lib/modules/$(basename ${module})
						;;
					*.ko.gz)
						gzip -dc ${module} > /boot/initramfs-tree/lib/modules/$(basename ${module} .gz)
						;;
				esac
			else
				errmsg "Couldn't find ${line}"
			fi
		fi
	done
fi
if [ -n "${initramfs_use_modules}" ]; then
	for line in ${initramfs_use_modules//,/ }; do
		module="$(fnd_mod ${line})"
		if [ -n "${module}" ]; then
			vrbmsg "Found ${module}"
			case "${module}" in
				*.ko)
					cat ${module} > /boot/initramfs-tree/lib/modules/$(basename ${module})
					echo "$(basename ${module} .ko)" >> /boot/initramfs-tree/etc/modules
					;;
				*.ko.gz)
					gzip -dc ${module} > /boot/initramfs-tree/lib/modules/$(basename ${module} .gz)
					echo "$(basename ${module} .ko.gz)" >> /boot/initramfs-tree/etc/modules
					;;
			esac
		else
			errmsg "Couldn't find ${line}"
		fi
	done
fi
cat /bin/busybox > /boot/initramfs-tree/bin/busybox
chmod 755 /boot/initramfs-tree/bin/busybox
cat > /boot/initramfs-tree/init << EOT
#!/bin/busybox sh
# Mount things which are needed by this script
/bin/busybox mount -t proc proc /proc
/bin/busybox mount -t sysfs sysfs /sys
# Disable kernel messages from popping up on
# the screen
/bin/busybox echo 0 > /proc/sys/kernel/printk
# Clear the screen
/bin/busybox clear
/bin/busybox cat << END
 This system is uses Community Beyond Linux From Scratch
 <http://cblfs.cross-lfs.org/>
END
# Create the symlinks to busybox
/bin/busybox --install -s
# Create device nodes
/bin/busybox mknod /dev/null c 1 3
/bin/busybox mknod /dev/tty c 5 0
# Check for modules
if [ -f /etc/modules ]; then
  /bin/busybox depmod /lib/modules
  /bin/busybox cat /etc/modules | while read line; do
    if [ -n "\${line}" ]; then
      /bin/busybox modprobe \${line/.ko/}
    fi
  done
fi
# Sleep for devices to connect, like USB
/bin/busybox sleep 5
/bin/busybox mdev -s
# Function for parsing command line options with
# '=' in them. Ex. get_opt("init=/sbin/init")
# would return "/sbin/init"
get_opt() {
	echo "\$@" | /bin/busybox cut -d "=" -f 2
}
# Defaults
init="/sbin/init"
root="${initramfs_use_rootfs}"
runlevel="3"
for i in \$(cat /proc/cmdline); do
	case \${i} in
		root\=*)
			root=\$(get_opt \${i})
			;;
		init\=*)
			init=\$(get_opt \${i})
			;;
		runlevel\=*)
			runlevel=\$(get_opt \${i})
			;;
	esac
done
# Mount the root device
mount -o ro -t ${initramfs_use_rootfstype} "\${root}" /root
if [ -f /root/lfs-root.img ]; then
  BNROOT=\$(/bin/busybox basename "\${root}")
  umount root
  mkdir -p /mnt/"\${BNROOT}" &&
  mount "\${root}" /mnt/"\${BNROOT}" &&
  mount -o loop /mnt/"\${BNROOT}"/lfs-root.img /root &&
  mkdir -p /root/mnt/"\${BNROOT}" &&
  mount /mnt/"\${BNROOT}" /root/mnt/"\${BNROOT}"
  unset BNROOT
fi
if [[ -x "/root/\${init}" ]]; then
	# Unmount all other mounts so that the ram used by
	# the initramfs can be cleared after switch_root
	umount /sys /proc
 	# Switch to the new root and execute the init at
	# the specified runlevel
	exec switch_root /root "\${init}" "\${runlevel}"
fi
echo "Failed 'exec switch_root /root \\"\${init}\\" \\"\${runlevel}\\"'"
exec sh
EOT
chmod 755 /boot/initramfs-tree/init
EOF
chmod 755 /usr/sbin/mkinitramfs