Archive for March, 2009

Embedded x86 Linux Revisited

March 4, 2009

Now that flash is really cheap, why use squashfs?  Save some time and effort and use this in your initrd for a readonly flash file system.

A non-wordpress-butchered version is available here:

http://pastebin.com/f3655ef7f

Here it is, read my notes at the top for howto actually use it:


# Local filesystem mounting -*- shell-script -*-
#
################################################################
# File:
# /scripts/local
#
# Root, or / in these notes is the initrd's (busybox) root,
# not your system's root!
#
# You need the aufs module for this to work. To do this install
# aufs on your base install, add aufs to: /etc/initramfs-tools/modules
# Now using your target kernel run:
# mkinitramfs -o initrd.img
#
# make a directory, copy an initrd to it then cd to it and:
#
# mv initrd.img initrd.img.gz
# gunzip initrd.img.gz
#
# make sure aufs exists somewhere in /lib/modules//
# After modifying local script, etc do the following in the initrd's
# root folder where /bin and /lib etc is to create a new initrd:
#
# find ./ -print | cpio -H newc -o > ../newinitrd.img
#
# Now tell grub to use this initrd for a RO root filesystem
#
# Note fstab gets hosed, if you need an fstab, make sure this
# script reflects that. I use an fstab for the default initrd for RW
# and none for RO, but you can make this script use a different one for
# RO if you want.
################################################################
# Parameter: device node to check
# Echos fstype to stdout
# Return value: indicates if an fs could be recognized
get_fstype ()
{
local FS FSTYPE FSSIZE RET
FS="${1}"

# vol_id has a more complete list of file systems,
# but fstype is more robust
eval $(fstype "${FS}" 2> /dev/null)
if [ "$FSTYPE" = "unknown" ] && [ -x /lib/udev/vol_id ]; then
FSTYPE=$(/lib/udev/vol_id -t "${FS}" 2> /dev/null)
fi
RET=$?

if [ -z "${FSTYPE}" ]; then
FSTYPE="unknown"
fi

echo "${FSTYPE}"
return ${RET}
}

# Parameter: Where to mount the filesystem
mountroot ()
{
[ "$quiet" != "y" ] && log_begin_msg "Running /scripts/local-top"
run_scripts /scripts/local-top
[ "$quiet" != "y" ] && log_end_msg

wait_for_udev 10

# If the root device hasn't shown up yet, give it a little while
# to deal with removable devices
if [ ! -e "${ROOT}" ] || ! $(get_fstype "${ROOT}" >/dev/null); then
log_begin_msg "Waiting for root file system"

# Default delay is 180s
if [ -z "${ROOTDELAY}" ]; then
slumber=180
else
slumber=${ROOTDELAY}
fi
if [ -x /sbin/usplash_write ]; then
/sbin/usplash_write "TIMEOUT ${slumber}" || true
fi

slumber=$(( ${slumber} * 10 ))
while [ ! -e "${ROOT}" ] \
|| ! $(get_fstype "${ROOT}" >/dev/null); do
/bin/sleep 0.1
slumber=$(( ${slumber} - 1 ))
[ ${slumber} -gt 0 ] || break
done

if [ ${slumber} -gt 0 ]; then
log_end_msg 0
else
log_end_msg 1 || true
fi
if [ -x /sbin/usplash_write ]; then
/sbin/usplash_write "TIMEOUT 15" || true
fi
fi

# We've given up, but we'll let the user fix matters if they can
while [ ! -e "${ROOT}" ]; do
# give hint about renamed root
case "${ROOT}" in
/dev/hd*)
suffix="${ROOT#/dev/hd}"
major="${suffix%[[:digit:]]}"
major="${major%[[:digit:]]}"
if [ -d "/sys/block/sd${major}" ]; then
echo "WARNING bootdevice may be renamed. Try root=/dev/sd${suffix}"
fi
;;
/dev/sd*)
suffix="${ROOT#/dev/sd}"
major="${suffix%[[:digit:]]}"
major="${major%[[:digit:]]}"
if [ -d "/sys/block/hd${major}" ]; then
echo "WARNING bootdevice may be renamed. Try root=/dev/hd${suffix}"
fi
;;
esac
echo "Gave up waiting for root device. Common problems:"
echo " - Boot args (cat /proc/cmdline)"
echo " - Check rootdelay= (did the system wait long enough?)"
echo " - Check root= (did the system wait for the right device?)"
echo " - Missing modules (cat /proc/modules; ls /dev)"
panic "ALERT! ${ROOT} does not exist. Dropping to a shell!"
done

# Get the root filesystem type if not set
if [ -z "${ROOTFSTYPE}" ]; then
FSTYPE=$(get_fstype "${ROOT}")
else
FSTYPE=${ROOTFSTYPE}
fi

[ "$quiet" != "y" ] && log_begin_msg "Running /scripts/local-premount"
run_scripts /scripts/local-premount
[ "$quiet" != "y" ] && log_end_msg

if [ "${readonly}" = "y" ]; then
roflag=-r
else
roflag=-w
fi

# FIXME This has no error checking

modprobe ${FSTYPE}
##########################################################################
###### Mod'd by Brian Phelps aka Electronjunkie ##########################

mkdir /root/.tmpfs
mkdir /root/.rootfs

mount -r -t ext2 /dev/sda1 /root/.rootfs

modprobe aufs
modprobe loop
mount -t tmpfs -o size=20M tmpfs /root/.tmpfs

mount -t aufs -o br:/root/.tmpfs=rw:/root/.rootfs=ro none /root/
mv /root/etc/fstab /root/etc/fstab.defunct

#########################################################################

# FIXME This has no error checking
# Mount root

[ "$quiet" != "y" ] && log_begin_msg "Running /scripts/local-bottom"
run_scripts /scripts/local-bottom
[ "$quiet" != "y" ] && log_end_msg
}

Advertisements