OpenWrt Forum Archive

Topic: Openwrt 10.03 boot from USB stick (pivotroot) and config

The content of this topic has been archived on 25 Apr 2018. There are no obvious gaps in this topic, but there may still be some posts missing at the end.

Hi,
  This is my config for booting 10.03 on DIR-825 from an USB Stick.Why would I want that ? Cause you can install then anything you want not beeing limited anymore by the size of your router flash memory.

It should work with very minor changes.
My FLASH firmware is the jffs version. It contains added modules from repos after install for mas storage, ext3, usb, etc. (things you need to be able to manually moount your usb stick when booting from flash.

Now in order to switch root to usb flash (suppose you have your ext2/3 filesystem already prepared on partition 1 on usb stick:

Req modules:
kmod-fs-ext3
kmod-fs-mbcache
kmod-nls-base
kmod-scsi-core
kmod-usb-core
kmod-usb-storage
kmod-usb-uhci
kmod-usb2

After flashing (my case a jffs firmware) and adding the necessary packages and modules copy the entire flash disk on the partition sda1. If /rom does not exits on on the sda1 create it.

mount -t ext2 /dev/sda1 /mnt
mkdir /tmp/root
mount -o bind /rom /tmp/root
cp /tmp/root/* /mnt -a
umount /tmp/root
umount /mnt

After that change the following file exactly in these locations in the filesystem from the flash.

/etc/init.d/rcS:
-----------------
#!/bin/sh
# Copyright (C) 2006 OpenWrt.org

if [ "$2" = "boot" ]
then
  /root/bin/pivotroot 7
fi>/root/boot

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"

if [ "$1" = "S" ]; then
        run_scripts "$1" "$2" &
else
        run_scripts "$1" "$2"
fi
-----------------------------------------------------------------------------------------------------

Create the following files exactly in on the specified locations  (/root/bin) and make them executable
chmod u+x on each file

/root/bin/pivotroot:
----------------------
#!/bin/sh
boot_dev="/dev/sda1"
newroot="/mnt"
oldroot="/rom"
for module in nls_base usbcore ehci-hcd ohci-hcd uhci-hcd scsi_mod sd_mod usb-storage jbd mbcache ext3
do {
        insmod $module 2>/dev/null
}; done
lsmod

if  ! /root/bin/usbwait $1
then
   exit 1
fi

echo mounting $boot_dev ...
#mount "$boot_dev" $newroot
/root/bin/mount_try $boot_dev $newroot 3

# if everything looks ok, do the pivot root
if [ $? -eq 0 -a -x $newroot/sbin/init ]
then
   cd $newroot
   echo pivoting...
   mount -o move /proc $newroot/proc && {
     pivot_root $newroot $newroot/rom && {
        mount -o move $oldroot/dev /dev
        mount -o move $oldroot/tmp /tmp
        mount -o move $oldroot/sys /sys 2>&-
     }
   }
fi
---------------------------------------------------------------------------------------------------------------

/root/bin/usbwait:
--------------------
#!/bin/sh

TOUT=${1:-10}

count=0
while [ ! -d /sys/block/sda  -a $count -le $TOUT ]
do
    sleep 1s
    c=$((count++))
done
[ $count -le $TOUT ] && { echo OK - $count seconds; exit 0; }
echo NOK - $count seconds
exit 1
--------------------------------------------------------------------------------------------------------------------

/root/bin/mount_try:
----------------------
#!/bin/sh

[ $# -ge 2 ] || exit 1

TOUT=${3:-3}

count=0
while [ $count -le $TOUT ]
do
    mount $1 $2
    ecode=$?
    [ $ecode -eq 0 ] && break
    sleep 1s
    c=$((count++))
done
echo $0 seconds $count - code $ecode
exit $ecode
----------------------------------------------------------------------------------------------------

If everything was ok after boot you will have the flash ROM mounted in /rom and the new root on the /dev/sda1 !


The usbwait can be replaced with a simple sleep. I just not wanted to wait 15 seconds on each boot. I did an active wait for the disk device to appear.
This setup boots on the original firmware if not capable to boot on the USB stick. So with well configured network part you still have a working router with the same net config as the one on the usb stick - maybe with less services.

In my case I partitioned the stick (a 4GB stick) to 2 paritions:
/dev/sda1 - new root
/dev/sda2 - 3bG and something as ext3 or fat32 user files storage - I have a mini server with some storage capacity. This partition is then exported by samba to my local network as well.


Optional network printer:
For those having an USB printer (not networked) and you want to share it on your local net you can install:
luci-app-p910nd
p910nd
Add a usb hub (better powered) to the DIR-825 usb connector and connect the usb stick and printer to the hub
and share your printer in the local network. (multifunctions - generally-  the fax, scanner will not work).  Install your network drivers on your pc (each one) and point the printer port to the DIR-825 device.(Cool !)

Also a nice thing to have - A wifi scheduler and toggler +LED status (at this moment the ath9k radio leds are not working yet)
--------------------------------------------------------------

1) Scheduler: (automatically turn off  the wifi during the night)
------------
Edit /etc/crontabs/root and add:

*/10 00-04 * * *  /sbin/wifi down
0 09  * * *  /sbin/wifi up
---------------------------------------
This will turn off radios between 00:00 -04:00 in the morning very 10 minutes (in the case the router reboots somehow) and turns on the radio at 09:00AM. Change the hours according to your schedule. Enable the cron service in luci - services section.

2) A wifi toggler so that those that want to see the radio status and to manually turn on/off the radios during the day can do that using the powersave button:
Create  /etc/hotplug.d/button/01-button with the content:
---------------------------------------------------
#!/bin/sh


if [ "$BUTTON" = "BTN_1" -a "$ACTION" = "released"  ]
then
   exec /root/bin/wifi_toggle &
fi
-----------------------------------------------------------------


and /root/bin/wifi_toggle:
---------------------------------------------------
#!/bin/sh
PATH=/bin:/sbin:/usr/bin:/usr/sbin
LOCK=/tmp/wireless.lock

lock=`cat $LOCK`
[ "$lock" = "lock" ] && exit
echo lock>$LOCK

grep -q wlan0 /proc/net/dev
wifi_state=$?

# 1 wifi is down - 0 wifi is up

if [ $wifi_state -eq 1 ]
then
   wifi up
else
   wifi down
fi
echo >$LOCK
exit
---------------------------------------------------------------
Now at each POWERSAVE (the one on the side) button press-release you toggle the wifi state.
Wifi substitute LED. If you like you can add to the led config (in luci) the follwing:

Led Name: button-powersave
LED Device: dir825b1:blue:powersave
Default State: off (not ticked)
Trigger: Network Device
Device:wlan0
Trigger Mode: Link on (checked)

Voila - while waiting for the kernel guys on ath9k to fix the Radio leds I use the powersave button led to indicate if wifi is on or off.

Adrian

Hi!

This is much easier using block-extroot package.

vargalex

YEs might be, but you need to build it yourself ?

Adrian

asergiu wrote:

YEs might be, but you need to build it yourself ?

Adrian

Hi!

You have two choises:

1. Build it yourself a squashfs version with necessary packages
2. Install the jffs2 firmware version, then install the necessary packages, change the /etc/config/fstab, and done.

vargalex

The discussion might have continued from here.