Asterisk on an Atcom IP01
Introduction
Oct 2012: I would recommend a SheevaPlug/RaspberryPi + Obi110 instead of 
the Atcom IP01 for the following reasons:
    - Due to its lack of an MMU, the Atcom requires a specific Linux distro 
    (uClinux)
- There's only one project still supported (Switchfin), and even then, 
    only by a couple of programmers. So if there's a bug, you're basically on 
    your own (and the Blackfin uClinux forum won't help much since they only 
    provide the CPU)
- Switchfin/AstFin don't provide a packaging system, so you must recompile 
    a whole new image to add/remove applications
- Applications must be recompiled, and possibly rewritten to run on uClinux
- The appliance only provides 64MB of RAM, and even less if RAM is used 
    to host the root filesystem instead of reading it off the NAND memory
- Asterisk is the only IP PBX available, and only in old releases (1.4 
    or 1.6)
- Zaptel isn't as good a solution as a dedicate appliance to connect to 
    the PSTN
This article contains information on how to work with the Atcom 
IP01 Asterisk appliance based on a project by David 
Rowe. The unit I ordered came with a single FXO module so as to connect it to 
an analog phone line, and used David's modular BAPS packaging system (ŕ la OpenWrt) 
which is different 
from the Astfin/Switchfin solution that includes everything into a single binary 
image.
As of June 2009, this device uses the BlackfinOne 
BF532 board using a Blackfin ADSP-BF532 
CPU, 64MB RAM+ 256MB NAND flash RAM + 2MB SPI Flash, and runs uCLinux 
(short for "Micro Controller Linux") instead of the standard Linux 
because the Blackfin has no Memory Management Unit 
(MMU). You can learn more about what the lack of MMU means and the differences 
between run-of-the-mill Linux and uClinux in the following articles: Differences 
between µClinux and Linux, Blackfin, 
uClinux for Linux Programmers, 
and Why is Malloc 
Different Under uClinux?.
When an application running under uClinux crashes, it might leave RAM in 
a poor state and it is recommended to reboot the appliance.
As the Blackfin boot ROM can't read the Linux kernel directly off the NAND, 
the Atcom uses a 256KB SPI flash chip (Serial Peripheral Interface) to hold the Uboot bootloader, which is 
able to read the NAND to copy the Linux kernel to RAM. When using "root=/dev/mtdblock0", 
this is a RAM-based root filesystem, while "root=/dev/mtdblock2" is 
the second partition in the NAND.
Note that the label of /dev/mtd0 is "ROMfs", but it's actually 
a device in RAM that uses the romfs 
filesystem as the initial ram disk, ie. this tiny RAM-based filesystem is 
concatenated 
to the kernel, so that you can safely erase and rewrite the NAND with a 
real, full filesystem.
FYI, "µClinux a.k.a. uClinux-dist, is a Linux distribution 
like any other Linux distribution, built from the Linux kernel from kernel.org 
and assorted other packages, and software from the GNU project. Since µClinux 
is optimised for size, it uses more compact alternatives (busybox, uclibc, 
etc) than a non-embedded distribution."
Since Blackfin uClinux-dist 
is meant to be used with any Blackfin-based appliance, uClinux-dist-based alternatives 
AstFin and Switchfin had to include telephony applications such as Asterisk + Zaptel/Dahdi.
"Buildroot is a set of Makefiles 
and patches that allows you to easily generate a cross-compilation toolchain, 
a root filesystem and a Linux kernel image for your target. Buildroot can be 
used for one, two or all of these options, independently.
Buildroot is useful 
mainly for people working with embedded systems. Embedded systems often use 
processors that are not the regular x86 processors everyone is used to having 
in his PC. They can be PowerPC processors, MIPS processors, ARM processors, 
etc.
A compilation toolchain is the set of tools that allows you to compile 
code for your system. It consists of a compiler (in our case, gcc), binary utils 
like assembler and linker (in our case, binutils) and a C standard library (for 
example GNU Libc, uClibc or dietlibc)."
Note that if you use the Atcom exclusively 
with digital devices and make sure all SIP devices use the same codec (ie. with 
no need to perform translation), the 
Blackfin is a questionable choice since its being a DSP offers no added-value compared 
to more standard CPUs with an MMU, which have the advantage of requiring less or no application 
rewrites. In this case, consider other compact, embedded devices like Alix 
boards, the SheevaPlug, Buffalo (eg. WZR-HP-G300NH) 
or Linksys (eg. WRT54GS) 
routers, the Seagate 
FreeAgent Dockstar NAS, or even some thin clients like HP's 55xx series.
Note that Freeswitch, the alternative to Asterisk, doesn't 
(yet?) support Blackfin processors, although someone was able to compile and 
run FS on a Planex router 
and the uClinux-based OpenWrt firmware.
Finally, when it comes to getting help, you should know that...
    - Atcom doesn't provide a forum where you could ask questions, and as 
    of January 2011, its wiki is gone
- The two 
    forums for the BAPS software has very little traffic; The Freetel 
    mailing list is a bit more responsive but not by much
- the AstFin and the Switchfin 
    forums are a bit more active, but not by much either
- The Blackfin 
    uClinux-dist forum doesn't know anything about the Atcom appliance, 
    since this product simply happens to use a Blackfin CPU but has otherwise 
    no connection with Blackfin, and the Atcom appliance is not part of the 
    official uClinux-dist software
- Applications that are part of uClinux-dist don't all work. You'll have 
    to include and test them to check
- Therefore, since the Atcom uses Uboot, uClinux-dist, the uClibc library, 
    and (for the BAPS software) the (now obsolete and replaced by opkg) 
    ipkg packaging tool, you 
    should also try to ask in sites dealing with those applications, such as 
    the OpenWrt community
MTD
Note: The MTD utilities can be installed on the workstation with "# apt-get install mtd-utils".
NAND
www.linux-mtd.infradead.org
"The memory is arranged as an array of pages. A page consists of 256 
/ 512 Byte data and 8 / 16 Byte spare (out of band) area. Newer chips have 2048 
Bytes data and and 64 Bytes spare area sizes. The spare area is used to store 
ECC (error correction code), bad block information and filesystem-dependent 
data. n pages build one block. The read / write access to data is on a per page 
basis. Erase is done on a per block basis. The commands to read / write / erase 
the chip is given by writing to the chip with the Command Latch Enable pin high. 
Address is given by writing with the Address Latch Enable pin high.
[...] UBI stores 2 small 64-byte headers at the beginning of each non-bad 
physical eraseblock:
    - erase counter header (or EC header) which contains the erase counter 
    of the physical eraseblock (PEB) plus some other not so important information;
- volume identifier header (or VID header) which stores volume ID and 
    logical eraseblock (LEB) number this PEB belongs to (plus some other not 
    so important information).
This is why logical eraseblocks are smaller than physical eraseblock - the 
headers take some flash space.
[...] Flash reads and writes may only be done in portions of minimum input/output 
unit size, which depends on flash type: NAND flashes usually have 512, 2048 
or 4096 byte min. I/O. unit size, which corresponds to NAND page size. NAND 
flashes store per-NAND page ECC codes in the OOB area, which means that whole 
NAND page has to be written at once to calculate the ECC code, and whole NAND 
page has to be read at once to check the ECC code.
[...] When working with UBI, it is important to realize that UBI stores erase 
counters on the flash media. Namely, each physical eraseblock has so-called 
erase counter header which stores the amount of times this physical eraseblock 
has been erased (see here). And of course, it is important not to lose the erase 
counters, which means that the tools you use to erase the flash and to write 
UBI images have to be UBI-aware. The mtd-utils repository contains the ubiformat 
utility which takes things right, instead of using flash_erase, dd, or nandwrite.
[...] UBIFS works on top of UBI volumes and cannot operate on top of MTD 
devices
Avoid formating an empty flash before running UBI on top of it, as you lose 
erase counters (wearing information) every time you erase the flash. Try to 
use UBI-aware utilities and flashing programs, eg. ubiformat /dev/mtd0
The ubinize utility uses a configuration file that describres all UBI volume(s) 
which the image has to contain".
Find NAND hardware information
Before flashing the NAND with a root filesystem, you'll need the following 
informations that are provided by the mtdinfo utility:
    - Physical erase block (PEB) (cat /proc/mtd)
- Minimum I/O unit size
- Sub-page size
From those, you can compute the Logical 
erase block (LEB) used by Ubi(fs).
Resources
Ubi(fs)
Ubi works with raw devices such as NAND, ie. those that don't have firmware 
to provide block-based access through FTL. UBI maps logical eraseblocks to physical 
eraseblocks, and provides wear-leveling and transparent I/O errors handling.
A UBI volume is a set of consecutive logical eraseblocks (LEBs). Each logical 
eraseblock may be mapped to any physical eraseblock (PEB). UBI volume size is 
specified when the volume is created and may later be changed.
UBI volumes can be static or dynamic, ie. they may be created, removed or 
re-sized dynamically, while MTD partitions are static.
Important UBI applications:
    - mtdinfo - reports information about MTD devices found in the system.
- ubinfo - provides information about UBI devices and volumes found in 
    the system
- ubiattach/ubidetach- attaches/detaches MTD devices (which describe raw 
    flash) to UBI and creates corresponding UBI devices
- ubimkvol/ubirmvol - creates/removes UBI volumes on UBI devices
- ubiupdatevol - updates UBI volumes; this tool uses the UBI volume update 
    feature which leaves the volume in "corrupted" state if the update 
    was interrupted; additionally, this tool may be used to wipe out UBI volumes
- ubinize - generates UBI images
- ubiformat - formats empty flash, erases flash and preserves erase counters, 
    flashes UBI images to MTD devices
Adding Ubi to menuconfig
Memory Technology Device (MTD) support > UBI - Unsorted block images > 
<*> Enable UBI
Add support for Ubifs filesystem.
Device nodes
For Ubi(fs), it is recommended to run "mdev" and let it create 
device nodes dynamically instead of listing device nodes statically in device_table.txt.
    - make config_menuconfig
 
 Miscellaneous Configuration > Device 
    Nodes (Dynamic)
 
 BusyBox > Linux System Utilities
 [*] mdev
 [*]   Support /etc/mdev.conf
 [ 
    ]     Support subdirs/symlinks (NEW)
 [ ]     Support 
    command execution at device addition/removal (NEW)
 [ ]   Support 
    loading of firmwares (NEW)
- vi /usr/src/uClinux-dist-2010R1-RC5/vendors/Rowetel/IP04/mdev
 
 #!/bin/sh
 # 
    Start up file for mdev
 
 case $1 in
 start) 
    echo "Starting mdev...";
 echo 
    /sbin/mdev > /proc/sys/kernel/hotplug;
 /sbin/mdev 
    -s;
 ;;
 
 stop) 
    killall -9 mdev;;
 enable) 
    rm -f /etc/rc.d/S20mdev;
 ln 
    -s /etc/init.d/mdev /etc/rc.d/S20mdev;;
 disable) 
    rm -f /etc/rc.d/S20mdev;;
 
 *) 
    cat <<EOF;;
 
 Syntax: /etc/init.d/mdev [command]
 Available 
    commands:
 start   Start 
    the service
 stop    Stop 
    the service
 enable  Enable 
    service autostart
 disable 
    Disable service autostart
 EOF
 esac
- vi /usr/src/uClinux-dist-2010R1-RC5/vendors/Rowetel/IP04/Makefile
 
 #Added
 $(ROMFSINST) 
    /etc/init.d/mdev
 $(ROMFSINST) -s /etc/init.d/mdev /etc/rc.d/S20mdev
Alternatively, here's how to create nodes manually:
    - mknod /dev/ubi_ctrl c 10 63
    - mknod /dev/ubi0 c 253 0
Upgrading just the kernel
Couldn't figure out how to get a running kernel without 
attached ext2 root filesystem.
First, boot up and run mtdinfo -a to check the size of the mtd1 partition
    - ip04> set autostart
- ip04> tftp 0x1000000 uImage
 
 Note the size of the image in 
    hexa, eg. "Bytes transferred = 3670016 (380000 hex)"
 
- ip04> nand erase clean 0x0 <size of mtd1>
- ip04> nand erase 0x0 <size of mtd1>
- ip04> nand write 0x1000000 0x0 0x380000
Important: "nand" expects numbers to be in hexa.
Creating Ubifs root filesystem
On the workstation
Compile uClinux mtdinfo
On the Atcom
    - Download and run mtdinfo /dev/mtd2 -u
- Write down "Default UBI LEB size" (UBIFS_LEB_SIZE) + "Amount 
    of eraseblocks" (UBIFS_MAX_LEB_CNT) + "Minimum I/O unit size" 
    (UBIFS_MIN_IO_SIZE), where the total size of the partition is Eraseblock 
    size * Amount of eraseblocks
On the workstation
    - vi vendors/AnalogDevices/vendor.mak
 
 UBIFS_MIN_IO_SIZE ?= 2048
 UBIFS_LEB_SIZE 
       ?= 129024
 UBIFS_MAX_LEB_CNT ?= 1984
 
- vi ubi.cfg
 
 [ubifs]
 mode=ubi
 image=./images/rootfs.ubifs
 vol_id=0
 vol_size=230MiB
 vol_type=dynamic
 vol_name=rootfs
 vol_flags=autoresize
 
- ubinize -o rootfs.ubi.img -m 2048 -p 128KiB -s 512 ./ubi.cfg
- mv rootfs.ubi.img /var/www
On the Atcom
    - Boot with a RAM-based root filesystem
- wget -c http://192.168.0.3/rootfs.ubi.img
- ubiformat /dev/mtd2 -s 512 -f rootfs.ubi.img
- ubiattach /dev/ubi_ctrl -m 2
- mount -t ubifs ubi0:rootfs /mnt
 
 Note: "rootfs" is set 
    in ubi.cfg
If mounted OK:
    - umount /mnt
- ubidetach /dev/ubi_ctrl -m 2
- reboot
- uboot> set bootargs ubi.mtd=2 
    root=ubi0:rootfs rw rootfstype=ubifs
Mounting a Ubifs partition
    - First, attach the MTD partition to Ubi: ubiattach /dev/ubi_ctrl -m 2 (2 = mtdblock2)
- To create /dev/ubi0: mdev -s
- Check Ubi infos: ubinfo /dev/ubi0 -a
- NOT NEEDED AFTER FIRST TIME? ubimkvol /dev/ubi0 -m -N ubifs0
- mount -t ubifs ubi0:rootfs /mnt
- umount /mnt
- ubidetach /dev/ubi_ctrl -m 2
- reboot
Do not worry about "UBIFS: recovery needed" after rebooting: /bin/reboot 
takes care of calling sync() before rebooting, so the Ubifs partition should 
be left in a stable state.
If you'd rather that uClinux unmount the Ubifs partition before rebooting, 
replace the default simpleinit with Busybox's init and include the "poweroff, 
halt, and reboot" option, More information here.
Resources
Updating to a new firmware
Tips for newbies
    - On the workstation where you'll build new images, use a standard Linux distro, and not too recent, so as to increases 
    chances of having the expected version of dependencies. Ubuntu seems like 
    the most common distro
- On Ubuntu, install a TFTP server thusly: apt-get update ; apt-get install 
    tftpd-hpa ; vi /etc/default/tftpd-hpa: RUN_DAEMON="yes"; 
    service tftpd-hpa start; Copy bootable image in /var/lib/tftpboot/
- uClinux provides "make single" to force GCC to only use one 
    core on CPU: Makes for easier debugging
- If requested for investigation, you can create a small bugreport by 
    running "make bugreport" in uClinux-dist. The tarball contains 
    information about the toolchain and configuration files
- Astfin/Switchfin require compiling Asterisk to get a web GUI to the 
    Atcom, even if it's just to update the firmware. Compiling Lighttpd isn't 
    enough (or even needed: The web GUI might use another web server).
- Tips on debugging 
    applications. Also use the "LD_DEBUG" environment variable 
    to investigate library issues
- Read how 
    to build applications/libraries either in FLAT or FDPIC ELF formats
- "the -l option is a linker option, and thus needs to be placed 
    AFTER the name of the file to be compiled. This is quite different from 
    the normal option syntax. If you place the -l option before the filename, 
    it may fail to link at all, and you can end up with mysterious errors." 
    (source) 
    Pay particular attention to linking options, such as for instance "-Wl,-E" 
    which is required to compile the Lua interpreter
- If the image doesn't include "ldd" to check which libraries 
    an application needs, you can find it in recent releases of uClinux 
    (in uClibc/utils/). If it doesn't compile, try "scanefl -an" from pax-utils 
    or "readelf"
- bin-elf is only needed if you wish to compile code as bare-metal, ie. 
stand-alone apps that don't use any OS to run. Since we'll use uClinux, ignore 
stuff that mention bin-elf
- To figure how to build and install the files that make an application, 
    you'll have to go through its config/Makefile(s) line by line. It's easier 
    to start from the deepest Makefile and work your way up
- If an application is part of uClinux-dist and you would like to compile 
    it indepently into an ipkg package but there are errors you can't solve, 
    a work around is to simply run "make menuconfig" to include it 
    in uClinux, build an image, and simply copy the binaries from its staging 
    directory and build an ipkg package
- Do not bother adding -fpic/-fPIC switches: The Blackfin toolchain takes 
    care of this
- Don't mix different versions of the toolchain, the uClinux-dist, and 
    the kernel + libraries running on the Atcom
- To add files to ./romfs during the build process, edit vendors/Rowetel/IP04/Makefile
- If you added files manually in ./romfs, you can build a new image with 
    "make image"
- To find out which version of uClibc is included in uClinux-dist:
 
 printf 
    '#include <features.h>\n__UCLIBC_MAJOR__ __UCLIBC_MINOR__ __UCLIBC_SUBLEVEL__\n' 
    | bfin-uclinux-gcc -E - | tail -1
- To remove unneeded libraries, in uClinux-dist, run "make config_menuconfig", 
    go to Blackfin build options, and enable "Cull unused ELF shared libraries". 
    Make sure no application requires those libraries, though: For instance, 
    dropbear requires libutil.so.0, which is removed by that option...
- In uClinux-dist in the ./vendor section, if a Makefile.local exists, 
    it gets included along with the Makefile. An easy way to add commands without 
    changing the standard Makefile
Here are standard variables that you can use in Makefiles to compile files 
as ELF FDPIC (instead of FLAT):
    - #Assuming the Blackfin toolchain is untarred there
    - export PATH:=$(PATH):/opt/uClinux/bfin-linux-uclibc/bin
    -  
    - TARGET_CROSS=bfin-linux-uclibc-
    -  
    - export CC=$(TARGET_CROSS)gcc
    - export STRIP=$(TARGET_CROSS)strip
    - export AR=$(TARGET_CROSS)ar rcu
    - export RANLIB=$(TARGET_CROSS)ranlib
    -  
    - #Download and untar uClinux-dist for apps that need it
 #Compile uClinux 
    to get binaries
 export STAGING_DIR=/usr/src/uClinux-dist/staging
- export UCLINUX_LIB=/usr/src/uClinux-dist/lib
    - export UCLINUX_ROOT_LIB=/usr/src/uClinux-dist/root/lib
    -  
    - export CFLAGS=-O2 -Wall -pedantic -I$(STAGING_DIR)/usr/include
    - export LDFLAGS=-L$(STAGING_DIR)/usr/lib -L$(UCLINUX_LIB) -L$(UCLINUX_ROOT_LIB) 
    add_required_libraries_here
To compile a static library:
    - $(AR) rcu -static -o libmylib.a mylib.o mylib2.o
    - #ranlib not always needed, but it doesn't hurt
    - $(RANLIB) libmylib.a
To compile a shared library:
    - $(CC) $(CFLAGS) -shared -Wl,-E,-soname,libmylib.so -o libmylib.so 
    mylib.c
To call AutoTool's configure to compile a C application:
    - export PATH=$PATH:/usr/src/baps/opt/uClinux/bfin-linux-uclibc/bin
    -  
    - ./configure --host=bfin-linux-uclibc CC=bfin-linux-uclibc-gcc AS=bfin-linux-uclibc-as 
    CFLAGS="-O2 -Wall -ansi -pedantic -I/usr/src/uClinux-dist/linux-2.6.x 
    -I/usr/src/uClinux-dist/staging/usr/include " LDFLAGS="$LDFLAGS 
    -L/usr/src/uClinux-dist/staging/usr/lib" AR="bfin-linux-uclibc-ar 
    rcu" RANLIB=bfin-linux-uclibc-ranlib
The same, to compile a C++ application:
./configure --host=bfin-linux-uclibc CPP=bfin-linux-uclibc-cpp CXX=bfin-linux-uclibc-g++ 
CC=bfin-linux-uclibc-gcc
Testing an image
You don't have to burn a new image just to try it and see if it works. Here's 
how to set things up:
    - Now is the time to save any data out of the Atcom, in case they get 
    removed/overwritten...
- On a workstation, run a TFTP server and put the image in its data directory 
    (for Windows, you can try the open-source Tftpd32 
    )
- Connect a serial cable to the Atcom and reboot
- Hit any key to prevent Uboot from loading Linux, and type the following 
    commands:
 
 #Disable autoloading of kernel
 set autostart
 set 
    serverip tftpd.server.address
 set bootargs ethaddr=atcom.MAC.address 
    root=/dev/mtdblock0 rw
 #Save params to EEPROM
 save
 tftp 0x1000000 
    myimage
 bootm 0x1000000
Important: Astfin-based images from Atcom are hard-coded to use mtd2 to save 
persistent data, even if you just wanted to test an image...
If the image works OK, reboot the Atcom, enter Uboot, and type the following 
commands to burn the image in the NAND:
    - nand erase clean- nand erase
 set autostart
 tftp 0x1000000 uImage
 ;tftp gives image size in "Bytes transferred": Use this 
    info as the last parameter below, using the next 20.000 increment to make 
    sure it fits:
 nand write 0x1000000 0x0 0x300000
 ;alternatively, use 
    the "filesize" variable
- nand write 0x1000000 0x0 ${filesize}
 
 set autostart yes
- save
    - reset
Switchfin
Switchfin is a fork of the AstFin2 
project by the SwitchVoice people that 
compiles a full binary image of the uClinux OS, and optionally  Asterisk, Dahdi 
and some other 
software (ls /usr/src/switchfin/package/).
Its makefile will take care of downloading 
the Blackfin toolchain, uClinux, and uClibc, and by default, generate both the 
image and the bootloader.
What I don't like about Switchfin:
    - 20MB of RAM is taken from the 64MB for the root filesystem, while BAPS 
    reads the root filesystem directly from NAND
- It downloads 80MB of files into /persistent/sounds/
- Unlike BAPS, Switchfin doesn't install applications through a package 
    manager: Every application must be compiled in the image
Updating
There are three ways to update an Atcom already running Switchfin:
    - If already running Switchfin, by connecting to its embedded Switchfin web server
- By connecting to the Atcom through its serial port or SSH, downloading 
    uImage-md5 into /persistent/imageupdate/, renaming the file as uImage, and 
    rebooting: The IP01 will reflash itself automatically
- By connecting to the Atcom through its serial port and a terminal application, 
    and using tftp + bootm (and if it works OK, burning the image to NAND)
Creating a new image
Here's how to compile the latest source from SVN on an x86 Ubuntu 10.04 host:
    - apt-get update
- apt-get upgrade (reboot with new kernel, if applicable)
- Install prerequisites: 
    apt-get install autoconf automake bash binutils bison bzip2 coreutils 
    flex gawk gcc gettext grep intltool iputils-ping libtool libz-dev linux-libc-dev 
    liblzo2-dev liblzo2-2 libncurses5 libreadline5 libreadline5-dev libncurses5-dev 
    ncurses-dev m4 make pax-utils pkg-config rpm texinfo zlib1g zlib1g-dev subversion 
    mtd-utils uuid-dev uuid unzip build-essential
 
 Note: On Linux Mint, 
    libreadline5-dev has been replaced with libreadline-gplv2-dev
 
- cd /usr/src
- svn co https://switchfin.svn.sourceforge.net/svnroot/switchfin/switchfin/trunk/ 
    switchfin
- cd switchfin
- make menuconfig
 
 Note: Include "SpanDSP based CallerID", 
    or libspandsp won't be built while it's expected by Asterisk
 
- make
- vi build_ip01/uClinux-dist/lib/libcurl/Makefile: If it refers to libcurl.so.4, 
    change this for libcurl.so.5 ; make
- make image: Output will be found in eg. ./build_01/image_01/ (more 
    infos):
        - uImage - uClinux image + file system compressed in a single file. 
        This image typically you load using the tftp support of u-boot or using 
        the serial interface support of u-boot.
- uImage-md5 - This is the image above with 32 bytes MD5 check sum 
        appended. This kind of image you can load directly (http or tftp) from 
        the GUI of the PBX.
        - u-boot.ldr - u-boot image which you can load in your hardware target 
        using JTAG programmer (like icebear) or serial interface (if you have 
        already an old u-boot loaded).
- cp build_ip01/image_ip01/uImage /tftpboot
In case you need them, binaries are located under build_ip01/image_ip01/.
Make sure a web server is running on the workstation, with its docroot set 
to "/tftpboot". If the Atcom is already running AstFin or Switchfin 
with the Asterisk GUI, just aim your browser to its web server, log on as admin/switchfin, 
locate Firmware Update, and copy/paste the full URL to uImage-md5 on the workstation. 
Reboot the Atcom, and check that it's using the new firmware.
If there's 
no GUI available, follow the instructions above to download the image through 
TFTP after copying the image in the /tftpboot on the workstation:
    - Connect the Atcom to the workstation through the serial cable
- Unplug, replug the Atcom, and hit any key to prevent it from booting 
    Linux
- Type the following commands (stuff in bold must be customized to fit 
    your setup):
 
 setenv autostart
 setenv ipaddr 192.168.0.9
 setenv 
    netmask 255.255.255.0
 setenv gatewayip 192.168.0.254
 setenv 
    serverip 192.168.0.3
 setenv bootargs ethaddr=Atcom.MAC.address console=ttyBF0,115200 
    root=/dev/mtdblock0 rw
 save
 
- Download the image in RAM, and check its size ("Bytes transferred 
    = 7471104 (720000 hex)):
 
 tftp 0x2000000 uImage
 
 Note: 
    If the Atcom can't fetch the image, unplug and replug its Ethernet cable, 
    and give it another try.
 
- Check that the image works OK by booting it directly from RAM:
 
 bootm 
    0x2000000
 
 Log on as root/uClinux
 
- IF OK, redownload image and save it to EEPROM:
 
 nand erase clean
 nand 
    erase
 nand write 0x2000000 0x0 0x720000
 setenv
 setenv autostart yes
 save
 reset
Note that unlike the BAPS firmware, Switchfin keeps the root filesystem in 
RAM and uses the NAND to save persistent files like sound files, etc. Consequently, 
only 40MB out of 64MB is available in RAM once Switchfin is up and running.
If you get the error "couldn't allocate a block (no free space)", 
it means your uImage is now to big, you need to enable "Cull unused ELF 
shared libraries" in the Build options, or remove some applications 
when running "make menuconfig" or the built files in the root 
filesystem. Alternatively, you can increase the space reserved for the 
root filesystem by editing /package/uClinux-dist/vendors/SwitchVoice/vendor.mak 
to change the EXT2_BLOCKS variable before running "make image".
Post-install tweakings
Network
If you get "ping: bad address 
'downloads.digium.com'", check that the IP address is OK: ifconfig. If 
not: ifconfig eth0 192.168.0.9, and connect to the Atcom's web GUI to change 
its IP configuration (Admin > Network settings). Click on Reboot when prompted.
Alternatively, the network configuration can be changed by editing 
/etc/asterisk/rc_org.conf which Switchfin uses to overwrite /etc/network.conf 
at boot-time.
By default, Switchfin provides an SSHd server (dropbear), so you can also 
connect to the Atcom through SSH instead of the serial port
Time
/etc/asterisk/rc_org.conf
    - #For Central European Time
    - TIMEZONE = CET-1CEST,M3.5.0/2,M10.5.0/3
 TZNAME=Europe/Paris
-  
    - #For France
    - NTPserver = fr.pool.ntp.org
Note: The reason those settings are located in /etc/asterisk is so they are 
accessible from the the Asterisk Management Interface (AMI). rc_org.conf is 
mapped to network.conf via the /etc/rc script.
Boot errors
If you see error messages related to dahdi/vlan "Permission denied":
    - chmod +x /persistent/etc/init.d/dahdi
 chmod +x /persistent/etc/init.d/vlan
 
 /persistent/etc/init.d/dahdi 
    disable
 /persistent/etc/init.d/vlan disable
 
 rm /persistent/etc/rc.d/S55vlan
 
 /persistent/etc/init.d/dahdi 
    enable
 /persistent/etc/init.d/vlan enable
 ls -al /etc/rc.d/
 
 sync
 reboot
Check that the problem went away
Procwatch
/etc/init.d/asteriskwatch calls procwatch, which reboots the host if asterisk 
isn't running. You can disable this while you're configuring asterisk:
/etc/init.d/asteriskwatch disable
Dahdi
Switchfin uses Dahdi instead of Zaptel. Its configuration file is located 
in /etc/dahdi/system.conf. The equivalent of zapata.conf is /etc/asterisk/chan_dahdi.conf.
Asterisk
To enable full logging for debugging:
 
How 
to Load u-boot in the hardware?
Can 
I load the uImage using the web GUI
"In the PBX GUI go to 'Firmware upgrade' (in the advanced options section) 
and select HTTP URL": Is it the same as the VoIPTel CE web GUI?
Can 
I load the uImage manually using u-boot?
Uprading 
an Atcom appliance that was installed using BAPS
Here's what the Switchfin tree contains after downloading the latest SVN 
code:
    - config/
- Config.in
- CONTRIBUTORS
- COPYING
- Makefile
- package/
- README
- .svn/
- TODO
Next, running "make menuconfig" adds the following two files in 
the root directory:
Next, "make" will download and install the Blackfin uClibc toolchain, 
followed by the uClinux distribution.
Trying Switchfin 2010
    - cd /usr/src
- svn co https://switchfin.svn.sourceforge.net/svnroot/switchfin/switchfin/tags/switchfin-2010R1-RC5/ 
    switchfin-2010R1-RC5
- cd switchfin-2010R1-RC5
- make menuconfig
- make
- make image
Cross-compiling Yate
Todo
    - Cross-compiling: Put settings in Bash script before calling configure
- Make: Edit fork() -> vfork() if needed
- Compile
- Install and configure: What files are required where?
- Check that it works with the FXO module: Does it need Zaptel?
From the original source
    - Install the toolchain + uclibc
- cd /usr/src
- svn checkout http://voip.null.ro/svn/yate/trunk yate
- cd yate
- ./autogen.sh
- Create a Bash script to pass parameters to "configure":
 
 #!/bin/bash
 
 TARGET=bfin-linux-uclibc
 
 CPP=${TARGET}-cpp
 CXX=${TARGET}-g++
 CC=${TARGET}-gcc
 
 STAGING_DIR:=/usr/src/switchfin/build_ip01/blackfin-linux-dist/staging
 STAGING_INC=${STAGING_DIR}/usr/include
 STAGING_LIB=${STAGING_DIR}/usr/lib
 
 YATE_CONFIGURE_OPTS=--host=${TARGET} 
    --prefix=/usr --sysconfdir=/etc --with-openssl=${STAGING_INC}/.. --with-libspeex=${STAGING_INC} 
    --with-zlib=${STAGING_INC}/.. --enable-dahdi --disable-zaptel --disable-wpcard 
    --disable-tdmcard --disable-wanpipe --enable-ilbc --disable-rtti --without-libpq 
    --without-mysql --without-libgsm  --without-amrnb --with-spandsp --without-pwlib 
    --without-openh323 --without-libqt4
 
 LDFLAGS="-L${STAGING_LIB}" 
    ./configure ${YATE_CONFIGURE_OPTS}
 
- chmod +x myconfig.bash
- ./myconfig.bash
- make
This is a Bash script to compile Yate for ARM:
http://voip.null.ro/tarballs/xconfigure
Adding Yate to Switchfin as an alternative to Asterisk
Note: By now, patches should be part of Switchfin, 
so this is no longer needed
    - cd /usr/src
- git clone https://github.com/HaydenTech/switchfin.git 
    hayden-switchfin
- wget -O - https://github.com/HaydenTech/switchfin/commit/558244ca9659b8b0223174300df0432ad6ab1737.diff 
    | patch -p1
- make menuconfig: Check "Yate"
- make
BAPS as alternative to buildroot (Switch/Astfin/uClinux-dist)
The very first build of Asterisk for the BlackFin processor was a hack of 
OpenWRT called uCasterisk, ie. it used the same buildroot approach 
("uClinux is the distribution of choice for Media and other embedded products. 
OpenWrt on the other hand is the distribution of choice for building a router." 
source)
"There are two commonly used build systems for Blackfin Asterisk, Astfin 
and BAPS. Astfin builds 
a single image containing all software, whereas BAPS is a package-based build 
system (like apt-get or rpm). It is easy to move between Astfin and BAPS (they 
both use similar Makefiles), so feel free to experiment with both." (source)
As of January 2011, when using the uClinux.mk Makefile, you will use the 
2007 version of the uClinux-dist software just to build the kernel with a few applications pre-installed, including 
the ipkg application which lets the user download and install packages, just like RPM and apt-get. As 
a result, a standard BAPS image from Rowetel is only 2MB, while 
a standard uClinux-dist 
image is about 7MB.
AstFin  is a rewrite of uCasterisk. 
At some point, AstFin stalled and BAPS packages picked up. As of June 2010, AstFin2 is apparently 
headed in a different direction than just Asterisk, so some developers forked 
the code to Switchfin.
Here 
is a comparison of BAPS and AstFin2, and here 
is a list of BAPS packages. BAPS also comes from the OpenWrt world (ipkg).
Note that the Uboot that ships with BAPS Atcom is very compact, and doesn't 
include commands like "mtdparts".
The reason the BAPS software require(d) to first boot Linux entirely in RAM, 
copy the RAM root filesystem to NAND, and reboot is because of this 
bug in mkyaffs.
uClinux.mk can build different images, such as "make -f uClinux.mk uClinux.mtd0.ip01" 
which is for the Atcom IP01 and has root=/dev/mtdblock0 hard-coded so it uses 
a RAM-based root filesystem.
Upgrading BAPS-based firmware
Here's how to upgrade an 
Atcom currently running a Astfin/Switchfin-based firmware to a BAPS-based firmware:
    - Connect to the Atcom through SSH
- cd /persistent
- wget http://rowetel.com/ucasterisk/downloads/uImage_r2.mtd0.ip01
 
- dd if=uImage_r2.mtd0.ip01 of=/dev/mtdblock1
- reboot
Once back in BAPS as root, the unit uses 192.168.1.30 as its IP address. 
To have it configured through DHCP instead, see below.
Building your own BAPS uImage
Based on this article. 
Note that unlike other *.mk files, uClinux.mk doesn't create an ipkg package 
but a Uboot-compatible, binary image that contains just the Linux kernel and a few basic 
applications (shell, ipkg, etc.).
WORKSTATION
    - Install prerequisites
- cd /usr/src
- svn co http://svn.astfin.org/software/baps/trunk baps
- cd baps
- wget -c http://blackfin.uclinux.org/gf/download/frsrelease/348/3347/blackfin-toolchain-07r1.1-3.i386.tar.gz
- tar xzf blackfin-toolchain-07r1.1-3.i386.tar.gz
- (if not starting from scratch) make -f uClinux.mk uClinux-clean
- make -f uClinux.mk uClinux
 This will download, patch, and compile the uClinux-dist 
    source code.
 
 To solve a possible PATH_STR error:
 
 vi uClinux-dist/linux-2.6.x/scripts/mod/sumversion.c
 add 
    "#include <limits.h>"
 
- cp uClinux-dist/images/uImage /tftpboot/uImage
 (uImage = uImage.ext2)
- Reboot the Atcom and test/burn this new image as explained below
ATCOM
To try out new image directly
    - ip04> set autostart
- ip04> setenv ipaddr 192.168.0.9
- ip04> setenv netmask 255.255.255.0
- ip04> setenv gatewayip 192.168.0.254
- ip04> set bootargs ethaddr=$(ethaddr) root=/dev/mtdblock0 rw
- ip04> setenv serverip 192.168.0.3
 
 serverip 
    = address of TFTP server from which image will be dowloaded
 
- ip04> save
- ip04> tftp 0x1000000 uImage
- ip04> bootm
To save new image into NAND
    - (In uClinux) # reboot
- ip04> set autostart
- ip04> tftp 0x1000000 uImage
- ip04> nand erase clean
- ip04> nand erase
- ip04> nand write 0x1000000 0x0 0x300000
- ip04> set bootargs ethaddr=Atcom.MAC.address root=/dev/mtdblock0 rw
- ip04> save
- ip04> reset
uClinux is running but using a RAM-based ext2 root file system (mtdblock0). 
To make it persistent, we must copy /root into /dev/mtdblock2 in the NAND:
    - root:~> copy_rootfs.sh
- root:~> reboot
Next, set up u-boot to mount the root filesystem from /dev/mtdblock2 (type "print" to check 
what env variables are already set, if any):
    - ip04> tftp 0x1000000 uImage
- ip04> set nandboot 'nboot 0x1000000 0x0'
- ip04> set bootcmd run nandboot
- ip04> set bootargs ethaddr=Atcom.MAC.address root=/dev/mtdblock2 rw
- ip04> set autostart yes
- ip04> save
- ip04> reset
- Let the Atcom reboot and load uClinux
Install packages through ipkg (repository address in /etc/ipkg.conf):
    - root:~> ipkg update
- root:~> ipkg list
- root:~> ipkg install zaptel-ip01
- root:~> ipkg install asterisk-1.4.20
- root:~> ipkg install dropbear
- root:~> ipkg install ntp
- root:~> ipkg list_installed
- root:~> reboot
Note:
    - The dropbear package (SSH server) doesn't install a boot script in /etc/init.d/
Building BAPS 2008
In case you previously compiled 2007, make sure you rename uClinux-dist to 
eg. uClinux-dist2007 and opt/uClinux to opt/uClinux2007.
    - cd /usr/src
- svn co http://svn.astfin.org/software/baps/trunk baps
- cd baps
- wget -c http://blackfin.uclinux.org/gf/download/frsrelease/375/4037/blackfin-toolchain-08r1-8.i386.tar.gz
- wget -c http://blackfin.uclinux.org/gf/download/frsrelease/375/4041/blackfin-toolchain-uclibc-default-08r1-8.i386.tar.gz
- tar xzvf blackfin-toolchain-08r1-8.i386.tar.gz
- tar xzvf blackfin-toolchain-uclibc-default-08r1-8.i386.tar.gz
- make -f uClinux2008.mk uClinux
In case you want to check how long compiling takes, edit /usr/src/baps/uClinux2008.mk 
thusly:
echo 'date' > time.txt
echo 'date' >> time.txt
Customizing kernel and/or applications
If some applications aren't available as ipkg packages but are available 
in the uClinux-dist version downloaded by the uClinux.mk file (2007), you can customize 
settings this way, before compiling a new image and find the compiled files 
under /usr/src/baps/uClinux-dist/root:
For the kernel: cd uClinux-dist ; make linux_menuconfig
For applications: cd uClinux-dist ; make config_menuconfig
Once done, cd /usr/src/baps/ ; make -f uClinux.mk uClinux-clean ; make -f uClinux.mk uClinux
If the application isn't available in that old version of uClinxux-dist, 
download the latest from Blackfin's site and try to compile it with either the 
2007 version of the toolchain or, if it doesn't work (likely) with the latest 
version of the toolchain, and see if the application works OK on an older uClinux 
kernel. If it complains of missing libraries, start by checking its inner-most 
Makefile and try to add the missing stuff to its LDFLAGS variable.
Things to try in BAPS
Connect the Atcom to a hub through the WAN interface, and telnet to it from 
a PC. By default, the Atcom is set up to use 192.168.1.30, and no username/password 
is required to telnet to it (to add a username + password, install the "login" 
package, whose default combo is root/uClinux).
Playing with ipkg
ipkg update
ipkg upgrade
ipkg list //uninstalled packages available in repo
ipkg info mypackage
ipkg install mypackage
ipkg status mypackage
ipkg list_installed //packages already installed in host
ipkg files mypackage
ipkg remove mypackage
Note: The wildcard character "*" is allowed, eg. "libstd*".
Installing DropBear (SSH server/client)
    - ipkg install dropbear
 
 DropBear is launched through Inetd: cat 
    /etc/inetd.conf ; netstat -natp
 
- Log on as root/uClinux
If you get errors in the log file:
    - touch /var/log/lastlog
- touch /var/log/wtmp
To set the date/time
First, install ntp:
    - ipkg install ntp
- vi /etc/init.d/ntp: Change for NTP servers close to you, eg. "fr.pool.ntp.org" 
    for France
- /etc/init.d/ntp enable
By default, time is displayed as UTC. To display the time correctly, 
"date" provided by Busybox 1.4.1 reads it localization through /etc/TZ, 
which is copied to /etc/profile and exported as environment variable by the 
/etc/init.d/ntp script:
For Central European Time, vi /etc/TZ to this:
    - CET-1CEST,M3.5.0/2,M10.5.0/3
- reboot
- run "date", and check that time is displayed OK
If you can't reboot because you're running a test image in RAM, here's how 
to change the current date/time for your location:
    - ntpdate fr.pool.ntp.org
- export TZ=CET-1CEST,M3.5.0/2,M10.5.0/3
- date
More information here.
Adding CRON jobs
I couldn't get "ntpd" to work, so resorted to running ntpdate every 
hour through a CRON job:
    - ipkg install cron
- vi /etc/config/crontab
 
 #BAD @hourly root /sbin/ntpdate -s -b 
    -p 8 -u fr.pool.ntp.org
 0 * * * * root /sbin/ntpdate -s -b -p 8 -u fr.pool.ntp.org
 
- /etc/init.d/cron enable
- /etc/init.d/cron start
- tail -f /var/log/messages, and wait about a minute for cron to re-read 
    its contrab automatically
Syslog
By default, syslogd will output "-- MARK --" every 20mn to /var/log/messages. 
syslogd is actually provided by Busybox, and this version ignore /etc/syslog.conf.
    - vi /etc/inittab
 
 slog:unknown:/bin/syslogd -n -m0
 
- reboot
If too much data in /var/log/messages, configure syslog 
to send data to remote syslogd server or /tmp (not good idea: No trace after 
rebooting) to save NAND.
To check network information
root:~> cat /proc/net/
To change the static IP settings
Edit /etc/init.d/network-static
To enable DHCP
    - /etc/init.d/network-static disable
- /etc/init.d/network enable
- reboot
If the network link is down, unplug and replug the network cable that connects 
the Atcom to the hub/switch, and see if the unit gets an address from the DHCP. 
For some reason, the Atcom sometimes has its "link down".
To check the version of ucLinux
> uname -a
Linux ip04 2.6.19.3-ADI-2007R1.1-svn #3 Mon Mar 10 08:53:41 CST 2008 blackfin 
unknown
> version
Linux release 2.6.19.3-ADI-2007R1.1-svn, build #3 Mon Mar 10 08:53:41 CST 
2008
release 2007R1, build #13 Mon Mar 10 09:55:24 CST 2008
> cat /etc/issue
BlackfinOne BF532 v2 uClinux (http://blackfin.uclinux.org/projects/bf1/)
> cat /etc/firmwareversion
To change the root password
    - perl -e 'print "crypt("yourpassword", "yoursalt")","\n"'
- copy/paste this new password in /etc/passwd
To transfer files to/from the Atcom
Use its FTP server by logging on as root/uClinux. wget is also installed by 
default.
Installing Lighttp + PHP + SQLite BAPS packages
    - By default, the Asterisk web server is running on TCP80. To turn it 
    off:
 
 vi /etc/asterisk/http.conf: enabled=no
 /etc/init.d/asterisk 
    stop ; /etc/init.d/asterisk start
 
- To install Lighttp, PHP, and SQLite:
 
 ipkg install lighttpd
 ipkg 
    install php
 ipkg install sqlite3
 ipkg list_installed
 
- Aim your browser at http://localhost/ to 
    check that Lighttpd is up and running. You can also get information on PHP 
    (http://localhost/test.php), and 
    play with SQLite (http://localhost/testdb.php) 
 
 By 
    default, Lighttpd starts with /etc/lighttpd.conf, and the document root 
    is /www
 
- To configure Lighttp so as to use PHP for CGI calls:
 
 (to create 
    a symlink in /etc/rc.d/)
 /etc/init.d/fastphp 
    enable
 
 vi /etc/init.d/lighttpd: Change "-f /etc/lighttpd.conf" 
    to "-f /etc/lighttpd-fastphp.conf"
 
 /etc/init.d/fastphp 
    start
 
 /etc/init.d/lighttpd stop
 /etc/init.d/lighttpd start
 
 ps aux | grep -i php
 
- ls -al /etc/rc.d/, and make sure Lighttpd is started before the PHP 
    FastCGI process
Installing Asterisk and Zaptel/Zapata
In case the Atcom didn't come with Asterisk preinstalled or you upgraded 
the image:
    - ipkg list, and check what the latest Asterisk package is
- ipkg install asterisk-1.4.20
- ipkg install zaptel-ip01
- vi /etc/zaptel.conf: If not living in the US, edit as needed
- cd /etc/asterisk
- mv sip.conf sip.conf.orig
- mv extensions.conf extensions.conf.orig
- mv users.conf users.conf.orig
- vi sip.conf
- vi rtp.conf
- vi extensions.conf
- vi indications.conf
- vi asterisk.conf to move astlogdir to RAM-based 
    /tmp instead of NAND-based /
- vi asterisk.conf to move astspooldir to 
    RAM-based /tmp instead of NAND-based /
- vi /etc/init.d/asterisk
 
 #Killall might leave RAM in disarray
 stop) 
    asterisk -rx "stop now";;
 
- /etc/init.d/asterisk enable
- /etc/init.d/asterisk start
- ps aux | grep -i asterisk
- asterisk -vvvvvvvvvvvvr
- sip show peers
You can edit modules.conf to avoid loading modules you 
don't need, eg.
    - noload => pbx_gtkconsole.c
    - noload => pbx_kdeconsole.c
    - noload => app_intercom.c
    - noload => chan_modem.c
    - noload => chan_modem_aopen.c
    - noload => chan_modem_bestdata.c
    - noload => chan_modem_i4l.c
    -  
    - load => res_musiconhold.c
    -  
    - noload => chan_alsa.c
    - noload => cdr_csv.c
    - noload => cdr_custom.c
    - noload => res_smdi.c
    - noload => chan_iax2.c
    - noload => format_g723.so
    - noload => format_g726.so
    - noload => format_g729.so
    - noload => format_gsm.c
    - noload => format_h263.so
    - noload => format_h264.so
    - noload => format_ilbc.so
    - noload => format_jpeg.so
    - noload => format_sln.so
    - noload => format_vox.so
    - noload => codec_g726.so
    - noload => codec_g729.so
    - noload => codec_speex.so
I don't know why some modules in .c and others in .so.
By default, output from launching "asterisk -vvvc" is in reverse 
video, making it harder to read. To changed output to standard black text/white 
background, edit asterisk.conf, and add this:
    - [options]
    - nocolor=yes
Asterisk
Checking Asterisk
On the Atcom, run "asterisk -r" to connect to the console, and 
check log messages.
Connect to Asterisk from an SIP client, and dial either 2008 (play prompt) 
or 2020 (record your voice, and check performance).
Modules
ls -al /usr/lib/asterisk/modules/
root:~> cat /proc/modules 
Managing sound files
ls -al /var/lib/asterisk/sounds/
ls -al /var/lib/asterisk/sounds/moh
Asterisk configuration files
They are located in the usual /etc/asterisk/. To restore its configuration 
files:
    - root:~> ipkg update
- root:~> ipkg remove asterisk
- root:~> ipkg install asterisk
- root:~> reboot
Caller ID
Asterisk requires the asterisk-spandsp package to handle CallerID. To check 
if it's installed:
$ ipkg list_installed
If not, here's how to install it:
    - $ /etc/init.d/asterisk stop
- $ ipkg remove asterisk
- $ ipkg install asterisk-spandsp
- $ reboot
Configuring Zaptel
To configure the Zaptel interface for your country, edit /etc/init.d/zaptel. 
Here's an example for Australia:
start) modprobe wcfxs opermode=AUSTRALIA;
root:~> ls -al /usr/doc/
-rw-r--r--    1 root     root         3142 
May 31 01:56 zaptel.txt
root:~> cat /proc/zaptel/1
Adding extension to sip.conf
    - tail /var/log/messages
- /etc/init.d/zaptel start
- vi /etc/asterisk/sip.conf
 
 [6000]
 type=friend
 secret=6000
 host=dynamic
 qualify=yes
 nat=no
 context=demo
 
- /etc/init.d/asterisk start
- From an IP phone, connect to server with above account, and dial 1000
Writing a PHP script to handle call through Asterisk + AGI
    - cd /var/lib/asterisk/agi-bin/
- vi myagiscript.php
 
 #!/sbin/php
 <?php
 print "Hello, 
    world!";
 ?>
 
-  
Building a new Busybox
    - 
On the workstation, in /usr/src/baps, compile uClinux once to get its source tree: make -f uClinux.dist
- Remove object files: make -f uClinux.mk uClinux-clean
- .. cd uClinux-dist, make config_menuconfig, and customize options for Busybox
 
- cd .. ; make -f uClinux.mk
- If compiling went OK, you should have a new busybox in ./uClinux-dist/root/bin
- On the Atcom, download this file, "chmod 755 busybox" and move (not copy) 
    it to /bin. 
    There is no need to copy this file in /sbin, as /sbin is just a symlink to /bin
- In /bin, add the new symlinks, eg. "ln -s busybox unzip".
Atcom firmware
As of June 2010, Atcom provides the AstFin-based VoIPTel 
CE firmware (eg. IP01-0.3.7.ext2) so you can update the appliance.
Here's 
how to reflash an Atcom that used the BAPS packaging system; Since this firmware 
doesn't support a web GUI, we'll use a serial cable to download the latest firmware 
from a workstation:
    - Hook up a DB9-DB9 male-female serial cable between the workstation and 
    the Atcom
- On the workstation, install a TFTP server eg. TFTPd32, 
    copy the ext2 Atcom image in its directory, and start the TFTPd server
- Still on the workstation, open a terminal application with the following 
    settings:
 
 Choose the right COM port, 115200 bps, 8 data bits and 
    no parity, hardware flow control off
 
- Reboot the Atcom
- Hit any key to prevent it from booting, and type the following commands 
    (you'll have to type: The serial connection is too slow and will probably 
    drop out some characters):
 
 ip04>setenv 
    autostart
 ip04>setenv ipaddr 192.168.0.9
 ip04>setenv netmask 
    255.255.255.0
 ip04>setenv gatewayip 192.168.0.254
 ip04>setenv 
    serverip 192.168.0.1
 ip04>save
 
 ip04>tftp 0x1000000 IP01-0.3.7.ext2
 
 Here, 
    I had a networking problem, where the Atcom couldn't connect to the TFTPd 
    server. I had to unplug and replug the Ethernet cable connecting the Atcom 
    to the hub
 
 ip04>nand 
    erase clean
 ip04>nand erase
 ip04>nand write 0x1000000 0x0 0x700000
 
 ip04>setenv 
    bootargs ethaddr=$(ethaddr) console=ttyBF0,115200 root=/dev/mtdblock0 rw 
    (NOT mtdblock2, or you'll get a kernel panic)
 ip04>setenv 
    autostart yes
 ip04>setenv nandboot 'nboot 0x2000000 0x0'
 ip04>setenv 
    bootcmd run nandboot
 ip04>save
 ip04>reset
 
 
- Reboot the Atcom, wait for the unit to download a zillion things and 
    reboot, and check that it boots up OK:
 
 root:~> uname -a
 Linux 
    IP0x 2.6.22.18-ADI-2008R1astfin-svn #2 Wed Jun 9 03:00:41 EDT 2010 blackfin 
    unknown
 
 root:~> cat /etc/issue
 BlackfinOne BF532 v2 uClinux 
    (http://blackfin.uclinux.org/projects/bf1/)
 
 root:~> cat /etc/version
 Rowetel/IP04 
    Version 3.2.0 -- Wed Jun  9 03:02:13 EDT 2010
 
 root:~> cat 
    /etc/firmwareversion
 voiptel_ce_IP01-0.3.7
 
- If you want to have a DHCP server send an IP configuration to the Atcom 
    (and use a local NTP server pool):
 
 > 
    vi /etc/network.conf
 
 DHCPD=yes
 NTPserver=0.fr.pool.ntp.org
 
 > 
    reboot
 > ping www.google.com
 
- Aim your browser at eg. http://192.168.0.9/, 
    and logon as admin / atcom
- If you'd rather connect to the appliance through SSH, use the serial 
    connection to set a new root password, and then aim your SSH client to the 
    appliance
Q&A
How to add SSHd, vim, Lighttpd + Lua + SQLite?, CRON?
How to upgrade from VoIPTel CE to own compiled Switchfin or Blackfin uClinux?
How to add alias ll=ls -al?
AstFin2
The image will include uClinux and whatever options you chose:
    - cd /usr/src
- svn co https://astfin.svn.sourceforge.net/svnroot/astfin/software/astfin/astfin2/trunk/ 
    astfin2
- cd astfin2
- make menuconfig
- make
- make image
- To update the Atcom appliance, choose one of the two images available 
    in /usr/src/astinf2/build_xx:
        - uImage-md5 to update through the web GUI. Use this image if you 
        are already running an AstFin2 firmware
        - uImage.ext2 to update from u-boot and an RS232 connection. If you 
        are currently using a BAPS image, use this image to upgrade
Blackfin uClinux-dist
As of June 2010, and unlike Astfin/Switchfin, the uClinux-dist available 
directly from the Blackfin subdomain of uClinux (blackfin.uclinux.org) 
doesn't support the Atcom IP01, so the only reason to work with that version 
is to rip software that hasn't made it to to the Astfin/Switchfin tree. There are plenty 
of information in the Blackfin 
uClinux wiki.
Here's how to add support for the Atcom IP01 and compile uClinux-dist:
    - Download and install the toolchain:
        - cd  /
- wget -c http://blackfin.uclinux.org/gf/download/frsrelease/501/8378/blackfin-toolchain-2010R1-RC4.i386.tar.bz2
- tar xjvf blackfin-toolchain-2010R1-RC4.i386.tar.bz2
- Add toolchain to PATH:
 
 export PATH=$PATH:/opt/uClinux/bfin-linux-uclibc/bin:/opt/uClinux/bfin-uclinux/bin
 echo 
        $PATH
 which bfin-linux-uclibc-gcc
 
 Note: To make this persistent 
        in Linux Mint, edit /etc/environment
 
- Download and install the  uclibc library:
        - cd /
- wget -c http://blackfin.uclinux.org/gf/download/frsrelease/501/8386/blackfin-toolchain-uclibc-full-2010R1-RC4.i386.tar.bz2
- tar xjvf blackfin-toolchain-uclibc-full-2010R1-RC4.i386.tar.bz2
- Download and install the uClinux-dist distribution:
        - cd /usr/src
- wget -c http://blackfin.uclinux.org/gf/download/frsrelease/509/8660/blackfin-linux-dist-2010R1-RC5.tar.bz2
- tar xjvf blackfin-linux-dist-2010R1-RC5.tar.bz2
- mv blackfin-linux-dist uClinux-dist-2010R1-RC5
- cd /usr/src/uClinux-dist-2010R1-RC5
- Compare /usr/src/baps/patch/vendors/Rowetel/IP04-2008/* 
    with /usr/src/uClinux-dist-2010R1-RC5/vendors/AnalogDevices
- mkdir -p vendors/Rowetel/IP04
- cp /usr/src/baps/patch/vendors/Rowetel/IP04-2008/* vendors/Rowetel/IP04
- vi init.sh
 
 #!/bin/bash
 
 #to avoid being prompted a bazillion times when running "make 
menuconfig"
 #the first time
 
 cp vendors/Rowetel/IP04/config.device .config
 chmod u+x config/setconfig
 yes "" | config/setconfig defaults
 config/setconfig final
- make menuconfig
- make
Compiling applications for Blackfin + uClinux
Tips
Converting an application so that it'll run OK on an MMU-less CPU like the 
Blackfin may require making changes to its source code (fixed point DTMF, absence 
of fork(), dynamic memory allocation causing memory fragmentation, etc.)
Toolchains from 2010R1 and above will no longer link applications that use 
fork() instead of vfork() and display the following error message: "undefined 
reference to `_fork'". This is due to its use of AC_FUNC_FORK in configure.ac. 
If an application you are trying to compile does handle fork/vfork, ????
More information: Porting 
Applications to uClinux and We 
have no Fork.
If an application does compile and start, what other issues, 
if any, are to expected besides memory fragmentation and can't be solved by 
running a watchdog application to reboot the system every night?
In case some applications don't behave and cause memory fragmentation, a 
work-around solution until the application has been debugged is to use the procwatch application to keep an eye on them, 
and also run nightly CRON job to reboot the device.
The toolchain contains two sets of binaries: One to compile source to FLAT 
format, and the other, to FDPIC ELF. If you are running a lot of applications 
with shared libraries, FDPIC ELF is a better choice since all the read-only 
sections get shared among all the applications; If you are running only a few 
applications, choose FLAT since only the functions they actually call will be 
compiled into the applications.
If a FLAT binary dies with either SEGV or BUS error, try to increase the 
size of its stack and give it another try:
    - bfin-uclinux-flthdr -s 0x20000 myapp
If the error goes away, you can recompile the FLAT binary with a bigger stack, 
using this option: bfin-uclinux-gcc -Wl,-elf2flt="-s 0x20000" application.c
To have the stack 
checked at runtime, you can compile a FLAT binary with either of those options:
    - -mstack-check-l1
- -fstack-limit-symbol=_stack_start
The Blackfin toolchain comes in three variations, two of which are used to 
compile software for the uClinux OS and one to run without any OS:
    - bfin-uclinux (eg. blackfin-toolchain-09r1.1-2.i386.tar.bz2): Those tools 
    are used to create FLAT files to run under Linux
- bfin-linux-uclibc (eg. blackfin-toolchain-uclibc-default-09r1.1-2.i386.tar.bz2): 
    Used to create FDPIC ELF files to run under Linux
- bfin-elf: To create ELF files that run on bare metal, ie. without any 
    underlying OS (so we'll just ignore this toolchain from here)
"The uClinux FLAT executable format, though it doesn't directly affect 
applications and their operations, does allow quite a few options that the usual 
ELF executables under Linux do not. FLAT format executables come in two basic 
flavors, fully relocated and a variation of position-independent code (PIC). 
The fully relocated version has relocations for its code and data, while the 
PIC version generally needs only a few relocations for its data." (source)
"Program loaders which support Position Independent Code (PIC) have 
been added and a new binary object code format named FLAT, which supports PIC, 
was created. Other program loaders, such as that for ELF, have been modified 
to support other formats which, instead of using PIC, use absolute references. 
It is then the responsibility of the kernel to fix-up these references during 
run time. Both methods have advantages and disadvantages. Traditionally PIC 
is quick and compact but has a size restriction on some architectures. The runtime 
fix-up technique removes this size restriction, but incurs overhead when the 
program is loaded by the kernel." (source)
Bottom line: To compile stand-alone applications, ie. with all their libraries 
compiled statically into the executable, use FLAT; If the application relies 
on shared libraries, use ELF.
The toolchains install by default in /opt. Each of those groups contain the 
following tools:
    - The GCC compiler (eg. bfin-uclinux\bin\bfin-uclinux-gcc)
- The AS assembler
- Thd LD linker
- The AR to turn an ELF file into an archive, ie. static library
To compile C file as FLAT file: bfin-uclinux-gcc -Wl,-elf2flt 
hello.c -o hello
To compile C file as FDPIC: bfin-linux-uclibc-gcc hello.c -o hello
You cannot mix FLAT and FDPIC ELF: Either both the library and the executable 
are compiled as FLAT, or they are both compiled as FDPIC ELF.
If you get an error such as "cc1: error: unrecognized command line option 
"-mcpu=bf518-0.0"", make sure you are using the latest toolchain 
+ uClibc from Blackfin.
You can use this utility to remove debugging information from FDPIC ELF binaries:
    - bfin-linux-uclibc-strip 
hello
Also, before testing a new application, make sure another, different version 
isn't already installed in any directory listed in PATH...
As for variables in Makefiles:
    - Plain variables are local: If you need to access them from a second, 
    chained Makefile, you must pass them as parameters. Here's an example:
 
 #myapp.mk
 MYVAR=test
 all:
 cd 
    myapp; $(MAKE) $(MYVAR)
 
 #./myapp/Makefile
 all:
 @echo 
    $(MYVAR)
 
 # make -f myapp.mk
 
- Alternatively, you can export a plain variable and access it from a 
    second Makefile since it's now an environment variable (only while "make" 
    is running). Here's an example:
 
 #myapp.mk
 export MYVAR=test
 cd 
    myapp; $(MAKE)
 
 #./myapp/Makefile
 @echo $(MYVAR)
 
 # make 
    -f myapp.mk
- When using "cd" and "make", they must be on the 
    same line:
 
 cd /tmp && make
Applications that rely on AutoTools instead of a static, plain Makefile provide 
a configure.ac file where you can check which options are available for "--enable/with" 
and "--disable/without".
Common variables to use in Makefile:
    - WARN:= -Wall -Wmissing-prototypes -Wmissing-declarations -ansi -pedantic
    - CFLAGS:= -O2 $(WARN)-  
    - #Compiling files as FDPIC ELF instead of FLAT
    - export PATH:=$(PATH):/opt/uClinux/bfin-linux-uclibc/bin
    - export TARGET_CROSS:=bfin-linux-uclibc-
    - export CC:=$(TARGET_CROSS)gcc
    - export STRIP:=$(TARGET_CROSS)strip
    - export AR:=$(TARGET_CROSS)ar rcu
    - export RANLIB:=$(TARGET_CROSS)ranlib
Here's a way to call Autotools' configure:
./configure --build=i686-pc-linux-gnu --host=bfin-linux-uclibc CC=/opt/uClinux/bfin-linux-uclibc/bin/bfin-linux-uclibc-gcc 
CFLAGS="-O2 -Wall -pedantic -I/usr/src/uClinux-dist/linux-2.6.x/include 
-I/usr/src/uClinux-dist/staging/usr/include" AR="/opt/uClinux/bfin-linux-uclibc/bin/bfin-linux-uclibc-ar" 
RANLIB="/opt/uClinux/bfin-linux-uclibc/bin/bfin-linux-uclibc-ranlib"
Choose either "-std=c99" or "-ansi", but not both. Some 
programs won't compile when using the "-ansi" switch, so try removing 
it and recompiling.
Use build/host/targer thusly:
    - ./configure --build=i686-pc-linux --host=i686-pc-linux --target=bfin-linux-uclibc
Note: --target is only needed when building the toolchain. You don't need 
this if you use the compiled toolchain from uClinux.
In case AutoTool doesn't include checking support for malloc, you can force 
the malloc configure thusly:
    - Configure the shell to export this variable:
 
 export ac_cv_func_malloc_0_nonnull=yes
 
- Write a configuration file, and export its location:
 
 export CONFIG_SITE=$PATH_TO_FILE/config.site
 
 For 
    reference, you can check uClinux-dist's vendors/config/bfin/config.site
- Pass the variable to configure:
 
 ./configure ac_cv_func_malloc_0_nonnull=yes
Using AutoConf's configure, it's possible to know which settings to enable/disable 
by checking the configure script and the Makefile it creates.
If libtool can't find libraries the application needs for compiling, you 
might have to modify ltmain.sh.
When compiling an application, if some libraries aren't available in the 
uClinux-dist used by your firmware, it might be available in other versions 
of uClinux-dist.
More information:
Packaging applications with ipkg (BAPS)
Infos
    - Download uClinux-dist and check under user/ if the application 
    has already been ported to uClinux. If that's the case, try to extract its 
    Makefile and compile it manually before attempting to convert it to an ipkg 
    package
 
 Note that BAPS uses the 2007 version of uClinux-dist, and 
    an application that is part of a more recent release of uClinux-dist might 
    not compile with that 2007 version of the toolchain. OTOH, the Blackfin 
    uClinux-dist doesn't know anything about the Atcom. YMMV.
- If not part of uClinux-dist, check the application's website to see 
    if the application could be compiled to run on an MMU-less CPU like the 
    Blackfin. If there's no indication, give it a shot anyway to see if it compiles, 
    and test it extensively to see if it seems to run OK without leaking memory
- Check existing *.mk files as reference
- Check the application's home website for information on compiling/installing
- If you get run-time issues, download the latest toolchain, and use its 
    "ldd" to check which shared libraries the application needs, if 
    any, and make sure those libraries are available on the Atcom
- Use "#!/bin/sh -x" to debug post/pre inst scripts
- In case ipkg complains about MD5 mismatch: rm /usr/lib/ipkg/lists/snapshots
You can check what a Makefile does using "-d" (for "details"), 
-n" (dry-run), and both switches can be combined: Pretty useful to figure 
out how the whole thing works.
As of Jan 2011, information about ipkg 
is no longer available from the official source (www.handhelds.org/moin/moin.cgi/Ipkg), 
but you can learn more from its more recent variant opkg 
and by reading how it's used to build packages for the OpenWrt platform.
"An Opkg package is essentially a Debian package with fewer control 
fields. If you know how to make a Debian package, you should be well on your 
way. In general, a package is an ar archive containing a control tarball (text 
+ script), a data tarball (binaries), and a debian-binary file (which simply 
contains the string 2.0)" (source)
More information:
opkg-utils 
is no longer maintained
Compiling an application into an ipkg package
A Hello, world sample can be found at www.rowetel.com/blog/?page_id=456. 
It can then be compiled thusly:
    - Compile binary and create package
 make -f hello.mk hello-package
- Output can be found in tmp/hello/ and the ipkg package under /usr/src/baps/ipkg/
Here's an example of a .mk file to build a BAPS package for the Lua language:
    - #make -f lua.mk-  
    - #======== Common to all applications
    - include rules.mk-  
    - export CC = $(TARGET_CROSS)gcc- export CFLAGS = -DLUA_USE_LINUX -I$(UCLINUX_DIST) 
    -I/usr/src/uClinux-dist/staging/usr/include
 #Must first compile those 
    libraries
- export LDFLAGS = -Wl,-E -L$(STAGING_DIR)/usr/lib -lm -ldl -lreadline 
    -lhistory -lncurses-  
    - #======== Application-specific stuff
    - LUA_VERSION=5.0.2
    - LUA_DIRNAME=lua
    - LUA_DIR=$(UCLINUX_DIST)/user/$(LUA_DIRNAME)
    -  
    - TARGET_DIR=$(BUILD_DIR)/tmp/lua/ipkg/lua
    - PKG_NAME:=lua
    - PKG_VERSION:=$(LUA_VERSION)
    - PKG_RELEASE:=1
    - PKG_BUILD_DIR:=$(BUILD_DIR)/tmp/lua
    -  
    - #======== Compile application
    - all: lua
    -  
    - lua:
    -         make -C $(LUA_DIR)
    -  
    -         mkdir -p $(TARGET_DIR)/bin
    -         cp $(LUA_DIR)/lua $(TARGET_DIR)/bin/lua
    -         touch $(PKG_BUILD_DIR)/.built
    -  
    - #======== Build ipkg package
    - define Package/$(PKG_NAME)
    -         SECTION:=lang
    -         CATEGORY:=Languages
    -         TITLE:=Lua 5.0.2 interpreter
    -         DESCRIPTION:=\
    -         Just the interpreter.
    - endef
    -  
    - # post installation
    - $(eval $(call BuildPackage,$(PKG_NAME)))
    -  
    - lua-package: lua $(PACKAGE_DIR)/$(PKG_NAME)_$(VERSION)_$(PKGARCH).ipk
Creating and using a repository
Server
We'll assume the build host also runs the web server that will provide users 
with packages:
    - cd /usr/src/baps/ipkg
- ../scripts/ipkg-make-index.sh . > Packages
- Copy Packages at the root of the web server's document directory
Atcom
    - Edit /etc/ipkg.conf: src snapshots http://server
- ipkg update
- ipkg list
Using opkg instead of ipkg
Development of ipkg was abandonned around 2008, but opkg, used in the OpenWrt 
world, is alive and well and is compatible with ipkg.
To keep the application as small as possible, I decided to compile opkg-cl 
without Curl and OpenSSL. But in case you need to...
Compiling Libcurl
"Opkg by default tries to link against libcurl. If you don't have libcurl, 
or disable it at configure time, then you will need wget installed."
    - Download the latest Libcurl source code
- CC=bfin-linux-uclibc-gcc ./configure --build=i686-pc-linux-gnu --host=bfin-linux-uclibc
- make
- If you compile opgk-cl with shared libraries, on the Atcom, copy the 
    library to /lib
Compiling OpenSSL
Note: libcrypto.so.0.9.8 is 1.317.955 bytes and libssl.so.0.9.8 is 258.818, 
for a total of 1.576.773 bytes
OpenSSL is part of uClinux-dist, so the includes/libs should be available 
and you should only need to point opkg to those directories for a successful 
build:
    - /usr/src/uClinux-dist-2010R1-RC5# cp staging/usr/lib/libssl.so.0.9.8 
    /var/www/
- /usr/src/uClinux-dist-2010R1-RC5# cp ./staging/usr/lib/libcrypto.so.0.9.8 
    /var/www/
- On the Atcom, copy the libraries to /lib
Compiling opkg
Here's how to build opkg-cl without Curl, OpenSSL, and GPG:
    - svn checkout http://opkg.googlecode.com/svn/trunk/ /usr/src/opkg
- To avoid having to use an environment 
    variable, vi libbb/gz_open.c
 
 /* gz_use_vfork = (getenv("OPKG_USE_VFORK") 
    != NULL);*/
 gz_use_vfork = 1;
 
 If using the 2010 toolchain, which 
    can't be told to handle the above with a warning instead of an error.... 
    edit gz_open.c thusly:
 
 #define UCLINUX 1
 ...
 /* gz_use_vfork 
    = (getenv("OPKG_USE_VFORK") != NULL);*/
 gz_use_vfork = 1;
 ...
 #ifdef 
    UCLINUX
 //if (gz_use_vfork) {
 *pid 
    = vfork();
 #else
 //} else {
 *pid 
    = fork();
 //}
 #endif
 
- Add the toolchain to the PATH
- apt-get install glib-gettextize libglib2.0-dev libcurl4-openssl-dev 
    libgpgme11-dev
- ./autogen.sh
- CC=bfin-linux-uclibc-gcc CFLAGS="-I/usr/src/uClinux-dist-2010R1-RC5/linux-2.6.x/include" 
    LDFLAGS="-static" ./configure --disable-gpg --disable-openssl 
    --disable-curl ac_cv_func_malloc_0_nonnull=yes --build=i686-pc-linux 
    --host=bfin-linux-uclibc
- make
- Copy ./src/opkg-cl to the web server, and download + chmod this file from 
    the Atcom
- Make sure PATH is filled with the usual suspects, eg. /bin:/usr/bin:/sbin:/usr/sbin, 
    or you might get "pkg_run_script: package "xyz" 
postinst script returned status 255" when installing a package
- mkdir -p /usr/lib/opkg
- mkdir /etc/opkg
- vi /etc/opkg/snapshots.conf
 
 src 
    snapshots http://rowetel.com/ucasterisk/ipkg
 dest root /
 
- ./opkg-cl update
- ./opkg-cl list
No command to list files in uninstalled package?
Packaging an application with opkg
Note: The Section field is completely ignored by opkg. You can put whatever 
you want here. The Architecture field is free form, it can be whatever you want, 
but it must match one of the arch fields specified in your conf files. 
Manually
    - mkdir /usr/src/mypackage ; cd mypackage
- mkdir bin ; cd bin ; vi hello.c ; bfin-linux-uclibc-gcc hello.c -o hello
- cd /usr/src/mypackage
- vi debian-binary
 
 2.0
 
- vi control
 
 Package: opkg-hello (must match 
    package name, ie. package.opk?)
 Version: 0.0.1
 Description: 
    Sample OPKG package
 Section: cyanogenmod/applications
 Priority: optional
 Maintainer: 
    Jiang Yio
 Architecture: all
 Homepage: http://inportb.com/
 
 NO! 
    Note: Do not leave fields empty : "Malformed 
    package file package.opk"
 
- vi preinst
 
 #!/bin/sh
 echo "The name of this script is 
    \"$0\"."
 
 
- chmod +x preinst
- cp preinst postinst
- cp preinst prerm
- cp preinst postrm
- tar czvf control.tar.gz control preinst postinst prerm
- tar czvfP data.tar.gz ./bin/hello
- ar -r package.opk debian-binary control.tar.gz 
    data.tar.gz
- cp package.opk /var/www
- On Atcom, download and run:
 
 /var/tmp> wget http://server/package.opk
 /var/tmp> 
    ./opkg-cl install package.opk
 
With opkg-utils
http://svn.openmoko.org/trunk/src/host/opkg-utils/
Requires Python
With OpenWrt's Makefile
To read
Creating a repository
http://wiki.openmoko.org/wiki/Om_2008_Guide#How_to_add_a_Repository_.3F
http://wiki.openwrt.org/doc/devel/feeds
Resources
Changing options for Busybox in BAPS
    - Run "make -f uClinux.mk uClinux" once so it downloads the 
    uClinux-dist source
- cd uClinux-dist
- make clean
- cd uClinux-dist/user/busybox/
- make menuconfig, and choose options
- cd /usr/src/baps
- make -f uClinux.mk uClinux
- Reboot the Atcom with this new image, and check that it works OK
Compiling iptables
As iptables relies on settings in the kernel, you'll need to recompile the 
kernel to enable Netfilters.
In addition, some features (eg. the "recent" Netfilter module) 
were added in later versions, so you might need to use a more recent release 
than the 2007 version of the kernel used in the BAPS firmware.
More information here.
Adding OpenVPN to BAPS uClinux
OpenVPN is a more reliable way than STUN to let remote SIP clients connect to an Asterisk server 
through locked-down NAT routers.
A patch 
is required to modify the uClinux-dist source code to include OpenVPN before 
rebuilding an image; We must also build OpenVPN 2.0.9 package to provide the 
/bin/openvpn binary that will talk to the /dev/net/tun virtual interface.
Note: Since OpenVPN requires patching the kernel and compiling/installing 
a package, and a VPN burns CPU cycles which would be better left to Asterisk, 
you might want to simply locate the VPN on your router instead.
Here's how to apply 
the patch, build/test a new image, compile and test the OpenVPN package, and 
finally burn the new image in the Atcom:
    - cd /usr/src/baps
- wget http://www.rowetel.com/ucasterisk/downloads/openvpn_package.patch
- patch -p0 < openvpn_package.patch
- make -f uClinux.mk uClinux
- cp uClinux-dist/images/uImage /tftpboot/uImage
- On the workstation, start a TFTP server so the Atcom can download this 
    new image
- On the Atcom, use a serial cable, reboot the appliance to get into the 
    Uboot loader, and download and run the new image:
 
 ip04>set autostart
 ip04>set 
    bootargs ethaddr=your:mac:address root=/dev/mtdblock0 rw
 ip04>save
 ip04>tftp 
    0x1000000 uImage
 ip04>bootm
 
- Check that this new image contains a character device in /dev/net/tun, 
    write its live root filesystem to NAND (copy_rootfs.sh), and reboot 
    with "root=/dev/mtdblock2 rw"
- On the workstation, build the OpenVPN package:
 
 make -f libssl.mk 
    libssl
 make -f libssl.mk libssl-package
 make -f openvpn.mk openvpn-package
 cp 
    ipkg/libssl_0.9.8d-1_bfin.ipk /var/www
 cp ipkg/openvpn_2.0.9-1_bfin.ipk 
    /var/www/
 
- From the Atcom, download and install this new package:
 
 cd /var/tmp
 wget 
    -c http://workstation/libssl_0.9.8d-1_bfin.ipk
 wget -c http://workstation/openvpn_2.0.9-1_bfin.ipk
 ipkg 
    install libssl_0.9.8d-1_bfin.ipk
 ipkg 
    install openvpn_2.0.9-1_bfin.ipk
 
The package only includes a single binary /bin/openvpn, which can use configuration 
files but is unable to create a Certification Authority (CA) certificate and 
its key, and pairs of public/private keys for the server and clients. Those 
are needed to use OpenVPN with a Public Key Infrastructure (PKI).
Therefore, 
the next steps must be performed on the workstation before copying the files 
on the Atcom and the clients: 
    - On the workstation:
 
 apt-get install openvpn
 mkdir /etc/openvpn/easy-rsa
 cp 
    -R /usr/share/doc/openvpn/examples/easy-rsa/2.0/* /etc/openvpn/easy-rsa
 
- cd /etc/openvpn/easy-rsa
- Create the certificates and keys:
 
 #Make necessary changes
 vi 
    vars
 . ./vars
 
 ./clean-all
 ./build-ca
 ./build-dh
 
 #Use 
    unique Common names
 ./build-key-server server
 ./build-key client1
 
- Copy certificates + keys to www so server and client can fetch them:
 
 cd 
    /etc/openvpn/easy-rsa/keys
 cp ca.crt dh1024.pem server.crt server.key 
    client1.crt client1.key /var/www
 #So web server can send files
 chmod 
    644 /var/www/server.key
 chmod 644 /var/www/client1.key
 
- Create a configuration file for the server:
 
 vi /var/www/server.ovpn
 
 port 
    1194
 proto udp
 dev tun
 
 ca ca.crt
 cert server.crt
 key 
    server.key
 dh dh1024.pem
 
 server 10.8.0.0 255.255.255.0
 ifconfig-pool-persist 
    ipp.txt
 keepalive 10 120
 #Uncomment if compiled with compression
 #comp-lzo
 persist-key
 persist-tun
 status 
    openvpn-status.log
 verb 3
 
- Create a configuration file for the client:
 
 vi /var/www/client1.ovpn
 
 dev 
    tun
 proto udp
 remote <public IP to reach OpenVPN/Asterisk server> 
    1194
 resolv-retry infinite
 nobind
 persist-key
 persist-tun
 
 ca 
    ca.crt
 cert client1.crt
 key client1.key
 
 #comp-lzo
 verb 3
 
 
- On Atcom, download files and launch server:
 
 Asterisk> cd /etc/openvpn
 Asterisk> 
    wget http://workstation/ca.crt
 Asterisk> wget http://workstation/dh1024.pem
 Asterisk> 
    wget http://workstation/server.crt
 Asterisk> wget http://workstation/server.key
 Asterisk> 
    chmod 600 server.key
 Asterisk> wget http://workstation/server.ovpn
 
 #Let's 
    test
 Asterisk> /bin/openvpn /etc/openvpn/server.ovpn
 
- On Windows host, install the Windows 
    OpenVPN package, which includes a GUI, download the required files, 
    and try to connect to OpenVPN server:
 
 cd c:\program files\openvpn\config
 wget 
    http://workstation/ca.crt
 wget http://workstation/client1.crt
 wget 
    http://workstation/client1.key
 wget http://workstation/client.ovpn
 
 Start 
    OpenVPN Service
 Start OpenVPN GUI with Admin rights: Right-click on OpenVPN 
    GUI icon > Connect
 
 ping 10.8.0.1
 
- If ping OK, configure SIP client to connect to Asterisk through the 
    server's private IP used by the OpenVPN tunnel, eg. 10.8.0.1, and make a 
    call
- Edit Asterisk's sip.conf to add a "localnet" for the VPN:
 
 externip=<public 
    IP>
 #local extensions
 localnet=192.168.0.0/255.255.255.0
 #remote 
    extensions, through VPN
 localnet=10.8.0.0/255.255.255.0
 
- On Atcom, create /etc/init.d/openvpn script to start app at boot-time:
 
 #!/bin/sh
 # 
    Start up file for OpenVPN
 
 case $1 in
 #--daemon 
    not implemented
 start) 
    openvpn --cd /etc/openvpn --config server.conf&;;
 stop) 
    killall openvpn;;
 enable) 
    rm -f /etc/rc.d/S60openvpn;
 ln 
    -s /etc/init.d/openvpn /etc/rc.d/S60openvpn;;
 disable) 
    rm -f /etc/rc.d/S60openvpn;;
 *) 
    cat <<EOF;;
 Syntax: /etc/init.d/openvpn [command]
 Available 
    commands:
 start   Start 
    the service
 stop    Stop 
    the service
 enable  Enable 
    service autostart
 disable 
    Disable service autostart
 EOF
 esac
 
 Remember to "chmod 
    755 openvpn"
 
- Add symlink in /etc/rc.d/: /etc/init.d/openvpn enable
Note that I couldn't get SJPhone and Qutecom to work with the VPN: Either 
one-way audio or couldn't even register. Ekiga could register, but couldn't 
dial an extension. Try XLite/EyeBeam or Zoiper instead.
More information: Switching 
to a software PBX and Setting 
up a client
Adding items to Switchfin menuconfig
    - To add a new package to the Switchin Buildroot, start by creating a 
    directory for the application under /package/, eg. myapp/
- This directory must include two files: Config.in which describes the 
    option when you run "make menuconfig", and myapp.mk which contains 
    the Makefile that will be run to download, configure, build, and install 
    the application
 
 If a package lacks a Config.in file, it will not be 
shown as an option when running "make menuconfig" and will always 
be compiled and included in the image.
 
- Next, edit /package/Config.in and add this new application.
- Finally, write myapp/myapp.mk. The contents is different depending on 
    if the package is generic or based on Autotools.
- The actual source code of the application is located in build_ip01/uClinux-dist/user/ 
    if it is part of the uClinux-dist, or in package/sources/myapp/ if you provide 
    the application yourself.
You can tell an application uses a generic Makefile or an Autotools-based 
Makefile, based on whether it has a "configure" scripts, in which 
case it's Autotools.
Read:
Checking shared libraries
With ldd or readelf
The Blackfin toolchain already has a binary that you can run on the workstation 
to check which shared libraries an application depends on, if any:
    - bfin-linux-uclibc-ldd
- bfin-linux-uclibc-readelf
- bfin-uclinux-readelf
On the workstation, you can run this:
find ./romfs/bin -type f -print0 | xargs -0 bfin-linux-uclibc-ldd
I failed compile ldd.c for Blackfin (either from the generic uClinux-dist 
distribution or from source files found through Google), but compiling Binutils 
went far enough to get a working readelf:
    - cd /usr/src/uClinux-dist-2010R1-RC5/binutils-2.21
- CC=bfin-linux-uclibc-gcc ./configure --build=i686-pc-linux-gnu --host=bfin-linux-uclibc
- make
- cp binutils/readelf /var/www/
- find / -xdev -type f -print0 | xargs -0 ./readelf -d
With scanelf
uClinux provides neither ldd nor readelf, but scanelf from the pax-utils 
application compiles OK:
    - wget -c http://distfiles.gentoo.org/distfiles/pax-utils-0.2.2.tar.bz2
- tar xjvf pax-utils-0.2.2.tar.bz2
- cd pax-utils-0.2.2
- export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/opt/uClinux/bfin-linux-uclibc/bin
- make CC=bfin-linux-uclibc-gcc
- Copy scanelf to web server
- Download scanelf on Blackfin appliance
- > ./scanelf -qn myapp
Here's a script to build a list of shared libraries, and check all the binaries 
recursively to find if any library is unused:
Building a smaller image
    - Start by checking romfs/bin for applications you don't need.
- Next, run the script above to check that you don't uselessly pack shared 
    libraries in /lib that aren't used by any application.
- Strip binaries (any drawback?)
"Hello, word" for uClinux
Here's how to install the toolchain, and compile some test files as either 
FLAT or FDPIC ELF binaries, manually and through a Makefile.
Setting up tools
    - From the Blackfin 
    uClinux site, download the two versions of the toolchain (to compile 
    binaries as FLAT or FDPIC ELF):
 
 cd  /
 
 wget -c http://blackfin.uclinux.org/gf/download/frsrelease/501/8378/blackfin-toolchain-2010R1-RC4.i386.tar.bz2
 wget 
    -c http://blackfin.uclinux.org/gf/download/frsrelease/501/8386/blackfin-toolchain-uclibc-full-2010R1-RC4.i386.tar.bz2
 
- Untar the two packages, and edit the PATH env't variable:
 
 tar 
    xjvf blackfin-toolchain-2010R1-RC4.i386.tar.bz2
 tar xjvf blackfin-toolchain-uclibc-full-2010R1-RC4.i386.tar.bz2
 
 vi 
    /etc/profile
 export PATH=$PATH:/opt/uClinux/bfin-uclinux/bin:/opt/uClinux/bfin-linux-uclibc/bin
 
 source 
    /etc/profile
 echo $PATH
 
 which bfin-uclinux-gcc
 which bfin-linux-uclibc-gcc
 
 
- mkdir /usr/src/uclinux.test/
- cd /usr/src/uclinux-test/
Compiling an application 
Based on Simple 
Hello World Application Example
    - vi main.c:
 
 #include <stdio.h>
 
 int main(int argc, char **argv)
 {
 printf("Hello World\n");
 return 0;
 }
 
 Save 
    and exit
- To compile main.c as a FLAT executable:
 
 bfin-uclinux-gcc -Wl,-elf2flt 
    main.c 
    -o main
 
 file main: "BFLT executable - 
    version 4 ram"
 
- To compile main.c as an FDPIC ELF executable:
 
 bfin-linux-uclibc-gcc 
    -Wall main.c -o main
 bfin-linux-uclibc-strip main
 
 file main: "ELF 
    32-bit LSB executable, Analog Devices Blackfin, version 1 (SYSV), dynamically 
    linked (uses shared libs), stripped"
Note: To compile source code into an object file instead of an executable, 
use the "-c" switch: bfin-uclinux-gcc -Wall -c main.c -o main.o
Compiling a library
First, here's the source code for the library:
    - #bar.h
    - void mytestfunc(void);
    -  
    - #bar.c
    - #include <stdio.h>
    -  
    - void mytestfunc(void) {
    -         printf("In mytestfunc\n");
    - }
Next, here's how to modify main.c to include a call to the library:
    - #include <stdio.h>
    - #include "bar.h"
    -  
    - int main(int argc, char **argv)
    - {
    -         //mytestfunc() located 
    in libbar.a, ie. bar.c
    -         mytestfunc();
    -         return 0;
    - }
FLAT static
First, let's compile the library:
    - bfin-uclinux-gcc -Wall -c bar.c -o bar.o
    - bfin-uclinux-ar rcu libbar.a bar.o
    - bfin-uclinux-ranlib libbar.a
Next, let's recompile main.c to include libbar.a statically:
    - bfin-uclinux-gcc main.c -o main -L. -lbar -Wl,-elf2flt
FLAT (shared) NOT RECOMMENDED
FDPIC ELF (static)
    - bfin-linux-uclibc-gcc -c bar.c -o bar.o
    - bfin-linux-uclibc-ar rcu libbar.a bar.o
    -  
    - bfin-linux-uclibc-gcc main.c -o main -L. -lbar
    - bfin-linux-uclibc-strip main
FDPIC ELF (shared)
    - bfin-linux-uclibc-gcc -c bar.c -o bar.o
    - bfin-linux-uclibc-gcc -shared -Wl,-soname,libbar.so -o libbar.so bar.o
    -  
    - bfin-linux-uclibc-gcc main.c -o main -L. -lbar
    - bfin-linux-uclibc-strip main
    - bfin-linux-uclibc-strip libbar.so
On the target host, a shared library must be installed in locations where 
the system expects to find it, eg. /lib. How to check which 
locations uClinux looks for shared libraries?
Compiling libraries and executables through a Makefile
If the application uses "configure", you might need to use "CROSS_COMPILE=bfin-uclinux- 
./configure" and/or "CC=bfin-uclinux-gcc ./configure".
FLAT static
    - CROSS  = bfin-uclinux-
    - AR     = $(CROSS)ar
    - CC     = $(CROSS)gcc
    - RANLIB = $(CROSS)ranlib
    -  
    - CFLAGS       += -Wall
    - LDFLAGS_test  = $(LDFLAGS) -Wl,-elf2flt
    - LDLIBS_test   = $(LDLIBS) -L. -lbar
    -  
    - LIBS = libbar.a
    - BINS = test
    -  
    - all: $(LIBS) $(BINS)
    -  
    - libbar.a: bar.o api.o
    -         $(AR) rcu $@ $^
    -         $(RANLIB) $@
    -  
    - test: test.o
    -         $(CC) $(CFLAGS) -o $@ 
    $^ $(LDLIBS_$@) $(LDFLAGS_$@)
FLAT (shared) NOT RECOMMENDED
FDPIC ELF (static)
    - CROSS  = bfin-linux-uclibc-
    - AR     = $(CROSS)ar
    - CC     = $(CROSS)gcc
    - RANLIB = $(CROSS)ranlib
    -  
    - CFLAGS       += -Wall
    - LDLIBS_test   = $(LDLIBS) -L. -lbar
    -  
    - LIBS = libbar.a
    - BINS = test
    -  
    - all: $(LIBS) $(BINS)
    -  
    - libbar.a: bar.o api.o
    -         $(AR) rcu $@ $^
    -         $(RANLIB) $@
    -         
    - test: test.o
    -         $(CC) $(CFLAGS) -o $@ 
    $^ $(LDLIBS_$@) $(LDFLAGS_$@)
FDPIC ELF (shared)
    - CROSS  = bfin-linux-uclibc-
    - CC     = $(CROSS)gcc
    -  
    - CFLAGS            += 
    -Wall
    - LDFLAGS_libbar.so  = -shared -Wl,-soname,libbar.so
    - LDLIBS_test        = $(LDLIBS) -L. 
    -lbar
    -  
    - LIBS = libbar.so
    - BINS = test
    -  
    - all: $(LIBS) $(BINS)
    -  
    - libbar.so: bar.o api.o
    -         $(CC) $(CFLAGS) -o $@ 
    $^ $(LDLIBS_$@) $(LDFLAGS_$@)
    -         
    - test: test.o
    -         $(CC) $(CFLAGS) -o $@ 
    $^ $(LDLIBS_$@) $(LDFLAGS_$@)
Compiling the Lua interpreter
Note: If you rarely use the Lua interpreter in interactive mode, you can 
save space by not including libreadline: Just edit LUA_USE_LINUX in luaconf.h.
First, update the PATH env't variable to where the toolchain is located.
Next, edit /usr/src/lua-5.1.4/src thusly:
    - CC=bfin-linux-uclibc-gcc
    - LD=bfin-linux-uclibc-ld
    - AR= bfin-linux-uclibc-ar rcu
    - RANLIB= bfin-linux-uclibc-ranlib
    - RM=rm -f
    -  
    - BASE=/usr/src/baps
    - STAGING_DIR=$(BASE)/uClinux-dist/staging
    - UCLINUX_LIB=$(BASE)/uClinux-dist/lib
    - UCLINUX_ROOT_LIB=$(BASE)/uClinux-dist/root/lib
    -  
    - CFLAGS=-O2 -Wall -DLUA_USE_LINUX -I$(BASE)/uClinux-dist/linux-2.6.x/include 
    -I$(STAGING_DIR)/usr/include
    -  
    - LIBS= -lm -ldl
    - LDFLAGS=-Wl,-E -L$(STAGING_DIR)/usr/lib -L$(UCLINUX_LIB) -L$(UCLINUX_ROOT_LIB) 
    $(LIBS)
    -  
    - ...
    -  
    - uclinux:
    -         $(MAKE) all
Compiling SQLite3
autoconf version
./configure --build=i686-pc-linux --host=bfin-linux-uclibc target=bfin-linux-uclibc 
CC=bfin-linux-uclibc-gcc AR=bfin-linux-uclibc-ar RANLIB=bfin-linux-uclibc-ranlib 
CFLAGS="-O2 -Wall -I/usr/src/baps/uClinux-dist/linux-2.6.x/include" 
LFLAGS=-L/usr/src/baps/uClinux-dist/lib
make
The command-line client sqlite3, the shared library libsqlite3.so and the 
static library libsqlite3.a will be found in ./.libs/
amalgamated version
Unzip the SQLite source file, and create the following Makefile:
    - BASE=/opt/toolchain
    - CC=bfin-linux-uclibc-gcc
    - AR=bfin-linux-uclibc-ar rcu
    - RANLIB=bfin-linux-uclibc-ranlib
    -  
    - CFLAGS=-O2 -Wall -DSQLITE_THREADSAFE=0 -I.
    - -I$(BASE)/uClinux-dist/linux-2.6.x/include
    - LDFLAGS=-Wl,-E -L$(BASE)/uClinux-dist/root/lib -L.
    -  
    - all:
    -         @echo "No target 
    specified."
    -  
    - object:
    -         $(CC) $(CFLAGS) -c sqlite3.c 
    -o sqlite.o
    -  
    - static:
    -         $(CC) $(CFLAGS) -c sqlite3.c 
    -o sqlite3.o
    -         $(AR) libsqlite3.a sqlite3.o
    -         $(RANLIB) libsqlite3.a
    -  
    - shared:
    -         $(CC) $(CFLAGS) $(LDFLAGS) 
    -shared -Wl,-soname,libsqlite3.so
    - -o libsqlite3.so sqlite3.c
    -  
    - cli: static
    -         $(CC) -static $(CFLAGS) 
    $(LDFLAGS) -o sqlite3 shell.c
    - -lsqlite3 -ldl
    -  
    - clean:
    -         -rm -rf *\.a *\.o *\.so 
    sqlite3
Compiling LuaSQL for SQLite3
LuaSQL requires either the SQLite3 static library (libsqlite3.a) or just 
the object file (sqlite.o), and will generate sqlite3.so which contains both 
SQLite3 and some glue to access SQLite3 from Lua:
/usr/src/luasql-2.1.1/config
    - /usr/src/luasql-2.1.1/config-  
    - LUA_INC= /usr/src/lua-5.1.4
    -  
    - LIB_OPTION = -shared -Wl,-soname,$(LIBNAME)
    -  
    - DRIVER_INCS = -I/usr/src/sqlite-autoconf-3070601
    - #DRIVER_LIBS= -L/usr/src/sqlite-autoconf-3070601/.libs -lsqlite3
    - DRIVER_LIBS= /usr/src/sqlite-autoconf-3070601/sqlite3.o-  
    - CFLAGS= -O2 -Wall
 
 #assumes exported in PATH
 CC=bfin-linux-uclibc-gcc
/usr/src/luasql-2.1.1/Makefile
    
    - ...
    - AR= bfin-linux-uclibc-ar rcu
 RANLIB= bfin-linux-uclibc-ranlib
 
 src/$(LIBNAME): $(OBJS)
-         $(CC) $(CFLAGS) $(LIB_OPTION) 
    -o $@ $(OBJS) $(DRIVER_LIBS)
Compiling LuaSocket
Compiling lsof
lsof is not part of BAPS and Switchfin, but is available in uClinux-dist 
in the "Miscellaneous Applications" section.
However, it won't compile with the 2010R1-RC4 toolchain due to its use of 
fork(). Incidently, "netstat -natp" will display the name of the program 
that opened the port.
Compiling applications with MPU
While the Blackfin has no MMU, it offers a Memory Protection Unit (MPU) so 
that an application won't access RAM that doesn't belong to it.
https://docs.blackfin.uclinux.org/doku.php?id=uclinux-dist:difference_from_linux
https://docs.blackfin.uclinux.org/doku.php?id=bfin:mpu
http://elinux.org/UClinux_Shared_Library
Compiling Samba
Samba 3.0.25a is part of uClinux-dist, and here's how to compile a more recent 
release:
 
To check the version: smbd -V
To check where smbd expects to find smb.conf:
smbd -b | grep CONFIGFILE
Compiling Busybox
Some options you might want to enable:
    - Busybox Settings > Build Options > Force NOMMU build
- Busybox Library Tuning > Command line editing + Tab completion + 
    Fancy shell prompts
- Shells > Hush + options, including Process substitution
By default, uClinux-dist uses simpleinit (in Core Applications), instead 
of the one provided by Busybox. You might want to use Busybox's init so that 
you use its poweroff/halt/reboot which unmount partitions before rebooting.
Busybox uses a different format for /etc/inittab. Here's 
an example:
    - # /etc/inittab
    - #
    - # Copyright (C) 2001 Erik Andersen <andersen@codepoet.org>
    - #
    - # Note: BusyBox init doesn't support runlevels.  The runlevels 
    field is
    - # completely ignored by BusyBox init. If you want runlevels, use
    - # sysvinit.
    - #
    - # Format for each entry: <id>:<runlevels>:<action>:<process>
    - #
    - # id        == tty to run on, or 
    empty for /dev/console
    - # runlevels == ignored
    - # action    == one of sysinit, respawn, askfirst, wait, 
    and once
    - # process   == program to run
    -  
    - # Startup the system
    - console::sysinit:/bin/sh /etc/rc
    -  
    - # Set up a console shell
    - #Using "console" prevents use of job control, eg. CTRL+c
    - #console::respawn:/bin/login -f root
    - #Check which tty is in your kernel command line
    - ttyBF0::respawn:/bin/login -f root
    -  
    - # Misc services
    - null::respawn:/sbin/inetd -f
    - null::respawn:/sbin/watchdog -F -T 20 -t 10 /dev/watchdog
    -  
    - # Logging junk
    - null::sysinit:/bin/touch /var/log/messages
    - null::respawn:/sbin/syslogd -n -m 0
    - null::respawn:/sbin/klogd -n
    -  
    - # Stuff to do for the 3-finger salute
    - ::ctrlaltdel:/sbin/reboot
    -  
    - # Stuff to do before rebooting
    - null::shutdown:/bin/killall klogd
    - null::shutdown:/bin/killall syslogd
    - null::shutdown:/bin/umount -a -r
Information
Choose a file format for 
shared libraries: Shared FLAT, FDPIC ELF. Read how to create 
libraries.
Resources
Q&A
What is difference between host, build, and target?
http://gcc.gnu.org/onlinedocs/gccint/Configure-Terms.html
--build=i686-linux-gnu --host=blackfin-unknown-linux-gnu
How to remove unneeded Asterisk modules?
There's no sure-fire way to check which modules Asterisk need. Here's how 
to investigate:
    - Configure Asterisk to log messages
- Start Asterisk with enough -d and -v, and watch for error messages
- vi /etc/asterisk/modules.conf
 
 autoload=no
 
 (load modules 
    you think you need)
 
- Repeat until Asterisk stops complaining about missing modules.
What files do I need for a minimal Asterisk?
Use "readelf -d" to check which shared libraries a binary needs.
If you'd rather run readelf on the Atcom rather than on the workstation,
This is what you need when using SIP and Dahdi:
    - Shared libraries in /lib:
        - libdl.so.0
- libdl.so.2
- libpthread.so.0
- libncurses.so.5
- libm.so.0
- libresolv.so.0
- libgcc_s.so.1
- libc.so.0
- Shared libraries in /usr/lib:
        - libsqlite3.so.0
- libtiff.so.3
- libspeexdsp.so.1
- libtonezone.so.2.0
- libspandsp.so.2
- /bin/asterisk
- Configuration files in /etc/asterisk/
        - asterisk.conf
- logger.conf
- modules.conf
- sip.conf
- extensions.conf
- voicemail.conf
- Startup script: /etc/init.d/asterisk
- Modules in /usr/lib/asterisk/modules/
- AGI scripts go in /var/lib/asterisk/agi-bin/
- Sound files in /var/lib/asterisk/sounds/
- Voice-mail in /var/spool/asterisk/
- DAHDI
Read this:
www.wains.be/index.php/2008/04/15/slimming-asterisk-for-the-nslu2-under-debian/
To locate dependency errors, edit logger.conf full => notice,warning,error,debug,verbose
How to monitor the connection to a VoIP provider for quality?
FreeSwitch can be used for this. Does Asterisk offer this feature?
Busybox's ping doesn't stop with CTRL+c
Make sure /etc/inittab uses the "tty" mentionned in the kernel command 
line instead of "console". More information 
here.
How to restart an application that crashed?
/bin/watchdog
How to check network performance?
Compile and install iperf on a workstation and the Atcom to stress-test the 
network part.
Simple TCP test
On the server: iperf -s
On the client: iperf -c server.ip -t 30 -i 1
Simple UDP test
On the server: iperf -s -u
On the client: iperf -c server.ip -u -b 4m -t 30 -i 1
Multiple UDP threads
On the client: iperf -c server.ip -u -b 4m -t 30 -i 1 -P 4
Bigger MTU
On the client: iperf -c server.ip -w 128k -t 30 -i 1 -P4
Finding biggest MTU supported by network
On the server: iperf -s -m
On the client: iperf -c server.ip
On the server, check the line that says "MSS size XXXX bytes"
Checking VoIP performance
Datagrams are 32-byte long and the MTU buffer is 128k:
On the server: iperf -s -u -l 32 -w 128k
On the client: iperf -c server.ip -u -b 1m -l 32 -w 128k -i 1
Upload, and then download data
On the client: iperf -c server.ip -t 30 -i 1 -r
Upload and download data simultaneously
On the client: iperf -c server.ip -t 30 -i 1 -d
Why two versions of the toolchain?
Eg. bfin-uclinux-readelf vs. bfin-linux-uclibc-readelf?
Try compiling FLAT + FDPIC ELF hello, world, and try apps on them to see
Which version of uClibc does uClinux-dist include?
$ printf '#include \n__UCLIBC_MAJOR__ __UCLIBC_MINOR__ __UCLIBC_SUBLEVEL__\n' 
| bfin-uclinux-gcc -E - | tail -1
DHCP client crashes at reboot -> Busybox's udhcpc
Patching dm9000.c didn't help, so I dumped the default DHCP client and used 
udhcpc provided by Busybox.
Here's the init.d script to be called at boot time:
    - OPTIONS="-R -a -S -T 3 -A 1 -t 3"
    - INT="-i eth0"
    - PID="-p /var/run/udhcpc.eth0.pid"
    - SCRIPT="-s /etc/simple.script"
    -  
    - case $1 in
    -         start) rm -f /var/run/udhcpc.eth0.pid;
    -                udhcpc 
    $OPTIONS $INT $PID $SCRIPT;;
/etc/simple.script can be found here.
To ask udhcpc to renew its lease run "killall -USR1 udhcpc ; tail 
/var/log/messages".
How to check Switchfin patches
    - cd /usr/src
- svn co https://switchfin.svn.sourceforge.net/svnroot/switchfin/switchfin/trunk/ 
    switchfin
- cd switchfin
- find ./package/ -name "*\.patch"
Does Uboot know about the NAND partitions?
No, it's up to you to provide correct offset/length to match the partition 
settings in the NAND driver compiled in the kernel.
Generally speaking, what patches are required to run Linux apps on uClinux?
    - svn co http://server/somedistro 
    somedistro
- grep .patch package/* -rs | grep -v .svn
How to find what shared libraries are needed?
On the workstation
find ./romfs/bin/ -executable -type f -print0 | xargs -0 bfin-linux-uclibc-readelf 
-d | egrep "File|library"
On the Atcom
Note: Make sure Busybox supports "-xdev"
find /bin -xdev -type f -perm +111 -print0 | xargs -0 ./readelf -d
How to find unused libraries?
for n in romfs/lib/*.* romfs/usr/lib/*.*; do du -sh $n; nn=`basename $n`; 
find romfs/ -type f -print0 | xargs -0 grep -l $nn | grep -v $n | grep -v ld.so.cache 
| wc -l; done
Alternatively, run "make menuconfig", and in the "uClinux 
Distribution Configuration > Blackfin build options" menu, enable "Cull 
unused ELF shared libraries", ie. CONFIG_INSTALL_ELF_TRIM_LIBS.
When installing new applications that use shared libraries, you'll have to 
check that they are available in /lib or /usr/lib.
What are the different files in ./images/ or build_ipXX/image_ipXX?
    - vmlinux: Uncompressed kernel in ELF format. Uboot won't load it ("Bad 
    Magic Number")
- vmImage: Compressed kernel in ELF format to be loaded with Uboot
- rootfs.*: Root filesystem in different formats (ext2, initramfs, ubifs)
- uImage.*: vmImage + rootfs.*, eg. uImage.ext2 = vmImage + rootfs.ext2
If you just want to upgrade the kernel in the NAND, use vmImage.
Images are compiled through Mfg/Board/Makefile, which calls vendors/AnalogDevices/vendor.mak.
More information in uClinux-dist 
Compiled Images
"init: exec rc failed"
Things to try/check:
    - romfs/bin: Is there a symlink sh->(the shell)?
- Try either the BusyBox init or the stand-alone Core Applications init
- If you get "Bad inittab entry at line 11", check ./user/inetd/Makefile: 
    The Busybox init seems unable to process the simple inittab format used 
    by the stand-alone init "ttyline:termcap-entry:getty-command". 
    Try  "inetd::sysinit:/sbin/inetd". Also, the stand-alon e 
    init will process /etc/rc first and then execute the lines found in /etc/inittab
- "can't execute '/etc/rc.d/S10network': Permission denied": 
    chmod 755 /etc/init.d/network
Kernel stuck at "Starting Kernel at = "
Make sure you compiled uClinux for the ADSP-BF532 
CPU.
The Hush shell lacks some features
If some features are missing when running the Hush shell (no path completion 
through TAB, no command history through the up arrow, etc.), check the Busybox 
> Busybox Settings > Busybox Library Tuning section in "make config_menuconfig".
How to monitor applications?
I think there is a standard Unix application that can monitor 
if another application is running.  It might even be in uClinux-dist.  Can't 
recall it's name......
Is RAM fred when an application ends?
Not all RAM is freed immediately after an application ends, as VFS file buffers, 
network buffers, kernel data structures, etc. can linger in RAM for a while.
Worse, some kernel threads, kernel modules, and service daemons won't exit 
and free memory allocated until you force a reboot.
So it's a good idea to 1) run a watchdog to check for memory leaks, and 2) 
schedule a nightly reboot to make sure unused memory is returned to the kernel.
How to check SVN version of downloaded source?
svnversion
BAPS ignores my settings
When compiling a new kernel with BAPS and uClinux.mk, it can happen that 
the script rewrite configuration files and ignore your settings such as when 
compiling Netfilter/iptables in the kernel image.
Looks like it's done by copying patch/vendors/Rowetel/IP04/config.linux-2.6.x 
into uClinux-dist/vendors
A solution is to compile uClinux once the usual way (make -f uClinux.mk uClinux), 
and modify uClinux.mk to add your own, simpler target:
    - mytarget:
    -         $(MAKE) -C $(UCLINUX_DIR) 
    ROMFSDIR=$(TARGET_DIR)
    -         ./src/zeropad uClinux-dist/images/uImage 
    uClinux-dist/images/uImage_r2.ip08 0x20000
    -  
    - uClinux: $(UCLINUX_DIR)/.unpacked ./src/zeropad 
    -     $(TARGET_DIR)/usr/doc/uImage.txt
    -     mkdir -p $(UCLINUX_DIR)/vendors/Rowetel/IP04/
    -     cp -af patch/vendors/* 
    $(UCLINUX_DIR)/vendors
    -     $(MAKE) -C $(UCLINUX_DIR) 
    Rowetel/IP04_config
    -     $(MAKE) -C $(UCLINUX_DIR) 
    ROMFSDIR=$(TARGET_DIR)
    -     ./src/zeropad uClinux-dist/images/uImage 
   uClinux-dist/images/uImage_r2.ip08 0x20000
    
FXO is acting funny
If you make a lot of use of FXO/Zaptel during tests, it might act funny after 
a while, either displaying error messages (eg. "chan_zap.c:6406 ss_thread: 
Got event 18 (Ring Begin)..." instead of handling the call), or not making/answering 
calls at all.
In this case, just reboot the Atcom and see if this solves the problem.
How to convert sound files from WAV to Ulaw?
Two easy solutions:
On the workstation, use "sox". If you need to convert a whole directory:
for i in *.wav; do sox $i -r 8000 -c 1 $(basename $i .wav).gsm resample -ql; 
done 
On the Atcom, enter the Asterisk CLI and use this command:
ip04*CLI> file convert /var/tmp/myfile.wav /var/tmp/myfile.ulaw
Zaptel sometimes goes berzerk
After making a bunch of test calls, Zaptel stops reporting an incoming call:
    - root:~> /etc/init.d/asterisk stop
    - root:~> /etc/init.d/zaptel stop
    - rmmod: wcfxs: Resource temporarily unavailable
    - rmmod: bfsi: Resource temporarily unavailable
    - rmmod: zaptel: Resource temporarily unavailable
    - rmmod: oslec: Resource temporarily unavailable
Must wait a little while before being able to stop/start Zaptel and Asterisk.
[modules.conf] .c instead of .so
Samples on the Net use the .so extension, while the default modules.conf 
in the Atcom uses .c, using "noload" with a .c extension doesn't work, 
and renaming all items from .c to .so causes Asterisk to start... and die. You'll 
have to try each line separately until you know which module can be safely renamed 
from .c to .so.
Call files aren't handled by Asterisk
This is due to a bug in Yaffs2 not updating the timestamp on parent directories. 
Upgrade uClinux and see if the bug is gone.
If you can't upgrade, edit /etc/asterisk/asterisk.conf so that the spool 
directory is located in /var/tmp, and edit /etc/init.d/asterisk so that the 
start) part contains this:
    - if [ ! -d /var/tmp/asterisk/outgoing ]
    - then
    -         mkdir -p /var/tmp/asterisk/outgoing
    - fi
[BAPS] Why two Ethernet devices?
root:~> ifconfig
eth0      Link encap:Ethernet  HWaddr 00:09:45:56:72:9B
          inet addr:192.168.0.9 
 Bcast:192.168.0.255  Mask:255.255.255.0
          UP BROADCAST 
NOTRAILERS RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:10 
errors:0 dropped:0 overruns:0 frame:0
          TX packets:11 
errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 
txqueuelen:1000
                    Interrupt:48
 
eth0:9    Link encap:Ethernet  HWaddr 00:09:45:56:72:9B
          inet addr:192.168.100.30 
 Bcast:192.168.100.255  Mask:255.255.255.0
          UP BROADCAST 
NOTRAILERS RUNNING MULTICAST  MTU:1500  Metric:1
          Interrupt:48
Why use "asterisk -f &"?
-f : Foreground. Starts Asterisk but does not fork as a background daemon.
What are local files?
Asterisk only handles callfile when restarted
Moving a callfile 
to Asterisk's outgoing/ directory while Asterisk is already running doesn't 
trigger a call: A call will only occur if Asterisk is stopped, the file moved, 
and Asterisk restarted. uClinux has inotify enabled. No idea as to the cause 
of this problem.
Alternative ways to have Asterisk auto-dial out:
Fails compiling the Asterisk 1.4.4 package
"The existing menuselect.makeopts file did not specify that 'app_flash' 
should not be included.  However, either some dependencies for this module 
were not found or a conflict exists."
    - cd asterisk-1.4.4/ ; rm menuselect.makeopts
- cd ..; make -f asterisk.mk asterisk-package
Fails compiling the Asterisk 1.4.20 package
This .mk file actually downloads Asterisk 1.4.21.2
    - cd asterisk-1.4.21.2/ ; rm menuselect.makeopts
- vi 
    pbx/ael/ael_lex.c
- cd ..; make -f asterisk-1.4.20.mk asterisk-package
How to stress-test Asterisk?
What is the recommended way to stop Asterisk?
Instead of "kill", try "asterisk -rx "stop now".
How to enable Asterisk message logging
It might not be enabled by default, so you won't see any Asterisk-related 
messages in /var/log/messages.
Provided you have a syslogd server running:
    - vi /etc/asterisk/logger.con
 
 syslog.local0 => notice,warning,error
 
- Connect to Asterisk with "asterisk -vvvvvvvvvr"
- Tell Asterisk to reload its configuration with "logger reload"
- Exit console, and check "tail -f /var/log/messages"
How to restart crashed/rogue applications?
What solution is available to restart an application that crashed, or is 
causing memory fragmentation and must be restarted so uClinux can reorganize 
RAM?
How to disable LD_DEBUG?
env -u LD_DEBUG didn't work. Had to reboot
What modules do I really need?
By default, Asterisk loads all the modules located in /usr/lib/asterisk/modules/, 
unless told otherwise in modules.conf.
The problem is that there doesn't seem to be away to be positive a module 
is required or not for your Asterisk server to work OK, but here are modules 
you can problably avoid loading without a problem:
Using Asterisk' mini web server
By default, Asterisk supports a basic web server. Its configuration is located 
in /etc/asterisk/http.conf, and its docroot is /var/lib/asterisk/static-http/.
Note that documents can be reached through http://srv/static/.
Making sense of MTD
The Atcom uses the MTD 
device file to access the NAND flash memory.
Check the dmesg for a bit of information about MTD partitions:
    - Creating 1 MTD partitions on "RAM":
    - 0x00000000-0x00300000 : "ROMfs"
    - uclinux[mtd]: set ROMfs:EXT2  to be root filesystem
    -  
    - Generic platform RAM MTD, (c) 2004 Simtec Electronics
    - NAND device: Manufacturer ID: 0xec, Chip ID: 0xda (Samsung NAND 256MiB 
    3,3V 8-bit)- Scanning device for bad blocks
    - Creating 2 MTD partitions on "NAND 256MiB 3,3V 8-bit":
    - 0x00000000-0x00800000 : "linux kernel"
    - 0x00800000-0x10000000 : "file system"
In addition to two partitions in the NAND to contain a kernel and a persistent 
root filesystem, respectively, the kernel creates another MTD object in RAM 
to hold the RAM-based root filesystem attached to the kernel:
> cat /proc/mtd
dev:    size   erasesize  name
mtd0: 00300000 00001000 "ROMfs"
mtd1: 00800000 00020000 "linux kernel"
mtd2: 0f800000 00020000 "file system"
"ROMfs" contains the RAM-based root filesystem that you can use 
to boot a new Atcom appliance before writing this root filesystem onto the /dev/mtdblock2 
partition in the NAND.
How to access NAND from uClinux?
If the MTD commands are included, you'll need to either build an ipkg package 
or recompile a root filesystem or image to include the MTD applications.
What are entrypoints in "mount"?
When running mount, some of the entry points refer to kernel data structures, 
not physical devices.
What is /etc/index.html?
Alias ll='ls -al'?
How to check the hardware?
root:~> cat /proc/cpuinfo
root:~> cat /proc/meminfo
How to save space?
Replace FTPd + TelnetD with SSHd?
Remove DHCPd?
Remove Inetd?
Remove IPTables?
Remove rsh and rshd?
Remove rcp?
Remove unneeded Asterisk modules?
HTTPd?
root:~> ls -al home/httpd/
drwxr-xr-x    1 500      500          2048 
Mar  9  2008 .
drwxr-xr-x    1 500      500          2048 
Mar  9  2008 ..
drwxr-xr-x    1 500      500          2048 
Mar  9  2008 cgi-bin
What is OpenIPPbx?
Wiki by Atcom: www.openippbx.com
What is SwitchVoice?
"It was sometime in spring 2006 when a small Bulgarian group (now part 
of SwitchVoice Ltd.) started the BlackFin One project. It was a flexible general 
purpose Blackfin BF532 based development board. Both the schematics and PCB 
layout was open to the public which made the project pretty popular that time. 
The platform was ideal for SMB VOIP applications and it was first David Rowe 
(Rowetel) who saw its potential. David had already developed the 4FX (FXS/FXO 
interface card) and it was only a matter of months before we get complete analog 
BPX (IP04) ready. At that time we all were working as perfect team. We got great 
contribution from Mark who pointed the team to “build root” way of maintaining 
of the software (Astfin). Since then all of our Blackfn based products are Astfin 
driven and we are the major Astfin 2.1 contributor.
One year after we started the BlackFin One project, part of the Bulgarian 
team joined with Mark created a company uCpbx Ltd. 
The team under uCpbx Ltd. entity has developed family of Analog and Digital 
(PRI &BRI ) VoIP Appliances based on Blackin and Freescale PowerQUICC CPUs. 
Many external telecom. projects have been successfully designed as well.
During second half of 2009 the core development team decided to take a course 
for spin-out and this way avoid the management redundancy uCpbx Ltd. has created 
among the years.
The result is SwitchVoice Ltd. 
!"
Resources
Tools
Books and Tutorial
Sites
    - IP04 Four Port 
    IP-PBX (bunch of information to get started from IP0x author David Rowe)
- EdgePBX 
    ("Edgepbx is dedicated to provide Open Source Computer Telephony 
    hardware and software product.")
- Blackfin Linux Docs
- "uCdot is the place for all 
    things uClinux and Embedded Linux"
- "Cooperative Linux (short-named 
    coLinux) is a port of the Linux kernel that allows it to run cooperatively 
    alongside another operating system on a single machine"
- "uClinux is a set of patches 
    for linux to allow it to run on systems without an MMU 
    (memory management unit)."
- Getting started 
    with uClinux
- uCLinux on Blackfin processors 
    (Forum 
    for Asterisk on Blackfin)
- "uClibc (aka µClibc/pronounced 
    yew-see-lib-see) is a C library for developing embedded Linux systems. It 
    is much smaller than the GNU C Library, but nearly all applications supported 
    by glibc also work perfectly with uClibc. Porting applications from glibc 
    to uClibc typically involves just recompiling the source code. " (What 
    is the difference between uC-libc and uClibc)
- "Buildroot is a set 
    of Makefiles and patches that makes it easy to generate a complete embedded 
    Linux system. Buildroot can generate any or all of a cross-compilation toolchain, 
    a root filesystem, a kernel image and a bootloader image. Buildroot is useful 
    mainly for people working with small or embedded systems, using various 
    CPU architectures (x86, ARM, MIPS, PowerPC, etc.) : it automates the building 
    process of your embedded system and eases the cross-compilation process."
- OpenWrt 
    Buildroot and Creating 
    Packages
- "Switchfin 
    is an Open Source uClinux/Asterisk based distribution running on top of 
    Blackfin CPUs. [...] Switchfin is an branch of Astfin (astfin.org) telephony 
    uClinux/Asterisk based distribution. [...] At the beginning of 2010 me and 
    few colleagues I was working with, had become one of the major contributors 
    for Astfin 2.1 project. The project father Mark however has shared with 
    us that he wants Astfin to migrate a bit out of telephony area which is 
    not exactly what we see its future. We want to work on a purely telephony 
    oriented project and that's why we have created Switchfin." Switchfin 
    comes from the SwitchVoice people.
- "Astfin is a Blackfin 
    uClinux Asterisk distribution. The authors have used Buildroot to make the 
    very complex embedded build process very simple."
- VoIPTel (offers a GUI for the IPx series)
- (French) Ajouter 
    un package dans Buildroot en 5 minutes
- Busybox manpage 
    with options for each applet