I do understand there are ways to make a device to boot off of a USB2 memory stick. However, since OpenWRT SVN trunk has gone under a lot of changes, some of the existing approaches may no longer work due to recent changes on mount_root. So, I decided to post my configurations (based on approach by dhkauffman as shown on his blog). To do this, I have modified several files that I provided below.
Below is my /etc/config/fstab, /etc/init.d/rcS scripts file, my modified /etc/init.de2fsck scripts file (from e2fsck package), and the modified /etc/init.d/pivotroot scripts file derived from dhkauffman's blog. My modification implements switch statements and makes use of /dev/sd*. It is by no means complete and may contain bugs; however, it works just fine on my WGT634U device without any problem, yet. So, please use it at your own discretions and please do let's know how it goes. I have all these files included under my openwrt-svn-trunk/files/etc/init.d directory so that they will be incorporated into the firmware during the build process.
For my WGT634U device, I compile the OpenWRT to include cfdisk and swap-utils packages (both under Utilities -> disc sub menu) into the firmware mainly because they are indispensable utilities for me to create needed partitions. To make my WGT634U device to boot off a USB2 external partition, I have used an old Patriot 512MB USB2 memory stick to achieve the task. It comes with two physical partitions, i.e. sda (~480MB) and sdb (~25MB). So, the swap partition is on /dev/sdb1. Before I can use this USB memory stick, it needs to be partitioned and formatted. I used cfdisk /dev/sda to create a primary partition (/dev/sda1) with Type 83 and cfdisk /dev/sdb to create a swap partition (/dev/sdb1) with Type 82. Then, I used mkfs.ext3 -L "WGT634U/OpenWRT" /dev/sda1 to format the /dev/sda1 as ext3 partition with "WGT634U/OpenWRT" as its label and mkswap -L "Swap" /dev/sdb1 to create a swap partition on /dev/sdb1 with "Swap" as its label. If you decide to use a swap partition and it is on /dev/sda2, please make the necessary changes to replace /dev/sdb1 with /dev/sda2 on all occasions, this includes the contents on /etc/config/fstab file, too.
After I have flashed the firmware to my WGT634U device, I do the following (at first boot) to make my device to boot with the new firmware:
1. Insert a USB2 memory stick to the USB2 port on the device. Assuming the USB2 memory stick already has been properly partitioned as above.
2. If the device is mounted after the USB2 memory stick is inserted and it contains some (important) data, additional and/or necessary precaution steps must be taken to insure the data has been backed up before reformatting the partition (requires to unmount the partition).
3. Once the partition is formatted, temporarily mount it, i.e. mount /dev/sda1 /usb/sda1, on any mount point of your choice. Then, copy the root contents of /tmp/root directory to the /dev/sda1 partition, i.e. cp -a /tmp/root/* /usb/sda1. NOTE: /tmp/root partition is ONLY available at the 1st boot (after the device is flashed with a new firmware, AFAIK). Be sure to create a /usb/sda1 under /usb/sda1, i.e. mkdir -p /usb/sda1/usb/sda1. On my OpenWRT SVN trunk, I have cireated the files/usb/sda1 directory so that it will be included into a newly built firmware.
4. Once the root contents have been copied to /dev/sda1 partition, do a unmount /usb/sda1 before executing a reboot. This is not necessary, but just as a precaution step to ensure the partition is cleanly unmounted before the reboot.
5. Now, you can execute reboot to shutdown and boot your device through its USB2 external partition.
6. After your device has finished booting and is ready, you can telnet into your device to check the /tmp/pivoroot.log file to see any problems.
/etc/config/fstab
cconfig mount
option target /usb/sda1
option device /dev/sda1
option fstype ext3
option options rw,sync
option enabled 1
config swap
option device /dev/sdb1
option enabled 1
/etc/init.d/rcS
#!/bin/sh
# Copyright (C) 2006 OpenWrt.org
run_scripts() {
for i in /etc/rc.d/$1*; do
[ -x $i ] && $i $2 2>&1
done | $LOGGER
}
LOGGER="cat"
[ -x /usr/bin/logger ] && LOGGER="logger -s -p 6 -t sysinit"
#
# Improved from http://oldwiki.openwrt.org/UsbStorageHowto.html
# Switch the root filesystem to USB, if present
# DHK 7/14/09
#
#
# Modified by Mazilo 02/06/2010
#
if [ "$2" == "boot" -a -x /etc/init.d/pivotroot ] ; then
echo "[`date`]: Pivot root log created." > /tmp/pivotroot.log
/etc/init.d/pivotroot >> /tmp/pivotroot.log
fi
if [ "$1" == "S" ]; then
run_scripts "$1" "$2" &
else
run_scripts "$1" "$2"
fi
/etc/init.d/e2fsck
#!/bin/sh /etc/rc.common
# Copyright (C) 2008 OpenWrt.org
# Vasilis Tsiligiannis <acinonyxs@yahoo.gr>
START=15
e2fsck() {
local args
local cfg="$1"
config_get device "$cfg" device
[ -b "$device" ] || return 0
config_get fstype "$cfg" fstype
case "$fstype" in
ext2|ext3|ext4)
#
# Look for a mounted (USB) partition and dismount it
#
if grep -q $device /proc/mounts; then
echo "$device is mounted. No checking perfomed"
else
echo "Checking $device partition"
/usr/sbin/e2fsck -y "$device"
local status="$?"
case "$status" in
0|1) continue;;
2) reboot;;
4) echo "e2fsck ($device): Uncorrected errors.";;
*) echo "e2fsck ($device): Error ($status). Check not complete.";;
esac
fi;;
*) echo "$fstype filesystem type on $device isn't supported"
;;
esac
}
start() {
config_load fstab
config_foreach e2fsck mount
}
/etc/init.d/pivotroot
#!/bin/sh
# From http://oldwiki.openwrt.org/UsbStorageHowto.html - DHK 7/14/09
#
# Greatly enhanced to select among (maybe) several USB Mass Storage devices
# Assumes that the root fs will be on an ext3 filesystem in partition 1,
# and looks for /flash and /jffs in the root directory. Also assumes that
# mounting and checking each candidate device is harmless. Runs e2fsck
# over partitions before mounting them; note that this causes spurious
# date-related complaints every time, since time has not been synchronized
# yet at the time pivotroot is run.
#
# Output from this script is stashed at /tmp/pivotroot.log.
#
# DHK 7/23/2009
#
#
# Modified to use switch statements by Mazilo 02/06/2010
#
echo "[`date`]: Pivot root in action"
#
# Flag is true
#
flag=1
#
# Partitions mount point
#
mp=/usb
pm=/proc/mounts
#
# Looking for available partitions on the system
#
parts=`ls /dev/sd[a-z][0-9]`
if [ -z "$parts" ]; then
echo "[`date`]: No partitions found. Skipping pivotroot"
else
#
# Set Power LED flashing while we look for OpenWRT root
#
if [ -f /etc/diag.sh ]; then
LED=1
. /etc/diag.sh
POW=`cat /proc/diag/led/power`
set_led power f
fi
for part in $parts
do
#
# Look for a mounted (USB) partition and dismount it
#
# CAUTION: Make sure your system has 'file' package
# installed or else the following won't be able to check
# the filesystem type on your USB partition and your
# USB partition won't get mounted.
#
fstype=`file -s $part | awk '{ print $5 }'`
if grep -q $part $pm; then
echo "[`date`]: Umount $part ($fstype filesystem)"
umount $part
fi
#
# Look for a partition type of a USB memory stick
#
disc=`echo $part|sed -e 's#[[:digit:]]##g'`
partid=`fdisk -l $disc|awk -vP=$part '$1==P {if ( $2 == "*" ) {print $6} else {print $5}}'`
#
# Check/auto clean the (USB) partition
#
case "$partid" in
83) echo "[`date`]: pivotroot checking $part"
e2fsck -y $part
flag=1;
status=$?;;
*) echo "[`date`]: Filesystem on $part isn't supported"
flag=0;
status=99;;
esac
echo "[`date`]: e2fsck status is $status"
case "$status" in
0|1) echo "[`date`]: No filesystem errors and/or corrections on $part"
md=$mp/`basename $part`
[ -d $md ] || (echo "[`date`]: Creating $md directory";mkdir -p $md)
mount -t $fstype $part $md
local status=$?
mtype=`awk -vP="$part" '$1==P {split($4,A,","); print A[1]}' $pm`
echo "[`date`]: Mounting $part on $md as $mtype filesystem"
#
# Create local $md$md directory if doesn't exist
#
[ -d $md$md ] || mkdir -p $md$md
case "$status" in
0) if [ -x $md/sbin/init -a -d $md/jffs -a -d $md$md ]
then
echo "[`date`]: Found OpenWRT root on $part"
flag=1;
break;
else
echo "[`date`]: Non-OpenWRT partition ($status)"
[ -x $md/sbin/init ] || echo "[`date`]: Failed -x $md/sbin/init"
[ -d $md/jffs ] || echo "[`date`]: Failed -x $md/jffs"
[ -d $md$md ] || echo "[`date`]: Failed -x $md$md"
echo "[`date`]: Dismount $part partition"
umount $part;
flag=0;
fi;;
*) echo "[`date`]: Mount status is $status"
continue;;
esac
continue;;
2) echo "[`date`]: Filesystem errors corrected on $part. System reboots"
reboot;;
4) echo "[`date`]: e2fsck $part [E($status)]: Warning! Filesystem errors left ncorrected"
flag=0;
continue;;
8) echo "[`date`]: e2fsck $part [E($status)]. Operational error"
flag=0;
continue;;
16) echo "[`date`]: e2fsck $part [E($status)]. Usage/syntax error"
flag=0;
continue;;
32) echo "[`date`]: e2fsck $part [E($status)]. Operation cancelled"
flag=0;
continue;;
99) echo "[`date`]: e2fsck $part [E($status)]. Un-supported partition type"
flag=0;
continue;;
128) echo "[`date`]: e2fsck $part [E($status)]. Shared library error"
flag=0;
continue;;
*) echo "[`date`]: e2fsck $part [E($status)]. Check not complete"
flag=0;
continue;;
esac
done
#
# if everything looks ok, do the pivot root
#
if [ -x $md/sbin/init -a $flag = 1 ]; then
echo "[`date`]: Mount (move) /proc -> $md/proc"
mount -o move /proc $md/proc
echo "[`date`]: Pivot root $md -> $md$md"
pivot_root $md $md$md && for ff in dev tmp jffs rom sys
do
echo "[`date`]: Mount (move) $md/$ff -> /$ff"
mount -o move $md/$ff /$ff
done
fi
#
# Restore Power LED to previous state
#
[ $LED -eq 1 ] && set_led power $POW
fi
EDIT: Since I posted the above pivotroot scripts, a lot of readers here have found some bugs, i.e. truncations 1/2 by dhkauffman/denken, logical error in if statement by kunfoo, etc., and made some contributions/suggestions, i.e. checking partition type using awk by Tommie, local /usb/<part>/usb/<part> creation + correctly locating partition type field for both bootable and/or non-bootable partition by mactalla, etc., to improve the scripts. Thanks.
(Last edited by mazilo on 14 Mar 2010, 02:46)