Booting from the CF card via initramfs
Finally got booting from the CF card via the initramfs method to largely work. It seems the wireless networking autoconfig decides to eject your CF card if it doesn't successfully detect and bring up the wlan0 interface. Not very nice when you're in the middle of trying to boot from it. Special thanks to Terry Kemp and Steve Sakoman for all their help in troubleshooting. Other things I observed when following Terry's instructions he linked to previously:
1. Your custom kernel can be bigger than 1MB and still work.
2. You need to partition the CF card similar to how Terry outlined. vfat for boot partition and ext3 for rootfs are confirmed to work
3. Mixing custom kernels with rootfs modules compiled with the vanilla kernel config can possibly be problematic so you may want to build your kernel and rootfs with an identical kernel defconfig
4. After the CF card is detected, it takes a few seconds to register as the /dev/hda1 and /dev/hda2 devices. That's where the 4 second sleep in the init file came from. If you don't wait long enough, the /dev/hda2 to /rfs mount fails.
5. alsa mixer is segfaulting - no idea
6. Occasionally the boot locks up at:
i2c: msg_num: 1 msg_idx: 0 msg_ptr: 0
i2c: ICR: 000007e9 ISR: 00000004
i2c: log:
I2C: i2c-1: PXA I2C adapter
i2c /dev entries driver
Working on troubleshooting the remaining issues. If anyone else would like to give this a whirl, here is the init file I'm working from:
#!/bin/sh
# initramfs /init
die()
{
echo ""
echo "/init failed: $*"
echo ""
echo "ERROR! Dropping to a shell so you can figure it out"
exec /bin/sh
exit 0
}
find_module()
{
find /lib/modules -name "$1" | grep "$1" > /dev/null 2>&1
return $?
}
load_module()
{
if find_module "$1.ko" ; then
echo -n " [*] loading $1 module..."
modprobe $1 || die "failed to load $1"
echo "done"
fi
}
echo "/init script running..."
if [ ! -d /dev/pts ] ; then
mkdir /dev/pts || die "failed to mkdir /dev/pts"
fi
if [ ! -d /dev/shm ] ; then
mkdir /dev/shm || die "failed to mkdir /dev/shm"
fi
mount /dev/pts || die "failed to mount /dev/pts"
echo "done"
echo -n " [*] mounting /proc..."
mount -t proc proc /proc || die "failed to mount /proc"
echo "done"
echo -n " [*] mounting /sys..."
mount -t sysfs sysfs /sys || die "failed to mount /sys"
echo "done"
echo -n " [*] starting udevd..."
/sbin/udevd &
udevd_pid=$!
echo "done"
load_module pcmcia
load_module pxa2xx_cs
load_module ide-cs
load_module ide-disk
# Wait for device to be detected... (max 30 secs)
echo "[*] Checking to see if CF Card is registered..."
i=1
sleep 4
while ! [ -f /proc/ide/ide0/hda/media ] ; do
/sbin/udevtrigger || die "udevtrigger failed"
sleep 2
echo "Waiting for CF Card to Register. $i/15"
if [ "$i" = "15" ] ; then
die "too long waiting on CF card to register"
fi
i=`expr $i + 1`
done
echo "[*] CF Card Registered"
#echo -n " [*] running e2fsck on /dev/hda2..."
#/sbin/e2fsck -y /dev/hda2
#echo "done"
echo -n " [*] mounting /dev/hda2 to /rfs..."
mount -t ext3 -o rw /dev/hda2 /rfs || die "failed to mount rootfs on second CF partition"
echo "done"
echo -n " [*] Cleaning up..."
# Clean up
kill $udevd_pid
umount -l /proc
umount -l /sys
umount -l /dev/pts
echo "done"
# Switch Root
echo " [*] Switching to real root fs..."
exec switch_root /rfs /sbin/init
#shouldn't get here!
die "switch_root must have failed"