Cross-Compile For It (Part 1)
Cross compile – Patch – Test – Cross compile
If you are a Linux user then you most probably use a Linux distribution that allows you to get the package that you need. Compiled for your version of the OS, for your architecture and ready to run. In the embedded Linux unfortunately the things are a bit different. Either due to lack of resources from the makers of your devices or because of their desire to prevent you from improving it without their consent.
Cross-Compiling
That means that I have to compile the code that I need for the camera that my friend brought . That camera has 2MB space and a bit of RAM but that is far from being enough to even copy the source code of the application. Which brings us to the topic of cross-compiling. Cross compiling generally speaking allows us to compile the source code on one architecture, which we will call host, for another which we will call target. Host is my computer and target is the camera. My host is quite powerful and has enough disk space and RAM to compile any code. But it has an Intel processor and it does not have the same version of the compiler or the binary tools needed for the target. Not to mention the version of the Linux kernel. Which means that I will have to compile myself binary tools, C compiler, C library and optionally a kernel for the target. And finally the versions of these tools have to be the same or very close to what the target device is using.
Cross-Compilation Toolchain
A cross-compilation tool chain is the collection of those binary tools, C compiler, library and so on that I have mentioned in the previous paragraph. Creating a toolchain for our target is not an easy job. And it requires a lot of knowledge. Thanks god we are not the first one to face that challenge so there are already existing tools that can help us configure a toolchain and run the compilation of all these tools that we need. But beware – for your device you may face there are still dependencies that are difficult to solve with our modern day operating systems.
Development Environment
The major hurdle is that a GCC compiler version 3, as the one that was used on my friend’s camera, can be compiled from source only with very early versions of GCC 4 compiler. I made a quick research and found out that I can use Ubuntu 10.4 and on it get an early version of GCC 4 with which I can compile the toolchain. Because I did not want to wipe out my up-to-date Linux OS with some outdated one and I did not want to mess with my C compiler I decided to create a separate environment where I can make my experiments. Using Virtual Box I was able to create a new virtual machine(VM) and install Ubuntu 10.4 on it. In it I installed the applications needed for development:
sudo apt-get install gcc-4.1 g++-4.1 build-essential libncurses5-dev git-core flex bison
And updated the alternatives for Ubuntu to set gcc-4.1 as default compiler.
In order to continue we should be ready with the answers for the following questions about our device.
- What C compiler is used and which version?
In my case I have gcc version 3.4.6 - What lib C is used and which version?
I have uclibc and the version is most probably 0.9.28 - What CPU you have and which version, revision and enabled flags?
I have ARM926EJ-Sid(wb) rev 5 (v5l). So I can say for sure that I have an ARM processor but I had to research more to find out exactly which one. I searched for “arm926ej-sid” which gave me some hints (1, 2) and it turns out that I have arm5te architecture with arm926ej-s as a tuning parameter. - What is the binary executable format that the applications on the device have?
I have “ELF 32-bit LSB executable, ARM, version 1, dynamically linked (uses shared libs), stripped” - (Optional) Do you have busybox and if yes then which version? That is needed only if you want to compile your own busybox.
If you are not able to answer these questions make sure to read the previous article Know Your Device because without these answers you cannot go further.
Once I was ready with the VM I had to find the right toolchain or event better a SDK for that camera. And I had to either find a ready for development toolchain / SDK or had to try to build one with the help of tools like buildroot or crosstool-ng. There is the theoretical third option to build myself my own toolchain but you should consider this option if you have a lot of time to waste. I am talking about weeks here if you are not advanced C programmer.
The chances of having a toolchain/SDK for you no-name camera are quite slim. Nevertheless there are websites like wikidevi.com that have some information and it is worth checking there.
For me this website did not help, so I had to search in Internet for a toolchain suitable for the system. The search terms containing the executable format “toolchain ELF 32-bit LSB executable, ARM, version 1, dynamically linked (uses shared libs), stripped” took me to the right track. And with a bit of luck I found out something that proved to work. Compiling and setting up this toolchain was done using the following commands:
git clone https://github.com/juergh/toolchain_arm.git cd toolchain_arm make # And when the compilation was ready I had to activate this toolchain with source toolchain_arm/build-env
In the cases where you cannot find a ready toolchain you can try to build one using buildroot. Buildroot is an open-source toolchain, or a configurator for creating such, that allows you to choose what you want to compile and for which architecture. Buildroot can be downloaded from http://buildroot.org/downloads/.
Buildroot has a lot of versions that are available for download. What you need to do is to find the right one for you or try to configure the latest one for your needs. In order to start the configuration of buildroot you have to type
cd <path/to/buildroot/> make menuconfig
This will pop up a text configuration dialog similar to the one that you can see if you compile yourself a Linux kernel.
And then you have to choose the right configuration. In my case even the oldest buildroot package ( buildroot-2009.02-rc1.tar.bz2 ) was having higher version of uclibc and the kernel than the one that I needed. That’s why I decided to go with the already existing toolchain that I have found.
In part 2 of this article I will explain you how you can compile programs using your toolchain.
Stay tuned and check this website frequently.