onsdag 28 september 2011

Linksys WRT54GL with SD-card

Denna guide skrev jag hösten 2010 och nyligen ville David att jag skulle slänga upp den här, det lät som en bra ide så här är den:

A guide of how to add a SD-card to your WRT54GL router and use it as root filesystem.

Add the card

I use a A-Data 2GB sd-card (cost me 59 sek 2010-10-21) and it works good, write speed about 600kb/s.
This is how the card should be wired:
WRT54GL SD map source: (404'ed last i checked: 2011-09-28)
I wont go into details about the soldering, for info about that i recommend to search around in forums and wikies in the WRT-community, if someone want to add that part to this guide your very welcome!


I use openwrt kamikaze 8.09.2 brcm-2.4 (linux 2.4 kernel becaus of better performance with mmc sd-card driver) to flash with tftp or webui to flash with mtd command-line tool
more info can be found here:

When thats done, connect to the router using the webinterface and set a new root password.
Then connect with ssh and type:
opkg update
opkg install kmod-broadcom-mmc kmod-fs-ext2 e2fsprogs fdisk
That will install the SD-card driver mmc, support for ext2 filesystem, programs to create ext2 filesystem and fdisk to manage partitions.
Next take a look with dmesg, you will probably get "error -1' and so on, then you need an other mmc driver.
I use 1.3.4 gpio2
source to info about the driver:
I got the driver source code here: mmc_1.3.4_src.tar.gz and a the compiled one here: mmc.o.tar.gz if the site goes down
rmmod mmc
wget -P /lib/modules/
echo 0x9c > /proc/diag/gpiomask
insmod mmc
and then check with dmesg, if should be something like:
[INFO] mmc_card_init: card inited successfully in 21 tries (647733 CPU cycles).
[INFO] mmc_init: MMC/SD Card ID:
03 53 44 53 44 30 32 47 80 03 fa 94 b9 00 a2 ad [INFO] Manufacturer ID   : 03
[INFO] OEM/Application ID: SD
[INFO] Product name      : SD02G
[INFO] Product revision  : 8.0
[INFO] Product SN        : 03fa94b9
[INFO] Product Date      : 2010-2
[INFO] mmc_card_config: size = 1931264, hardsectsize = 1024, sectors = 1931264
[WARN] mmc_init: hd_sizes=1931264, hd[0].nr_sects=3862528
[INFO] mmc_card_init: set_blocklen (CMD16) succeeded !
Partition check:
mmca: p1
If it's somehing like "mmc_init got error calling mmc_card_init" then it probably short circuit or bad contact with the SD-card

Use the card as root filesystem

I have tested a lot of guides and failed on them till i found this old wiki: (does not exist last i checked: 2011-09-28)
But i needed to do some changes and ugly hack to make it work
First, if you haven't created a ext2-partition on your SD-card you should now, I don't recommend doing it on the router, I failed when doing it but I think it was because i forgot to write 0x9c to /proc/diag/gpiomask
Use fdisk to create a partition if you don't got one already, then create the filesystem, this is how to do it:
fdisk /dev/mmc/disc0/disc
mkfs.ext2 /dev/mmc/disc0/part1
mount /dev/mmc/disc0/part1 /mnt # mounting it to check if it works
Recursive copy the root to the SD-card:
mkdir /tmp/orig mount -o bind / /tmp/orig   # this is necessary to prevent duplicating /proc /dev and so forth
tar -c -C /tmp/orig -f - . | tar -xv -C /mnt -f -
umount /tmp/orig
rmdir /tmp/orig
rm -r /mnt/etc/*   # we don't need a duplicate /etc tree
umount /mnt
and here the /etc/init.d/bootext script, copy and paste or wget it ./bootext
#!/bin/sh /etc/rc.common


echo 0x9c > /proc/diag/gpiomask
insmod mmc

bootext_cleanup() { # [cleanup_level]
[ "$1" -ge 3 ] && grep -q '^[^ ]* /rom ' /proc/mounts && mount -o move /rom $putold/rom
[ "$1" -ge 2 ] && { . $putold/bin/firstboot ; pivot $putold $target ; }
[ "$1" -ge 1 ] && umount -l $target/etc
return 0

bootext_fail() { #  [cleanup_level]
echo "$1" >&2
[ ! "$2" ] || bootext_cleanup $2
exit 1

bootext_quit() { # 

echo "$1" >&2
exit 0

bootext_start() {
! grep -q "^$device / " /proc/mounts || bootext_quit "$name already on /"

if ! grep -q "^$device $target " /proc/mounts
 ! grep -q "^$device " /proc/mounts || bootext_fail "$name already mounted"

 for module in $modules
  if ! grep -q "^$module " /proc/modules
   [ $module != mmc ] || [ ! "$gpiomask" ] || echo "$gpiomask" > /proc/diag/gpiomask || bootext_fail "could not set gpiomask"
   insmod $module || bootext_fail "could not insert $module module"

 while [ ! -b $device ]
  [ "$waitdev" -gt 0 ] || bootext_fail "$device does not exist"
  waitdev=$(( $waitdev - 1 ))
  sleep 1

 [ -d $target ] || mkdir $target || bootext_fail "could not create mountpoint $target"
 mount ${filesys:+-t $filesys} ${mountopt:+-o $mountopt} $device $target || bootext_fail "could not mount $name on $target"

[ -d $target$putold ] || mkdir $target$putold || bootext_fail "could not create mountpoint $putold"
[ -d $target/etc ] || mkdir $target/etc || bootext_fail "could not create mountpoint /etc"
mount -o bind /etc $target/etc || bootext_fail "could not bind mount /etc"

. /bin/firstboot
pivot $target $putold || bootext_fail "could not pivot to $target" 1

! grep -q "^[^ ]* $putold/rom " /proc/mounts || { [ -d /rom ] || mkdir /rom && mount -o move $putold/rom /rom ; }

return 0

bootext_stop() {
grep -q "^$device / " /proc/mounts || bootext_quit "$name not on /"

bootext_cleanup 999

bootext_config() { # 
local section=$1 local action=$2 local enabled device name target putold modules gpiomask waitdev filesys mountopt config_get_bool enabled $section enabled 1 [ "$enabled" -gt 0 ] || return 0 config_get device $section device [ "$device" ] || bootext_fail "external boot device not configured" config_get name $section name config_get target $section target config_get putold $section putold config_get modules $section modules config_get gpiomask $section gpiomask config_get waitdev $section waitdev config_get filesys $section filesys config_get mountopt $section mountopt [ "$name" ] || name="$device" [ "$putold" ] || putold="${target:-/old}" [ "$target" ] || target="/${filesys:-new}" bootext_$action } start() { config_load bootfromexternalmedia config_foreach bootext_config bootfromexternalmedia start } stop() { config_load bootfromexternalmedia config_foreach bootext_config bootfromexternalmedia stop }
The only difference is that i added: echo 0x9c > /proc/diag/gpiomask insmod mmc and dont forget to chmod a+x /etc/init.d/bootext

and the /etc/config/bootfromexternalmedia ./bootfromexternalmedia
config bootfromexternalmedia
       option enabled  '1'
       option device   '/dev/mmc/disc0/part1'
       option name     'mmc'
       option target   '/mnt'
       option putold   '/mnt'
       option modules  'mmc ext2'
       option gpiomask '0x9c'
       option waitdev  '0'
       option filesys  'ext2'
       option mountopt 'noatime'
Don't need jbd (its the module for journaling) as in the original
/etc/init.d/bootext stop    # should report that device is not on /
/etc/init.d/bootext start   # should perform the switch without producing any output

df -h          # chould get somehting like:
Filesystem                Size      Used Available Use% Mounted on
rootfs                    1.8G     29.8M      1.7G   2% /
/dev/root                 1.6M      1.6M         0 100% /rom
tmpfs                     7.0M    732.0k      6.3M  10% /tmp
/dev/mtdblock/4           1.7M    420.0k      1.3M  24% /jffs
mini_fo:/jffs             1.6M      1.6M         0 100% /mnt
/dev/mmc/disc0/part1      1.8G     29.8M      1.7G   2% /
mini_fo:/jffs             1.6M      1.6M         0 100% /etc
Enable it at boot:
/etc/init.d/bootext enable

To be able to use the space on the SD-card for applications, comment out this line:
option overlay_root /jffs
in /etc/opkg.conf


To be able to use php i followed this guide:
in short:
opkg update
opkg install lighttpd lighttpd-mod-simple-vhost lighttpd-mod-status lighttpd-mod-cgi
mkdir /www0

# in /etc/lighttpd.conf:
# ----------------

simple-vhost.server-root = "/www0/"
simple-vhost.default-host = ""
simple-vhost.document-root = "/"

cgi.assign = ( ".php" => "/usr/bin/php" )

server.indexfiles = ( "index.html", "index.htm", "index.php")

#### status module
status.status-url = "/status"
status.config-url = "/config"
# ----------------
# "Status" gives you the pages you can see in http://your_router_ip/status and http://your_router_ip/config once we get as far as to get the server stated.

opkg install php4 php4-cgi php4-mod-gd

# change a few things in /etc/php.ini:
# ------------------
doc_root = /www0
extension_dir = "/usr/lib/php"
# ------------------

#try it out:

echo "" > /opt/www/phpinfo.php
/etc/init.d/lighttpd start
Update time:
echo "CET-1CEST,M3.5.0,M10.5.0/3" > /etc/TZ #-1 is Europe/Stockholm
opkg install ntpclient
ntpclient -h -s
Now you got a webserver that runs on 14W, at least mine does :)

All sources:
Much info about wrt54g/gl/gs:
Pictues and info about SD-card mod: (404'ed last i checked: 2011-09-28)
Forum thread about SD-card driver:
Howto root in external drive: (does not exist last i checked: 2011-09-28)
Use php on Openwrt:

Created: 2011-01-05
Updated: 2011-09-28 (changed links and stuff)
Feel free to use, distribute and modify this documentation /DomeDan

Inga kommentarer:

Skicka en kommentar