Thursday, July 16, 2009

Build OpenWrt howto

* get code from svn repository
cd ~/openwrt/
svn co svn://svn.openwrt.org/openwrt/branches/8.09/ 8.09/
svn co svn://svn.openwrt.org/openwrt/packages 8.09/feeds/packages
cd 8.09/
./scripts/feeds update -a
* build
make package/symlinks
make menuconfig
make prereq
make world

Wednesday, July 15, 2009

[zz] USB Storage Howto

USB storage howto

Intro

It's useful to extend the storage capacity of your USB enabled Wrt router f. e. making a central file server. This can easily be done with connecting USB storage devices (like a USB stick or a external USB harddisc) to the USB port on your router.

Requirements

  • Supported router by OpenWrt with USB (f. e. the Asus WL-500G or the Asus WL-500G deluxe)

  • a recent OpenWrt version installed (at least White Russian RC3)

  • some kind of a USB storage device (a USB stick or a external USB harddisc) supported by Linux
  • a USB hub (optional) to add more USB ports (it's probably a good idea to use an active USB hub with it's own PSU)

NOTE: Devices supporting USB v2.0

Installation

TIP: Some routers are USB 1.1 and 2.0 compatible. To use both devices with both versions install the modules for USB 1.1 and 2.0.

Modules for USB 1.1

For USB 1.1, try installing the UHCI drivers first:

ipkg install kmod-usb-uhci
insmod usbcore
insmod uhci

If you see the message:

insmod: init_module: uhci: No such device

then your hardware does not have a UHCI compliant device, so you might as well remove the package:

ipkg remove kmod-usb-uhci

TIP: Most USB chips have UHCI controllers. If you received a "No such device" error, then try installing the kmod-usb-ohci package instead. The BCM4710 and BCM4712 based routers require kmod-usb-ohci:

ipkg install kmod-usb-ohci
insmod usb-ohci

If you see the message:

insmod: init_module: usb-ohci: No such device

then your hardware does not have a OHCI compliant device, so you might as well remove the package:

ipkg remove kmod-usb-ohci

Modules for USB 2.0

This package includes the modules for USB 2.0.

NOTE: USB 2.0 support in White Russian is broken. There are some threads in the forum and some tickets as well if you like to read about what happens. (Im using WR 0.9 on an ASUS WL-500g Premium and USB 2.0 works just fine)

ipkg install kmod-usb2
insmod ehci-hcd

If you see messages like this:

insmod: unresolved symbol usb_calc_bus_time

try loading usbcore and then try ehci-hcd again:

insmod usbcore
insmod ehci-hcd

Note that you may want to have available the utility, lsusb. To enable it in Kamikaze, run "opkg install usbutils".

Modules for storage

To add storage support finally install

ipkg install kmod-usb-storage
insmod scsi_mod
insmod sd_mod
insmod usb-storage

Clean up

TIP: The max_scsi_luns=8 bit is needed for multi-card readers and should be added to the end of the scsi_mod line in the /etc/modules.d/60-usb-storage file.

OpenWrt uses /etc/modules.d directory to load the modules automatically on the next reboot. So reboot the router with

reboot

Now check if OpenWrt sees your USB device (of course inserting it into your Wrt router). If it's correct you should see similar messages as on the dmesg dump below.

dmesg

usb.c: registered new driver usbdevfs
usb.c: registered new driver hub
uhci.c: USB Universal Host Controller Interface driver v1.1
PCI: Enabling device 01:02.0 (0000 -> 0001)
uhci.c: USB UHCI at I/O 0x100, IRQ 2
usb.c: new USB bus registered, assigned bus number 1
hub.c: USB hub found
hub.c: 2 ports detected
PCI: Enabling device 01:02.1 (0000 -> 0001)
uhci.c: USB UHCI at I/O 0x120, IRQ 2
usb.c: new USB bus registered, assigned bus number 2
hub.c: USB hub found
hub.c: 2 ports detected
hub.c: new USB device 01:02.0-2, assigned address 2
usb.c: USB device 2 (vend/prod 0xd7d/0x100) is not claimed by any active driver.
Initializing USB Mass Storage driver...
usb.c: registered new driver usb-storage
scsi0 : SCSI emulation for USB Mass Storage devices
Vendor: Apacer Model: Drive Rev: 1.05
Type: Direct-Access ANSI SCSI revision: 02
Attached scsi removable disk sda at scsi0, channel 0, id 0, lun 0
SCSI device sda: 256000 512-byte hdwr sectors (131 MB)
sda: Write Protect is off
Partition check:
/dev/scsi/host0/bus0/target0/lun0: p1
WARNING: USB Mass Storage data integrity not assured
USB Mass Storage device found at 2
USB Mass Storage support registered.

Configuration

Usage as a storage device to extend storage

First install the kernel file system modules, for example:

ipkg install kmod-vfat

Under Kamikaze 7.07 or later, use

ipkg install kmod-fs-vfat

TIP: After installing the modules, you should either reboot the device or load the installed modules manually:

insmod fat
insmod vfat

TIP: You can install support for more file systems by installing the appropriate packages.

File system

Package name

Comment

VFAT/MSDOS

kmod-vfat (kmod-fs-vfat)

File system generally used in USB devices and older Windows

EXT2

kmod-ext2 (kmod-fs-ext2)


EXT3

kmod-ext3 (kmod-fs-ext3)


Now install the fdisk package from the White Russian's backports repository. How to use the backports repository see OpenWrtDocs/Packages.

ipkg install fdisk

TIP: If you don't find fdisk in the rc6 backports repository, you can use the rc5 backports version:

ipkg install http://downloads.openwrt.org/backports/rc5/fdisk_2.12r-1_mipsel.ipk

Create the/mntdirectory for the mount point on the flash

mkdir /mnt

Check what partition you like to mount from your USB device

fdisk -l

Finally you can mount and use your USB device (with relevant modules for your file system in memory and created directory for mount):

mount /dev/scsi/host0/bus0/target0/lun0/part1 /mnt

Be happy and use your USB device like on every other GNU/Linux system or create a file server using Samba.

If you go with ext2 with journaling and install kmod-fs-ext2 , kmod-fs-ext3 and e2fsprogs you can use it like a normal unix type disk. Create the script /etc/init.d/usbdrive ( changing the mount point to match yours )

#!/bin/sh /etc/rc.common
START=99
STOP=40
start()
{
echo -n "Testing USB Partition: "
e2fsck -p /dev/scsi/host0/bus0/target0/lun0/part1 &
sleep 5
echo -n "Mounting USB drive: "
mount -t ext3 -o noatime /dev/scsi/host0/bus0/target0/lun0/part1 /usb
echo "Done."
}
stop()
{
echo -n "Umounting USB drive: "
sync
sync
umount /dev/scsi/host0/bus0/target0/lun0/part1
echo "Done."
}
restart()
{
stop
start
}

then do a ./usbdrive enable

You may need language packages to support the filenames on various file systems:

kmod-nls-base - Kernel modules for basic native language support

kmod-nls-cp437 - Kernel module for codepage 437

kmod-nls-cp850 - Kernel module for codepage 850

kmod-nls-iso8859-1 - Kernel module for iso8859-1 charset support

kmod-nls-iso8859-15 - Kernel module for iso8859-15 charset support

kmod-nls-utf8 - Kernel module for utf8 support

How do I boot from the USB device (prep)

For this to work you need the same kernel modules for USB as described above. You also need the modules for the EXT3 file system:

/!\ NOTE: IMPORTANT: There are reports that this procedure bricks routers running Kamikaze with 2.6 kernel - proceed at your own risk! (It works for some, not for others)

ipkg install kmod-ext2 kmod-ext3

After installing the modules, you should either reboot the device or load the installed modules manually:

insmod ext2
insmod jbd
insmod ext3

The next step is to partition the USB device and create an EXT3 FS partition. This requires fdisk (install it as described above). You can do the partioning in OpenWrt it self or on a normal PC.

In OpenWrt do

fdisk /dev/sda
-OR-
fdisk /dev/scsi/host0/bus0/target0/lun0/disc

On a GNU/Linux desktop PC do

fdisk /dev/sda

/!\ IMPORTANT: Make sure you are modifying the right device. If you have any other USB drives, or a SCSI or SATA drive, your USB device might be at /dev/sdb or /dev/sdc (and so on) instead! Also, you do not want to use a partition such as /dev/sda1 (note the number at the end); you do want the base device name.

For more information about using fdisk, see http://www.tldp.org/HOWTO/Partition/fdisk_partitioning.html.

Next, "format" the newly created partition.

In OpenWrt do

For doing this in OpenWrt you first have to install the e2fsprogs package from the White Russian's backports repository. How to use the backports repository see OpenWrtDocs/Packages.

ipkg install e2fsprogs

Then "format" your partition with

mke2fs -j /dev/scsi/host0/bus0/target0/lun0/part1

mke2fs may fail on large disks (e.g. 300GB) if there is not enough memory, consider adding a swap partition, even if it is only used during mke2fs.

If you keep getting errors like:

Creating journal (4096 blocks): mke2fs: No such file or directory
while trying to create journal

then run the following command:

ln -s /proc/mounts /etc/mtab

Now, we will copy everything from the flash to the USB device (make sure the EXT3 modules are loaded):

# mount it
mount -t ext3 /dev/scsi/host0/bus0/target0/lun0/part1 /mnt
# now, we need to mount the root contents somewhere so we can copy
# them without copying /mnt and /proc to the new usb device
mkdir /tmp/root
# if you're using squashfs, you want to copy the squashfs contents,
# not the jffs2 symlinks, so use the command:
mount -o bind /rom /tmp/root
# if you're using jffs2 then use the command /
mount -o bind / /tmp/root
# now /tmp/root contains the root filesystem with no extra directories mounted
# so we just copy this to the usb device
cp /tmp/root/* /mnt -a
# and now we unmount both the usb and our /tmp/root
umount /tmp/root
umount /mnt

/!\ Problems with booting from USB storage were reported with WhiteRussian RC4 or later, which is the version that introduced USB hotplug support. If you encounter problems as well, try disabling USB hotplug. (more info on this?)

As earlier stated on this page (to remove /etc/hotplug.d/usb/01-mount) is NOT a good idea, as this is where usbfs is mounted, so usb-storage might work fine but lsusb wohn't list your devices, and most software using USB won't be able to find devices since /proc/bus/usb will remain empty?

So either remove the file and mount usbfs somewhere else, or everything inside except the line which goes: [ -f /proc/bus/usb/devices ] || mount -t usbfs none /proc/bus/usb

Boot Configuration - (White Russian)

Next, remove /sbin/init from the JFFS2 partition (this is just a symlink to BusyBox anyway):

rm /sbin/init

And replace it with this script:

#!/bin/sh
# change this to your boot partition
boot_dev="/dev/scsi/host0/bus0/target0/lun0/part1"
# install needed modules for usb and the ext3 filesystem
# **NOTE** for usb2.0 replace "uhci" with "ehci-hcd"
# **NOTE** for ohci chipsets replace "uhci" with "usb-ohci"
for module in usbcore uhci scsi_mod sd_mod usb-storage jbd ext3; do {
insmod $module
}; done
# this may need to be higher if your disk is slow to initialize
sleep 4s
# mount the usb stick
mount "$boot_dev" /mnt
# if everything looks ok, do the pivot root
[ -x /mnt/sbin/init ] && {
mount -o move /proc /mnt/proc && \
pivot_root /mnt /mnt/mnt && {
mount -o move /mnt/dev /dev
mount -o move /mnt/tmp /tmp
mount -o move /mnt/jffs2 /jffs2 2>&-
mount -o move /mnt/sys /sys 2>&-
}
}
# finally, run the real init (from USB hopefully).
exec /bin/busybox init

Make sure your new /sbin/init is executable:

chmod a+x /sbin/init

Now just reboot, and if you did everything right it should boot from the USB device automatically.

If it could not boot from the USB device it will boot normally from the file system found on the flash as fallback.

Note that it is safest to leave the 'pivot_root' procedure as an ordinary script file, not part of the code automatically run on startup, at least until you are certain that it is operating as desired. This allows you to recover from any problems created by this script by simply rebooting the router without it.

Boot Configuration (Kamikaze)

First Create a script /etc/init.d/pivotroot

#!/bin/sh
# change this to your boot partition
boot_dev="/dev/sda1"
# install needed modules for usb and the ext3 filesystem
# **NOTE** for usb2.0 replace "uhci" with "ehci_hcd"
# **NOTE** for ohci chipsets replace "uhci" with "usb-ohci"
for module in usbcore uhci scsi_mod sd_mod usb-storage jbd kmod-fs-ext2 kmod-fs-ext3 ; do {
insmod $module
}; done
# this may need to be higher if your disk is slow to initialize
sleep 4s
# mount the usb stick
mount "$boot_dev" /mnt
# if everything looks ok, do the pivot root
[ -x /mnt/sbin/init ] && {
mount -o move /proc /mnt/proc && \
pivot_root /mnt /mnt/mnt && {
mount -o move /mnt/dev /dev
mount -o move /mnt/tmp /tmp
mount -o move /mnt/jffs2 /jffs2 2>&-
mount -o move /mnt/sys /sys 2>&-
}
}

Note: for Kamikaze 2.4 kernel that may not have hotplug2 then try using this instead. Tested with openwrt-brcm-2.4-squashfs.

#!/bin/sh
# change this to your boot partition
boot_dev="/dev/discs/disc0/part1"
# install needed modules for usb and the ext3 filesystem
# **NOTE** for usb2.0 replace "uhci" with "ehci-hcd"
# **NOTE** for ohci chipsets replace "uhci" with "usb-ohci"
for module in usbcore uhci scsi_mod sd_mod usb-storage jbd ext2 ext3 ; do {
insmod $module
}; done
# this may need to be higher if your disk is slow to initialize
sleep 4s
# mount the usb stick
mount "$boot_dev" /mnt
# if everything looks ok, do the pivot root
[ -x /mnt/sbin/init ] && {
mount -o move /proc /mnt/proc && \
pivot_root /mnt /mnt/mnt && {
mount -o move /mnt/dev /dev
mount -o move /mnt/tmp /tmp
mount -o move /mnt/jffs /jffs 2>&-
mount -o move /mnt/sys /sys 2>&-
}
}

Note: for Kazimate 2.6 kernel, add this before insmod loop.

/sbin/hotplug2 --override --persistent --max-children 1 --no-coldplug &

And kill it after the loop.

killall hotplug2

Make it executable:

chmod +x /etc/init.d/pivotroot

Then install the modules, for Kamikaze 7.07 or later (Kernel 2.6), use

ipkg install kmod-fs-ext2 kmod-fs-ext3

Test to see if pivotroot works:

/etc/init.d/pivotroot
df -h

You may safely ignore errors saying "insmod: cannot insert ..." If pivotroot worked, then df will show that your USB storage is mounted on "/" (root). Now reboot.

reboot

after that edit /etc/init.d/rcS

#!/bin/sh
# Copyright (C) 2006 OpenWrt.org
if test $2 == "boot" ; then
/etc/init.d/pivotroot
fi
{
for i in /etc/rc.d/$1*; do
$i $2 2>&1
done
} | logger -s -p 6 -t '' &

now your System should Startup nicely either from USB or from internal Flash if the USB-disk is not available.

Installing and using OPKG packages in mount point other than root

The Optware packages already make use of a similar concept, by which ipkg-opt uses a config file (/opt/etc/opkg.conf) that points / to /opt in order to force the packages to install there. The settings to control where new packages are installed are defined by single-line entries in /etc/ipkg.conf with the original default being 'root / '. If you have external flash or hard drive, you may want to install packages there and add the corresponding directories to $PATH in /etc/profile.

/!\ NOTE: This is not tested. Please report if it's working for you.

-Works for me (MikkoKorkalo)

-Works for me (ElbenfreunD)

/!\ NOTE: PackagesOnExternalMediaHowTo, OpenWrtDocs/KamikazeConfiguration/PackagesOnExternalMediaHowTo and OpenWrtDocs/KamikazeConfiguration/BootFromExternalMediaHowTo contain additional important infos.

/!\ NOTE: Destination needs not to have trailing slash in order to make following script work (Nijel).

/!\ NOTE: Following script has been adjusted to reflect kamikaze using opkg instead of opkg

Configure opkg for a non-root destination

echo dest usb /mnt/usb >> /etc/opkg.conf

then install a package to a non-root destination

opkg -dest usb install kismet-server

Copy & paste this script into /bin/opkg-link (or somewhere in your $PATH).

#!/bin/sh
COMMAND=$1
PACKAGE=$2
setdest () {
for i in `grep dest /etc/opkg.conf | cut -d ' ' -f 3`; do
if [ -f $i/usr/lib/opkg/info/$PACKAGE.list ]; then
DEST=$i
fi
done
if [ "x$DEST" = "x" ]; then
echo "Can not locate $PACKAGE."
echo "Check /etc/opkg.conf for correct dest listings";
echo "Check name of requested package: $PACKAGE"
exit 1
fi
}
addlinks () {
setdest;
cat $DEST/usr/lib/opkg/info/$PACKAGE.list | while read LINE; do
SRC=$LINE
DST=`echo $SRC | sed "s|$DEST||"`
DSTNAME=`basename $DST`
DSTDIR=`echo $DST | sed "s|$DSTNAME\$||"`
test -f "$SRC"
if [ $? = 0 ]; then
test -e "$DST"
if [ $? = 1 ]; then
mkdir -p $DSTDIR
ln -sf $SRC $DST
else
echo "Not linking $SRC to $DST"
echo "$DST Already exists"
fi
else
test -d "$SRC"
if [ $? = 0 ]; then
test -e $DST
if [ $? = 1 ]; then
mkdir -p $DST
else
echo "directory already exists"
fi
else
echo "Source directory $SRC does not exist"
fi
fi
done
}
removelinks () {
setdest;
cat $DEST/usr/lib/opkg/info/$PACKAGE.list | while read LINE; do
SRC=$LINE
DST=`echo $LINE | sed "s|$DEST||"`
DSTNAME=`basename $DST`
DSTDIR=`echo $DST | sed "s|$DSTNAME\$||"`
test -f $DST
if [ $? = 0 ]; then
rm -f $DST
test -d $DSTDIR && rmdir $DSTDIR 2>/dev/null
else
test -d $DST
if [ $? = 0 ]; then
rmdir $DST
else
echo "$DST does not exist"
fi
fi
done
}
mountdest () {
test -d $PACKAGE
if [ $? = 1 ]; then
echo "Mount point does not exist"
exit 1
fi
for i in $PACKAGE/usr/lib/opkg/info/*.list; do
$0 add `basename $i .list`
done
}
umountdest () {
test -d $PACKAGE
if [ $? = 1 ]; then
echo "Mount point does not exist"
exit 1
fi
for i in $PACKAGE/usr/lib/opkg/info/*.list; do
$0 remove `basename $i .list`
done
}
case "$COMMAND" in
add)
addlinks
;;
remove)
removelinks
;;
mount)
mountdest
;;
umount)
umountdest
;;
*)
echo "Usage: $0 "
echo " Commands: add, remove, mount, umount"
echo " Targets: , "
echo "Example: $0 add kismet-server"
echo "Example: $0 remove kismet-server"
echo "Example: $0 mount /mnt/usb"
echo "Example: $0 umount /mnt/usb"
exit 1
;;
esac
exit 0

Make sure the /bin/ipkg-link script is executable:

chmod a+x /bin/opkg-link

Examples howto use the script:

Link a single package to root:

opkg-link add kismet-server

Link all packages on a mount point to root:

opkg-link mount /mnt/usb

Remove symlinks:

opkg-link remove kismet-server

Remove all symlinks for all packages:

opkg-link umount /mnt/usb

[zz] USB on Kamikaze

USB on Kamikaze

From Crashcourse Wiki

Jump to: navigation, search

This page will shortly have information on how to configure USB on your WL500GP for things like USB drives and so on. Until then, here are a number of links into the OpenWrt wiki (and elsewhere) that should be helpful.

Contents

[hide]

USB Devices on the WL500g Premium

Installation, configuration and testing done using Kamikaze devlopment version (bleeding edge, r10760).

All USB devices require the installation of the kmod-usb-core kernel module. For development versions of the operating firmware, packages are most easily accessed by copying the ~/openwrt/bin/packages directory from the git build tree to a USB key and mounting it on the router. Initial configuration can also be achieved by moving required packages to the router with scp. From a directory containing the relevant packages, the ipkg command can be used in direct mode:

root@OpenWrt:# ipkg install kmod-usb-core*

Version 1.1 USB controllers are one of two varieties, UHCI or OHCI. Installing both modules covers all V1.1 devices:

ipkg install kmod-usb-uhci*
ipkg install kmod-usb-ohci*

Version 2.0 USB devices require the usb2 kernel module:

ipkg install kmod-usb2*

USB Storage on the WL500g Premium HOWTO

USB storage on the WL500gP in OpenWRT requires the usb-storage module. This module has a dependency of the scsi-core module which must be taken care of manually when using ipkg in direct mode:

ipkg install kmod-scsi-core*
ipkg install kmod-usb-storage*

Standard Linux filesystem capability (ext2/3):

ipkg install kmod-fs-ext2*
ipkg install kmod-fs-ext3*

Basic MS filesystem (msdos) and long filename capability (vfat) for default USB flash drive configurations:

ipkg install kmod-nls-base*
ipkg install kmod-fs-msdos*
ipkg install kmod-fs-vfat*

Further NLS modules may be required to mount filesystems containing filenames with non-English characters:

kmod-nls-cp1250 (Central and Eastern European MS Windows)

kmod-nls-cp437 (Extended ASCII DOS)

kmod-nls-cp850 (Western European DOS)

kmod-nls-iso8859-1 (Latin #1 ISO)

kmod-nls-iso8859-15 (Latin #9 ISO - includes Euro symbol)

kmod-nls-iso8859-2 (Latin #2 ISO)

kmod-nls-koi8r (Russian)

kmod-nls-utf8 (Unicode standard character set)

File Transfer Performance from USB Storage

So what is the transfer capability of a WL500gP router acting as a fileserver?

ftp network connection:

 USB2 drive->(hub*)->WL500gP->100mbit network->laptop
*Same stats with/out the hub


laptop command line:

ftp> get ThomasVHS.mpg
local: ThomasVHS.mpg remote: ThomasVHS.mpg
200 PORT command successful. Consider using PASV.
150 Opening BINARY mode data connection for ThomasVHS.mpg (3026878464 bytes).
226 File send OK.
3026878464 bytes received in 1218.19 secs (2426.5 kB/s)


top on router during the transfer:

Mem: 28824K used, 1104K free, 0K shrd, 228K buff, 21188K cached
CPU: 0% usr 32% sys 0% nice 0% idle 0% io 3% irq 63% softirq
PID PPID USER STAT VSZ %MEM %CPU COMMAND
4772 1 root R 2076 7% 95% vsftpd
3592 2 root RW< 0 0% 3% [usb-storage]

The router is waiting on the disk I/O (softirq and sys CPU usage) and is transferring as efficiently as possible.


The router can move files off an attached USB2 hard drive at 2.37 MiB/s. The same drive directly connected to the laptop shows a 20.6MiB/s transfer rate. Clearly the router is not saturating the 100Mb/s ethernet link (>10Mib/s) nor the USB port bandwidth. The transfer rate is bound by the router hardware, most notably the CPU. Note that reported transfer speeds for the stock firmware are around 1.8MiB/s, so the Kamikaze (bleeding edge, r10760) firmware shows a distinct performance improvement.

USB Audio on the WL500g Premium HOWTO

ipkg install kmod-sound-core*
ipkg install kmod-usb-audio*
ipkg install alsa-lib*
ipkg install libncurses*
ipkg install libpthread*
ipkg install alsa-utils*
reboot


There are several options for USB soundcards. The Creative Audigy 2 NX USB sound card was used in this example.

By default, ALSA mutes sound devices. Use alsamixer to unmute and adjust volume of the sound card.


Madplayer can be used as a command-line client for playback of audio from local or web-based sources. Installation has several dependencies:

ipkg install zlib*
ipkg install libid3tag*
ipkg install libmad*
ipkg install madplay*

Testing:

# wget -O - http://www.mobiuseng.com/Kermit/Songs/Rainbow.mp3 | madplay -

Serving USB Printers on the WL500g Premium HOWTO

Printer sharing with OpenWRT is covered in: [[1]]. It uses the lightweight p910nd pass-through print server.

For the WL500g Premium, printer sharing requires the following packages to be installed:

ipkg install kmod-usb-printer*
ipkg install p910nd*

The configuration file for the print server is found in at /etc/config/p910nd. An example which works for a pair of Lexmark laser printers at ports 9100 and 9101 is:

config p910nd
option device "/dev/lp0"
option port 0
option bidirectional 1

config p910nd
option device "/dev/lp1"
option port 1
option bidirectional 1

Configuration of clients is straightforward:

From ubuntu, printer configuration uses a device URI of:

socket://192.168.254.111:9100

for a WL500gP at 192.168.254.111. Be sure to make a rule for forwarding port 9100 for print connections to the router from the WAN side.

Tips openWRT

* setting openWRT to client mode
things might get missed during the procedure
- change /etc/resolv.conf
nameserver InternetGatewayIP
#nameserver 127.0.0.1 #default version
- missing wl520gu IP with DHCP enabled
after issuing /etc/init.d/network restart, Asus wl520gu IP changes, go to gateway router to see active connections and figure out new IP of wl520gu
* opkg package manager
- update /etc/opkg.conf to reflect package location
- opkg update
- use -force-downgrade when package is older than kernel

[zz] OpenWRT MP3 player with keyboard and display

OpenWRT Enable an usbkeyboard for OpenWRT


Insert those modules:

insmod /lib/modules/2.4.30/input.o
insmod /lib/modules/2.4.30/evdev.o
insmod /lib/modules/2.4.30/hid.o

Download HERE

To compile those modules yourself, you need to enable the following kernel option:

Input core support  --->
Input core support
< > Keyboard support
< > Mouse support
< > Joystick support
Event interface support
< > User level driver support

USB support  --->
--- USB Human Interface Devices (HID)
USB Human Interface Device (full HID) support
[*] HID input layer support
[*] /dev/hiddev raw HID device support

Info: I couldn't use the keyboard module (keybdev.o), when i inserted this module he complained about undefined references:

 unresolved symbol handle_scancode
unresolved symbol keyboard_tasklet
unresolved symbol kbd_ledfunc

I guess this is because the keyboard.o module doesn't exist.
Now create a new modules.d config file, /etc/modules.d/61-usb-hid with this content:
input
evdev
hid
Insert the modules manually or reboot your OpenWrt box.

Syslog when you connect the usb keyboard:
Jan 1 00:01:45 OpenFoensi kern.info kernel: hid-core.c: v1.8.1 Andreas Gal, Vojtech Pavlik
Jan 1 00:01:45 OpenFoensi kern.info kernel: hid-core.c: USB HID support drivers
Jan 1 00:01:51 OpenFoensi kern.info kernel: hub.c: new USB device 01:03.0-2.3, assigned address 8
Jan 1 00:01:51 OpenFoensi kern.info kernel: input: USB HID v1.11 Keyboard [04d9:1203] on usb2:8.0
Jan 1 00:01:51 OpenFoensi kern.info kernel: input: USB HID v1.11 Device [04d9:1203] on usb2:8.1
Now there should be 2 input devices:
/dev/input/event0 /dev/input/event1

Now we need to handle these keyboard events, its time for cmdpad (http://cmdpad.sourceforge.net/). this app will listen to a /dev/input/eventX device (i our case a USB keyboard) and execute a program for each key pressed/released/keep pressing.
there seems to be a similar tool called mpc keyboard daemon, http://simon.arlott.org/sw/mpckbd/, but i didn't test it.

I compiled cmdpad for OpenWRT, but I didn't manage to create an ipkg package. You can get my poor ipkg attempt here or download just the binaries here.

install cmdpad to /usr/bin/
install cmdpad.conf to /etc/
install S70USBKbd to /etc/init.d/

the startscript looks like this:

/etc/init.d/S70USBKbd
#!/bin/sh
/usr/bin/cmdpad --quiet


SOUND


Install modules, source: http://sokrates.mimuw.edu.pl/%7Esebek/openwrt/ (http://sokrates.mimuw.edu.pl/%7Esebek/openwrt/packages/), extract them to /lib/modules/2.4.30/

Create /etc/modules.d/72-snd-usb-audio:
 soundcore
snd-page-alloc
snd
snd-rawmidi
snd-hwdep
snd-timer
snd-pcm
snd-mixer-oss
snd-pcm-oss
snd-usb-lib
snd-usb-audio

install alsa-lib ipkg
install alsa-utils ipkg
install mpd / mpc ipkg

Configure mpd:
I mount a usb stick to /mnt/stick1, where the _mp3 subdirectory contains all my mp3's.

My mpd configuration, /etc/mpd.conf:

##################### REQUIRED ###########################
music_directory "/mnt/stick1/_mp3/"
playlist_directory "/mnt/stick1/_mp3/playlist"
db_file "/mnt/stick1/_mp3/.mpd/mpd.db"
log_file "/mnt/stick1/_mp3/.mpd/mpd.log"
error_file "/mnt/stick1/_mp3/.mpd/mpd.error"
pid_file "/mnt/stick1/_mp3/.mpd/mpd.pid"
##########################################################

#audio device
audio_output {
type "oss"
name "my OSS sound card"
device "/dev/dsp" # optional
format "44100:16:2" #optional
}

# OSS Mixer
mixer_type "oss"
mixer_device "/dev/mixer"
mixer_control "PCM"

state_file "/mnt/stick1/_mp3/.mpd/mpdstate"

buffer_before_play "0%"


Don't forget to create those directories:
mkdir /mnt/stick1/_mp3/.mpd
mkdir /mnt/stick1/_mp3/playlist

Start mpd, this will create the db and searches for all mp3 files.

Now add all mp3 files to mpc:
# mpc listall | mpc add -

WARNING for asus wl500 users, DO NOT INSTALL the package "kmod-usb-ohci" or your usb subsystem will get messy, for example my usb 2.0 stick didn't work anymore, error: usb.c: USB device not responding, giving up (error=-145)


DISPLAY


First I wanted to use a "regular" LCD display, but compared to a palm device on ebay, they are way too expensive. I bought some palm devices on ebay and the best device I think is the palm 3c. Nice color display and a rechargeable battery. I modded a palm 3x device, so I don't need batteries anymore but take the power from the usb port. This has a big drawback, when the device loose power, all installed applications are gone. You could copy some apps to the internal ROM but there is just 50k free space.

PalmORB (http://palmorb.sourceforge.net/) is your friend, this application emulates an Matrix Orbital LK204-25 LCD. My palm use a serial connector, so I need an usb/serial convertor. I had trouble with an FTDI adapter, now I use an PL2303 adapter. It looks like you only can go up to 9600bps, else the connection gets fluffy, but this should be enough for our display.

On the Openwrt you need to install LCD4Linux, I've patched the mpc plugin, check this article for a how-to.


CONCLUSION

There is still much to do here's a small list...

Current Issues:
- My cheap USB sound card seems to buffer the sound, when i want to pause a song, the device keeps playing for about 4 seconds.
- I need to write some scripts for mount / dismount the USB stick, rescan the music source.
- Currently I'm working on a gps plugin for LCD4Linux.
- ...

Feel free to support me, contact me at michu at neophob dot com.

[zz] Building OpenWrt Kamikaze from source

Assuming you are using Ubuntu 6.06.1 LTS (on a physical system or in the VMware Player)


1. install packages required by the OpenWrt Kamikaze buildsystem

aptitude install build-essential binutils flex bison autoconf gettext texinfo sharutils subversion libncurses5-dev ncurses-term zlib1g-dev

2. checkout and prepare Kamikaze and the packages

Code:

cd ~
svn co https://svn.openwrt.org/openwrt/trunk/
svn co https://svn.openwrt.org/openwrt/packages/ ~/trunk/feeds/packages/
cd ~/trunk/
make package/symlinks

2.1 Configure Kamikaze (select target system) and the packages (a full build with all packages selected requires about 9GB of free disk space)

make menuconfig

2.2 If you select extra packages it's a good idea to check if you have all prerequisites installed. Check with:

make prereq

TIP: To find the missing packages search at http://packages.ubuntu.com/

2.3 Finally build Kamikaze (to download all packages at once use 'make download world')

make world

3. After the build finished, ready to use images can be found in $(TOPDIR)/bin


Targets for 'make'

download
download all source tarballs (from the selected packages and it's dependencies) at once before starting the build

prereq
checks if you have all prerequisites installed on the host-system for building the selected packages

world
build everything

tools/install toolchain/install
only build the tools and the toolchain

clean
cleans the packages (NOT the tools and toolchain)

distclean
cleans up everything expect $(TOPDIR)/.config and $(TOPDIR)/dl/

package/-{clean,compile}
rebuild a single package

package/index
updates $(TOPDIR)/bin/packages/Packages

V=99
turns on debugging

make kernel_menuconfig
If you want, you can also modify the kernel config for the selected target system. Simply run "make kernel_menuconfig"
and the build system will unpack the kernel sources (if necessary), run menuconfig inside of the kernel tree, and then
copy the kernel config to target/linux//config so that it is preserved over "make clean" call.


Also look at the OpenWrt Kamikaze documentation at
- http://nbd.name/openwrt.html#x1-250002.1 or
- http://nbd.name/openwrt.pdf

Some more useful URLs:
- Free VMware Player (enough for most users, no need for the VMware Server)
- Download VMDK and VMX files for VMware Player
- Ubuntu (for the Ubuntu ISO image)
- Free VMware Server (also includes the VMware Tools)

Last edited by forum2006 (2007-05-06 18:24:28)

[zz] The OpenWrt build environment

The OpenWrt build environment

One of the biggest challenges to getting started with embedded devices is that you just can't install a copy of Linux and expect to be able to compile a firmware. Even if you did remember to install a compiler and every development tool offered, you still wouldn't have the basic set of tools needed to produce a firmware image. The embedded device represents an entirely new hardware platform, which is incompatible with the hardware on your development machine, so in a process called cross compiling you need to produce a new compiler capable of generating code for your embedded platform, and then use it to compile a basic Linux distribution to run on your device.

The process of creating a cross compiler can be tricky, it's not something that's regularly attempted and so the there's a certain amount of mystery and black magic associated with it. In many cases when you're dealing with embedded devices you'll be provided with a binary copy of a compiler and basic libraries rather than instructions for creating your own -- it's a time saving step but at the same time often means you'll be using a rather dated set. Likewise, it's also common to be provided with a patched copy of the Linux kernel from the board or chip vendor, but this is also dated and it can be difficult to spot exactly what has been changed to make the kernel run on the embedded platform.

OpenWrt takes a different approach to building a firmware, downloading, patching and compiling everything from scratch, including the cross compiler. Or to put it in simpler terms, OpenWrt doesn't contain any executables or even sources, it's an automated system for downloading the sources, patching them to work with the given platform and compiling them correctly for the platform. What this means is that just by changing the template, you can change any step in the process.

As an example, if a new kernel is released, a simple change to one of the Makefiles will download the latest kernel, patch it to run on the embedded platform and produce a new firmware image -- there's no work to be done trying to track down an unmodified copy of the existing kernel to see what changes had been made, the patches are already provided and the process ends up almost completely transparent. This doesn't just apply to the kernel, but to anything included with OpenWrt -- It's this one simple understated concept which is what allows OpenWrt to stay on the bleeding edge with the latest compilers, latest kernels and latest applications.

So let's take a look at OpenWrt and see how this all works

download openwrt

This article refers to the "Kamikaze" branch of OpenWrt, which can be downloaded via subversion using the following command:

svn co https://svn.openwrt.org/openwrt/trunk

Additionally, there's a trac interface on http://dev.openwrt.org/ which can be used to monitor svn commits and browse the sources.

The directory structure

There are three key directories in the base:
- toolchain
- target
- package

Toolchain refers to the compiler, the c library, and common tools which will be used to build the firmware image. The result of this is two new directories, toolchain_build_ which is a temporary directory used for building the toolchain for a specific architecture, and staging_dir_ where the resulting toolchain is installed. You won't need to do anything with the toolchain directory unless you intend to add a new version of one of the components above.

Target refers to the embedded platform, this contains items which are specific to a specific embedded platform. Of particular interest here is the "target/linux" directory which is broken down by platform and contains the kernel config and patches to the kernel for a particular platform. There's also the "target/image" directory which describes how to package a firmware for a specific platform.

Package is for exactly that -- packages. In an OpenWrt firmware, almost everything is an ipk, a software package which can be added to the firmware to provide new features or removed to save space.

Both the target and package steps will use the directory "build_" as a temporary directory for compiling. Additionally, anything downloaded by the toolchain, target or package steps will be placed in the "dl" directory.

Building openwrt

While the OpenWrt build environment was intended mostly for developers, it also has to be simple enough that an inexperienced end user can easily build his or her own customized firmware.

Running the command "make menuconfig" will bring up OpenWrt's configuration menu screen, through this menu you can select which platform you're targeting, which versions of the toolchain you want to use to build and what packages you want to install into the firmware image. Similar to the linux kernel config,
almost every option has three choices, y/m/n which are represented as follows:

<*> (pressing y) This will be included in the firmware image
(pressing m) This will be compiled but not included (for later install)
(pressing n) This will not be compiled

After you've finished with the menu configuration, exit and when prompted, save your configuration changes. To begin compiling the firmware, type "make". By default OpenWrt will only display a high level overview of the compile process and not each individual command.

Code:

  make[2] toolchain/install
make[3] -C toolchain install
make[2] target/compile
make[3] -C target compile
make[4] -C target/utils prepare
...

This makes it easier to monitor which step it's actually compiling and reduces the amount of noise caused by the compile output. To see the full output, run the command "make V=99".

During the build process, buildroot will download all sources to the "dl" directory and will start patching and compiling them in the "build_" directory. When finished, the resulting firmware will be in the "bin" directory and packages will be in the "bin/packages" directory.

Creating your own packages

One of the things that we've attempted to do with OpenWrt's template system is make it incredibly easy to port software to OpenWrt. If you look at a typical package directory in OpenWrt you'll find two things:

- package//Makefile
- package//patches

The patches directory is optional and typically contains bug fixes or optimizations to reduce the size of the executable. The package makefile is the important item, provides the steps actually needed to download and compile the package.

Looking at one of the package makefiles, you'd hardly recognize it as a makefile. Through what can only be described as blatant disregard and abuse of the traditional make format, the makefile has been transformed into an object oriented template which simplifies the entire ordeal.

Here for example, is package/bridge/Makefile:

Code:

include $(TOPDIR)/rules.mk

PKG_NAME:=bridge
PKG_VERSION:=1.0.6
PKG_RELEASE:=1

PKG_BUILD_DIR:=$(BUILD_DIR)/bridge-utils-$(PKG_VERSION)
PKG_SOURCE:=bridge-utils-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=@SF/bridge
PKG_MD5SUM:=9b7dc52656f5cbec846a7ba3299f73bd
PKG_CAT:=zcat

include $(INCLUDE_DIR)/package.mk

define Package/bridge
SECTION:=base
CATEGORY:=Network
DEFAULT:=y
TITLE:=Ethernet bridging configuration utility
DESCRIPTION:=Ethernet bridging configuration utility\\\
Manage ethernet bridging; a way to connect networks together to\\\
form a larger network.
URL:=http://bridge.sourceforge.net/
endef

define Build/Configure
$(call Build/Configure/Default,--with-linux-headers=$(LINUX_DIR))
endef

define Package/bridge/install
install -m0755 -d $(1)/usr/sbin
install -m0755 $(PKG_BUILD_DIR)/brctl/brctl $(1)/usr/sbin/
endef

$(eval $(call BuildPackage,bridge))

As you can see, there's not much work to be done; everything is hidden in other makefiles and abstracted to the point where you only need to specify a few variables.

PKG_NAME - The name of the package, as seen via menuconfig and ipkg
PKG_VERSION - The upstream version number that we're downloading
PKG_RELEASE - The version of this package Makefile
PKG_BUILD_DIR - Where to compile the package
PKG_SOURCE - The filename of the original sources
PKG_SOURCE_URL - Where to download the sources from
PKG_MD5SUM - A checksum to validate the download
PKG_CAT - How to decompress the sources (zcat, bzcat, unzip)


The PKG_* variables define where to download the package from; @SF is a special keyword for downloading packages from sourceforge. The md5sum is used to verify the package was downloaded correctly and PKG_BUILD_DIR defines where to find the package after the sources are uncompressed into $(BUILD_DIR).

At the bottom of the file is where the real magic happens, "BuildPackage" is a macro setup by the earlier include statements. BuildPackage only takes one argument directly -- the name of the package to be built, in this case "bridge". All other information is taken from the define blocks. This is a way of providing a level of verbosity, it's inherently clear what the DESCRIPTION variable in Package/bridge is, which wouldn't be the case if we passed this information directly as the Nth argument to BuildPackage.

BuildPackage uses the following defines:

Package/
matches the argument passed to buildroot, this describes the package
the menuconfig and ipkg entries. Within Package/ you can define the
following variables:

SECTION - The type of package (currently unused)
CATEGORY - Which menu it appears in menuconfig
TITLE - A short description of the package
DESCRIPTION - A long description of the package
URL - Where to find the original software
MAINTAINER - (optional) Who to contact concerning the package
DEPENDS - (optional) Which packages must be built/installed before this package

Package//conffiles (optional)
A list of config files installed by this package, one file per line.

Build/Prepare (optional)
A set of commands to unpack and patch the sources. You may safely leave this
undefined.

Build/Configure (optional)
You can leave this undefined if the source doesn't use configure or has a
normal config script, otherwise you can put your own commands here or use
"$(call Build/Configure/Default,)" as above to pass in additional
arguments for a standard configure script.

Build/Compile (optional)
How to compile the source; in most cases you should leave this undefined.

Package//install
A set of commands to copy files out of the compiled source and into the ipkg
which is represented by the $(1) directory.

The reason that some of the defines are prefixed by "Package/" and others are simply "Build" is because of the possibility of generating multiple packages from a single source. OpenWrt works under the assumption of one source per package makefile, but you can split that source into as many packages as
desired. Since you only need to compile the sources once, there's one global set of "Build" defines, but you can add as many "Package/" defines as you want by adding extra calls to BuildPackage -- see the dropbear package for an example.

After you've created your package//Makefile, the new package will automatically show in the menu the next time you run "make menuconfig" and if selected will be built automatically the next time "make" is run.

Troubleshooting

If you find your package doesn't show up in menuconfig, try the following command to see if you get the correct description:

TOPDIR=$PWD make -C package/ DUMP=1 V=99

If you're just having trouble getting your package to compile, there's a few shortcuts you can take. Instead of waiting for make to get to your package, you can run one of the following:

make package/-clean V=99
make package/-install V=99

Another nice trick is that if the source directory under build_ is newer than the package directory, it won't clobber it by unpacking the sources again. If you were working on a patch you could simply edit the sources under build_/ and run the install command above, when satisfied, copy the patched sources elsewhere and diff them with the unpatched sources. A warning though - if you go modify anything under package/ it will remove the old sources and unpack a fresh copy.

Final notes

I'm always interested to hear about people's experience with OpenWrt or answer questions about it so please don't hesitate to contact me.