How to cross-compile a Kernel for Matrix 504 module


This is intended to be used on a Linux system (I used a Ubuntu server 10.04 LTS)

Make sure your system is up to date.

This is not a total guide how to setup all the drivers to the Matrix, it is just a guide how to get things up and running. Then you are free to try on your own to make everything run smooth.

Italic text means commands to be written in linux console (bash)

Bold Italic means files to be used or other configuration data.


First of all you need to download some packages to start with:

Your system will need to have gcc, ncurses for host compiling, such as menuconfig.
You will need to use mkimage, just get it from

$sudo apt-get install mkimage



This toolchain was found on Matrix504 CD that was shipped with the module. (You could also get the version via Artila ftp page)


In my case I used the same kernel as that was already shipped with the Matrix module.
I later found out that 2.6.29 is the first version to support the AT91SAM9G20 to be found in the Matrix module.


Just to make things easier I used a configuration file from Linux4sam community.


I used for version 2.6.30, probably other version also works fine.

Which can be found here:


I then copied the files to the host machine and create a new folder to work in.
In my case I used my home folder to work in:

$mkdir /home/jonas/kernel

$cp /mnt/usb/linux- /home/jonas/kernel

Unpack the kernel:

$tar –xf linux-

You will now get a folder with the kernel.

To be able to compile files for ARM we need to install the toolchain.

To get all the directories in the right order I need to copy my toolchain to the root of the system

$cp arm-linux-gnueabi-4.3.3.tar.bz2 /

I then just did a unpacking of the toolchain

$tar –xf arm-linux-gnueabi-4.3.3.tar.bz2

Now we will have our toolchain installed, just to make sure everything is working try to write:


You should get the answer:

$arm-linux-gnueabi-gcc: no input file

If you get that message congratulations, you now have your toolchain up and working.

Kernel setup:

Now it is time to setup the kernel to work with our device:

Enter your kernel folder:

$cd /home/jonas/kernel/linux-

Then you copy the at91sam9g20ek_defconfig to this directory and also change the name on it.

$cp /mnt/usb/at91sam9g20ek_defconfig /home/jonas/kernel/linux-

Now we could either choose to run oldconfig or menuconfig to setup our kernel.
I prefer the menuconfig. Make sure to add ARCH=arm to setup your

$make ARCH=arm menuconfig

If everything compiles you will enter a menutree.

Now we just need to be sure that menuconfig gets the configfile we added. Check that we got the right type under:

System Type -> ARM system type (Atmel AT91)
System Type -> Atmel AT91 System-on-Chip->Atmel AT91 Processor (AT91SAM9G20)

You will also need to add support for UIBFS which is the default file system for this device.

Device Drivers -> Memory Technology Device (MTD) support

Enable to be included in the kernel (*).
Then enable:

Device Drivers -> Memory Technology Device (MTD) support -> UBI – Unsorted block images -> Enable UBI

We also need to activate support for filesystem via UBI:

Add these also:

File Systems -> Miscellaneous filesystems -> UBIFS file system support

To makes life easier we also add kernel debugging under Kernel hacking

Kernel hacking -> Kernel debugging
Kernel hacking -> Kernel debugging -> Kernel low-level debugging functions

Now exit from menuconfig and save the config.

But before we actually start the compiling we need to change the machine type to make the system to boot .

Since the AT91bootstrap that is included in the Matrix 504 module pass a machine number which does not match the machine number we now will compile for we just swap these values.

Enter the following folder

$cd /home/jonas/kernel/linux-

$more mach-types | grep at91sam9g20ek

You will find one matching number, at the end you will get a 4 digit number, this number has to be changed to 2294 which is the number for our Matrix 504 module. Use your favorite editor (I use nano)

Now we are ready to compile.

Compile Kernel

Now it is time for compiling, the most excited command in this guide:

$make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-

This will take a while so go grab a coffee or your favorite cola.

Hopefully everything went well, so now we have our kernel compiled in both uncompressed and compressed form.

Before the kernel is ready to be copied to the matrix module we need to wrap it in a special format to make sure the AT91 bootstrap can read the kernel and add it correctly to the internal memory.

$mkimage –A arm –O linux –C none –T kernel –a 20008000 –e 20008000 –n YourName –d /home/jonas/kernel/linux- /home/jonas/kernel/MATRIX504K

Now we should get a file with name MATRIX504K in our kernel folder. That is your kernel, packaged and ready to be transferred to the matrix module.

Transfer kernel to target

There is two way to transfer the kernel to our target. One way is via serial communication, the other way is to use TFTPD and command the Matrix module to download the new kernel to itself.

The last method is the fastest, but that also put a need to install a TFTPD on your computer.

Here is a method how to setup a TFTPD, totally copied from

1. Install tftpd and related packages.

$ sudo apt-get install xinetd tftpd tftp

2. Create /etc/xinetd.d/tftp and put this entry:

service tftp


protocol = udp

port = 69

socket_type = dgram

wait = yes

user = nobody

server = /usr/sbin/in.tftpd

server_args = /tftpboot

disable = no


3. Make /tftpboot directory

$ sudo mkdir /tftpboot

$ sudo chmod -R 777 /tftpboot

$ sudo chown -R nobody /tftpboot

4. Start tftpd through xinetd

$ sudo /etc/init.d/xinetd start

5. Testing. Tranfering file hda.txt from (Client using tftp) to (Server Get an example file to transfer (eg. hda.txt)

$ touch /tftpboot/hda.txt

$ chmod 777 /tftpboot/hda.txt

$ ls -l /tftpboot/

total 0

-rwxrwxrwx 1 davids davids 0 2006-03-27 23:04 hda.txt

$ tftp

tftp> put hda.txt

Sent 722 bytes in 0.0 seconds

tftp> quit

$ ls -l /tftpboot/

total 4

-rwxrwxrwx 1 davids davids 707 2006-03-27 23:07 hda.txt

Of course we need to change IP number to match the device or module we are using.

As default the matrix module will have as IP number and the module will search for a TFTP server.

Now copy your MATRIX504K file to /tftpdboot and make sure you have rights to read the file.

$cp /home/jonas/kernel/tftpdboot /tftpdbott

Now boot your Matrix module and press @, you will then enter a meny, choose to download from TFTPD

Your module will now try to connect to the TFTP server and grab the new kernel.

When the module has been flashed, then press R to reboot your system and enjoy your own kernel! :)

Serial downloading

If you don’t want to setup a TFPD you could transfer via serial communications, but that will take about 7-8 minutes (depending how large your kernel is) ( I used a windows computer for this part)

Start HyperTerminal and boot your device. Press @ to enter the boot menu.

Choose to download from serial.

Now the matrix will wait for data.

In HyperTerminal now choose Transfer in menu, and choose Send file. Choose MATIX504K and choose Kermit as a protocol.

Click SEND, now the transfer will begin. Grab a new cup of coffee.

How to setup Realtime-support for Matrix504


We need to use some sort of realtime support for our module, we therefore looked for a solution how to achieve that, we found that Xenomai was able to support realtime for our CPU (AT91SAM9G20).

Xenomai will use Adeos as a interface to achieve realtime support. This is in conjunction to RTAI made for flexible support for upgrades and hardware support at the cost for good performance. But since we do not have that high requirements on our realtime this will fit our needs.


First of all you need to download some packages to start with:

You will need the Xenomai package, I use the following:


You will also need Adeos, here I used a patch which was suited for my kernel (


And of course we need our kernel as before, I used the same as above, but you maybe want to keep the two versions along each other.


Here I assume that you already have compiled a ordinary version of the kernel so you are familiar with that

Xenomai setup

First a make a new folder to work in:

$mkdir /home/jonas/xenomai

Then I copied the kernel files to my directory that I just created:

$cp –R /home/jonas/kernel/linux- /home/jonas/xenomai

Now we need to unpack the xenomai package:

$tar –xf xenomai-

We then need to patch our kernel via following command:

$/home/jonas/xenomai/xenomai- --arch=arm --adeos=/home/jonas/xenomai/xenomai-* --linux=/home/jonas/xenomai/kernel-

Since we already have configure our kernel we do not really need to make any new configuration, but it could be a good check to see that everything looks okay before you start. Especially the Xenomai part is in the config.

Compile Realtime kernel

Just do as before and enter:

$/home/jonas/xenomai/linux- ARCH=arm menuconfig

If everything is okay we now will have Realtime support in the menu.

Exit and save the configuration.

Now we are ready to compile the kernel

$/home/jonas/xenomai/linux- ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-

Now we have our kernel with realtime support.

Run mkimage and copy your kernel to target and boot.

If everything went well you should now have a kernel with realtime support. Please check boot text and see if Xenomai is in the list and loaded correct.

Compile Realtime development environment

We now need to compile our development environment for Xenomai.

First we make a folder to work in.

mkdir /home/jonas/buildenv

cd /home/jonas/buildenv

We need to execute the following command:

$/home/jonas/xenomai/xenomai- --build=i686-pc-linux-gnu --host=arm-linux-gnueabi --enable-arm-mach=at91sam9 --enable-arm-tsc

This will make a check for our environment and make all the configfiles

Then make our environment folder.

mkdir /home/jonas/Xenomaienv

Now we want to compile and install the environment:

$make DESTDIR=/home/jonas/Xenomaienv install

Now everything is setup and ready! :)

Compile MyApp.c test application

I do have some problems with compiling my own written code for Xenomai.

It seems that I miss some library to get it to work.

After some tweaks I managed to compile, but it still not running on the target.

Will need to update this section when I got some example running.

Testexample that is in the /usr/xeonmai/bin library is working fine and I have now running the switch function for over 24h without any problem (the module itself has at the moment been up 3days without problems)