====== Cross Compile Environment for DNS-323 ======
===== Pre-compiled Binaries =====
If, for whatever reason, you cannot compile the source code below, pre-compiled binaries are available from the uClibc website [[http://uclibc.org/downloads/binaries/0.9.30.1/cross-compiler-armv5l.tar.bz2|here]] as of May 17th. You can also download a native compiler, to compile programs for the device, on the device [[http://uclibc.org/downloads/binaries/0.9.30.1/mini-native-armv5l.tar.bz2|here]]. The cross-compiler is around 55MB when unpacked, and the native compiler around 35MB.
To set up the build environment, you simply need to un-tar the files and add the necessary folders to the PATH:
For the cross-compiler ('user' is an example username):
cd /home/user
tar xjf cross-compiler-armv5l.tar.bz2
rm cross-compiler-armv5l.tar.bz2
export PATH=/home/user/cross-compiler-armv5l/bin:$PATH
Then you would compile programs with armv5l-tool, e.g. armv5l-gcc
If you are using configure/make programs, you will need to follow the documentation for cross-compilation. You will also want the programs to be installed in a different directory from /usr/local so you can copy them later. For GNU and compatible programs, it is usually this:
export CC=armv5l-gcc
./configure --host=arm-unknown-linux --prefix=/home/user/arm # example directory
make
make install
For the native compiler:
cd /mnt/HD_a2
tar xjf mini-native-armv5l.tar.bz2
rm mini-native-armv5l.tar.bz2
export PATH=/mnt/HD_a2/mini-native-armv5l/usr/bin:$PATH
Then you would compile programs simply with the normal tool name e.g. gcc
Oh, I might point out, these images actually use newer versions of the source components than D-Link used.
==== __cxa_atexit error ====
You might get this error when using make with the native compiler. You can either download a patched version here: {{:download:make.gz}} or recompile make, adding the following line to main.c after the includes:
int __cxa_atexit(void (*func) (void *), void * arg, void * dso_handle){}
==== Cross vs Native compile ====
Since the DNS-323 has only a 400MHz processor, configuring and compiling programs can be a slow process, usually slow enough that you won't be able to just sit there while it processes, but not so slow you have to do something else entirely or leave it on overnight. Native compiling has the advantage of building programs that exactly match the specifications of the device, only linking to libraries that are present, and warning of any errors properly.
A cross-compiler takes advantage of your PC's CPU, meaning that it will work a lot faster, however the end result might not work 100% on the device. You also need to ensure that the program you are compiling is properly configured for cross-compilation to ARM devices.
An ideal solution would be to emulate the DNS-323 architecture and kernel, but at much faster speeds. I haven't managed to do this with qemu, it is just as slow as the device itself.
Usually the best solution, if you are compiling large programs, is to construct your own configuration file, check all the dependencies manually, ensure libraries are linked dynamically, then cross-compile it.
===== Firmware 1.05 =====
This was done with http://tsd.dlink.com.tw/temp/download/3034/dns323_GPL_v1.05_05052008.tgz .
Untar this tarball. You should find another one inside which holds the actual source. Untar that one as well.
wget http://tsd.dlink.com.tw/temp/download/3034/dns323_GPL_v1.05_05052008.tgz
tar zxvf dns323_GPL_v1.05_05052008.tgz
cd dns323_GPL
tar zxvf dns323_GPL.tgz
cd dns323_GPL
==== Host build environment ====
This was done with
* gcc (GCC) 3.4 (Ubuntu 3.4.6-6unbuntu2)
* bison (GNU Bison) 2.3
* flex 2.5.34
* gettext (GNU gettext-runtime) 0.17 (0.16.1 also works)
* and some small utilities like: make, bzip2, libncurses5-dev, patch
To install these using apt do something like
sudo apt-get install gcc-3.4 bison flex gettext make bzip2 libncurses5-dev patch
If you are using ubuntu 9.04 you should set an symbolic link, since the build of the toolchain will be done using ''/usr/bin/gcc''. If this is the default ubuntu gcc (for ubuntu 9.04 it is 4.3) then the build fails.
sudo rm /usr/bin/gcc
sudo ln -s /usr/bin/gcc-3.4 /usr/bin/gcc
Now you are ready to build the toolchain, but dont forget to set a symbolic link back to ''/usr/bin/gcc-4.3'' when it's finished.
==== Toolchain ====
The toolchain didn't quite compile out-of-the-box…
note (2009-10-24) Somebody should note where to get the tarball for uclibc described below?
-> As for me, the tarball was found inside the downloaded file (dns323_GPL.tgz).
# untar everything
tar xzf uclibc-toolchain-src-20040609.tgz
cd uclibc-toolchain-src-20040609/gcc-3.3.x
# fix broken link
#sed -i.old -e 's%ftp://ftp.gnu.org/gnu/gcc/releases/gcc-%ftp://ftp.gnu.org/gnu/gcc/gcc-%' -e 's/gdb //'
#
# above link to ftp-site refuses to connect, http-site would answer
sed -i.old -e 's%ftp://ftp.gnu.org/gnu/gcc/releases/gcc-%http://ftp.gnu.org/gnu/gcc/gcc-%' -e 's/gdb //' make/gcc-uclibc-3.3.mk
# fix linux headers versioning
sed -i.old -e 's/UTS_RELEASE \\"2\.4\.21\\"/UTS_RELEASE \\"2.6.12.6-arm1\\"/' -e 's/LINUX_VERSION_CODE 132117/LINUX_VERSION_CODE 132620/' make/kernel-headers.mk
# do not build gdb.
# building gdb did not work for me. you might want give it a shot, if you really need the debugger..
# to do so just leave out these steps. if it fails, just retry from this point
sed -i.old 's/gdb #ccache$/# gdb #ccache/' Makefile
mv make/gdb-uclibc.mk make/gdb-uclibc.mk.dontinclude
# build a clean toolchain
# if some error occurs, try to fix it, drop a note somewhere and redo these two steps
make dirclean
yes "" | make
Voila, you just have built your cross-compiler.
Note: this does not compile with gcc-4.2, but works with gcc-3.4
==== Setting up build environment for cross-compiling ====
Use crosstools-env.sh, which is in [http://www.inreto.de/dns323/source/fw103-scripts-0.3-2007-07-29.tar.bz2], and fix the CWD variable to suit your needs.
Now you should be able to compile whatever you need.
For example:
# create a directory for this and copy all the files that you need there
mkdir ~/arm
cd ~/arm
# copy the toolchain_arm directory here. The directory is something like: dns323_GPL/dns323_GPL/uclibc-toolchain-src-20040609/gcc-3.3.x/toolchain_arm
cp -R $PATH_TO_DNS323_toolchain_arm .
# get the crossentools-env.sh with bunch of other stuff. We only need crosstools-env.sh
wget http://www.inreto.de/dns323/source/fw103-scripts-0.3-2007-07-29.tar.bz2
tar xvjf fw103-scripts-0.3-2007-07-29.tar.bz2
cp fw103-0.3/crosstools-env.sh .
This is what crosstools-env.sh looks like
#!/bin/sh
#CWD=$(pwd)
#CWD=/opt/dns323/fw103-0.3
CWD=/home/dns323_GPL/dns323_GPL/uclibc-toolchain-src-20040609/gcc-3.3.x
# I've changed this line:
#export CROSSTOOLS=$CWD/crosstools/gcc-3.3.x/toolchain_arm
# to:
export CROSSTOOLS=~/arm/toolchain_arm
# compile-time
export PATH=$CROSSTOOLS/bin:$PATH
export BUILD="-Os -mtune=arm9e -march=armv5te"
export CROSS_TARGET=arm-linux-uclibc
export CC="${CROSS_TARGET}-gcc"
export CXX="${CROSS_TARGET}-g++"
export AR="${CROSS_TARGET}-ar"
export AS="${CROSS_TARGET}-as"
export LD="${CROSS_TARGET}-ld"
export RANLIB="${CROSS_TARGET}-ranlib"
export READELF="${CROSS_TARGET}-readelf"
export STRIP="${CROSS_TARGET}-strip"
Now, to compile your own program, do:
# bring the environment variables from crosstools-env.sh into our current shell
source crosstools-env.sh
# check the CC environment variable has been set
echo $CC
# output should be: arm-linux-uclibc-gc
# create a sample hello-world program:
echo '#include
int main()
{
printf("Hello, World\n");
return 0;
}' > hello.C
# now compile it
$CC -O2 hello.C -o hello
#or
arm-linux-cc -O2 hello.C -o hello
# now copy the hello executable to your DNS-323, and try it there
===== Firmware 1.06 =====
For firmware 1.06 all you have to do is get another tarball from ftp://ftp.dlink.com/GPL/DNS-323/106/dns323_GPL_v1.06_12032008.tgz
# get and unpack toolchain files
wget ftp://ftp.dlink.com/GPL/DNS-323/106/dns323_GPL_v1.06_12032008.tgz
tar zxvf dns323_GPL_v1.06_12032008.tgz
cd dns323_GPL
tar zxvf dns323_GPL.tgz
cd dns323_GPL
then continue with instructions for firmware 1.05 above.
- didn't work for me, it generated "32-bit, no machine" executables, which of course, can't be executed on i686.
# workaround (just remove --build= and --host= from ./configure options):
sed -i.old 's/--build=$(GNU_HOST_NAME) \//g' make/gcc-uclibc-3.3.mk
sed -i.old 's/--host=$(GNU_HOST_NAME) \//g' make/gcc-uclibc-3.3.mk
# for binutils too
sed -i.old 's/--build=$(GNU_HOST_NAME) \//g' make/binutils-uclibc.mk
sed -i.old 's/--host=$(GNU_HOST_NAME) \//g' make/binutils-uclibc.mk
__Note:__ to compile (optware-)packages for the DNS323, the correct **./configure** parameter is **-- --host=arm-linux-uclibc**. at least that worked for me...
__Another note:__ i set this up with ubuntu 9.04 in a virtual machine (vmware, any other flavour should do too) and did a snapshot of the working environment. gives me a fully operational and (in a certain way) portable solution for cross compiling.
__And yet another note:__ For 1.6, you need also to comment out or remove the 'gdb' target in gcc-uclibc-3.3.mk, i.e. before making, run:
sed -i.old 's/gdb//' make/gcc-uclibc-3.3.mk
===== Firmware ?.?? =====
**Please feel free to update, cleanup or correct this page**
**Note**: The **wget-gpl** script now no longer works: instead the GPL directory has a readme file redirecting you [[http://www.dlink.com/support/gpl/|here]]. The actual GPL files are found [[ftp://gpl.dlink.com/|here]], with the DNS-323 specific file [[ftp://gpl.dlink.com/DNS-323/dns323_GPL_v1.08_12182009.tgz|here]] as of May 10th. Simply copy this file into GPL/zips and continue.
What is this?
This document shows how to build the D-LINK DNS-323 GPL
toolchain, kernel and u-boot loader
**Things you will need first**
* Development System x86-based Debian-based [[http://releases.ubuntu.com/6.06/|Ubuntu Linux "Dapper Drake" (6.06)]]
* You will need the following tools: **bison flex gcc-3.4 byacc g++-3.4 gettext patch**
* Check your active compiler version with **gcc -v**
* If your compiler is newer then gcc-3.4 then change the /usr/bin/gcc symlink to point to **/usr/bin/gcc-3.4** for building the toolchain - **restore it when you are done**
* If g++ is newer than version 3.4 also change the /usr/bin/g++ symlink accordingly.
* Make sure **libncurses5-dev** is installed or you'll get termcap not found error
* Create a directory to build your source in
mkdir GPL
* Create a directory to download the sources into
mkdir GPL/zips
* Change into the GPL directory
cd GPL
* Download and extract my {{howto:build_dns323.tgz|build_dns323.tgz}} the GPL directory
tar xzf build_dns323.tgz
* Download the GPL sources:
./wget_GPL
* Build the **ARM UCLIBC toolchain**
Fix the bug in the script **build_uclibc**: on line 24, replace .tar.gz with .tgz (obviously the extension of the tarballs changed)
The path to the gcc sources has changed, so we need to fix it:
tar xzf zips/uclibc-toolchain-src-20040609.tgz
edit the file: uclibc-toolchain-src-20040609/gcc-3.3.x/make/gcc-uclibc-3.3.mk
Change the so that the path defined on line 23 reads:
\\
\\ GCC_SITE:=ftp://ftp.gnu.org/gnu/gcc/gcc-$(GCC_VERSION)
\\ - note: I could not access the ftp server, but http://ftp.gnu.org/gnu/gcc/gcc-$(GCC_VERSION) worked fine. -- badwolf April 09
\\
\\ Now, since we have already uncompressed the tar file, we comment out lines 23 and 24 of build_uclibc by adding a # to that start of each line.
\\ Save the modified file, then run the script:
./build_uclibc
And now you must fix your symlinks. cd to $GPL/uclibc-toolchain-src-20040609/gcc-3.3.x/toolchain_arm/arm-linux-uclibc/lib and fix all broken links:
for lib in crypt dl m nsl pthread resolv rt thread_db util; do ln -sf lib${lib}-* lib${lib}.so; done
ln -sf libuClibc-0.9.28.so libc.so
**Note** For each build script below - extract the corresponding file from the zips directory. Example:
tar xzf zips/linux-2.6.12.6.tgz
This creates a directory called **linux-2.6.12.6** that **build_kernel**
knows about.
* Build the **ARM kernel**
fix bug in script **build_kernel**: on line 5, replace linux-2.6.6 by linux-2.6.12.6
./build_kernel
* Build the **u-boot loader**. The script defaults to u-boot_1_1_1, but newer boxes use 1.7.3 - If you want to do so, you have to change the directory in the build_u-boot file accordingly and remove all .depend files from the u-boot_1_7_3 directory and its subdirectories.
./build_u-boot
* Build **busybox**
The script needs a change; add line **export CC=arm-linux-gcc**, then execute.
./build_busybox
* Build **at**
./build_at
**Notes:**
The **./build_uclibc** script creates a script called **setpath** that can be used
to compile other **ARM uclibc** programs later on.
Many of the remaining D-LINK sources have not been configured for being cross-compiled. In fact, the "Readme.txt" file they supply with the GPL sources has instruction that are just plain wrong.