Linux on ARM

ARM (and Movial) has published a new site that provides Open Source components, middleware and utilities used to build a Linux Mobile software stack on ARM.

All components (applications, libraries, etc) are in GIT repositories. The build tool is called Matrix. Matrix clones all components under one directory and compiles them with a single command. With another command you get JFFS2 image although that’s not as simple as it should be.

ARM would like to get all contributions directly to upstream instead of providing large code dumps and states that developers are encouraged to participate in discussion forums and developer community of respective components used on this site. That’s why there are no new mailing lists nor forums available for the platform. There is #matrixhelp (#matrix was taken) on irc.ipv6.oftc.net for Matrix related issues though. Developing the components is convenient if you are familiar with GIT. It’s easy to test if your patch works and send it to the upstream project.

One of the supported hardware platforms is n8x0 which is nice as it’s commonly available. The downside is the closed source nature of it. There are two projects, example-project and Kaze that has n8x0 configured as one target platform. Kaze has XFCE desktop instead of Matchbox desktop that the example-project uses.

Kaze boots but most features need still work. WLAN works without encryption but WEP and WPA encryptions need to be fixed. ALSA works with alsa plugins through the DSP but the closed source DSP tasks need to be copied to the build system. Kaze has normal X.Org instead of Xomap, so there’s no XV extension, only stubs.

2.6.25 and BT working on Gumstix

I finally got the Bluetooth working with my Gumstix running 2.6.25 and my linux setup. My patches are against two weeks old kernel but hopefully apply to current HEAD too. The patches include my kernel config: gumstix-verdex-bt.config too.

I had to configure the BT hardware using pxaregs and /prog/gpio in my startup scripts (copied from some OE image):


echo -n "Starting 32kHz clock..."
/usr/sbin/pxaregs OSCC_OON 1
while /usr/sbin/pxaregs OSCC_OOK | tail -n 1 | grep -q -v 1;do
echo -n '.'
sleep 1
done
echo "Settled"

/sbin/modprobe gumstix_bluetooth
/sbin/modprobe proc_gpio

echo "AF3 out" > /proc/gpio/GPIO9

echo "AF1 in" > /proc/gpio/GPIO42
echo "AF2 out" > /proc/gpio/GPIO43
echo "AF1 in" > /proc/gpio/GPIO44
echo "AF2 out" > /proc/gpio/GPIO45

I also had to patch my hciattach from bluez-utils 3.29. Those patches are here.

UBIFS and Gumstix

I wanted try something other than JFFS2 as the rootfs and decided to go with UBIFS. Thanks to GIT’s brilliance I had no trouble pulling the UBIFS kernel patches from their tree to mine.

It seems that the UBIFS hasn’t had many NOR flash users before me and it needed some fixes. Artem Bityutskiy was extremely helpful in fixing the deficiencies and helping me out. After a few debug rounds I now have UBIFS root on my Gumstix.

I created the UBIFS image with the following commands:


sudo mkfs.ubifs --compr=zlib -r /tmp/rootfs -m 1 -e 130944 -c 120 -o ubifs.img
ubinize -o ubi.img -m 1 -p 128KiB -v ubinize.cfg

With this ubinize.cfg:


[ubifs]
mode=ubi
image=ubifs.img
vol_id=0
vol_size=13MiB
vol_type=dynamic
vol_name=rootfs
vol_alignment=1
vol_flags=autoresize

Note that I have reserved 2MiB for the kernel partition.

I had to add one extra parameter to the kernel args to specify what MTD partition I wanted to use:

console=ttyS0,115200n8 root=ubi0:rootfs rootfstype=ubifs reboot=cold,hard ubi.mtd=1

Now my Gumstix boots with simplified kernel to busybox shell in roughly 4.2 seconds (counted from the bootm command in U-Boot).

2.6.25 running on Gumstix

I had to add a new category after all: gumstix. The embedded word has too broad a meaning.

Updating the kernel wasn’t such a big thing after all, even for a kernel n00b like me. I git cloned the vanilla tree from kernel.org and patched the generic (and one bluetooth) Gumstix patches from OE: arch-config.patch, board-init.patch, header.patch, mach-types-fix.patch, modular-init-bluetooth.patch, tsc2003-config.diff, tsc2003.c, and uImage-in-own-partition.patch. Most of them applied fine, I just had to manually apply simple Makefile patches and change pxa_init_irq call to pxa27x_init_irq.

I don’t know if it really works, but at least it booted:


root@gumstix-custom-verdex:~$ uname -a
Linux gumstix-custom-verdex 2.6.25-rc8-00151-gdc41023 #2 Fri Apr 4 23:43:25 EEST 2008 armv5tel unknown

Gumstix

It’s time to create a new category in my projects blog: embedded.

I got interested in microcontrollers some years ago and wrote something simple for 16F88 with assembler. Then I connected it to an old IPAQ using a serial connection. But the IPAQ isn’t a very good development platform so now I decided to buy a gumstix.

Gumstix Verdex

It’s 400Mhz verdex mainboard with 64M RAM and 16M flash. And a bluetooth. The mainboard is the smaller board upside down in the picture. The bigger board is a expansion board including 3x rs232, power plug, a USB mini-B connector and a bunch of GPIO lines.

The bootloader is U-Boot and the Linux distribution is based on OpenEmbedded. U-Boot is nice as I’m somewhat familiar with it but the OE I’m going to replace with something else.

I just booted it up to see how it looks inside:


cat /proc/cpuinfo
Processor : XScale-PXA270 rev 7 (v5l)
BogoMIPS : 415.33
Features : swp half thumb fastmult edsp iwmmxt
CPU implementer : 0x69
CPU architecture: 5TE
CPU variant : 0x0
CPU part : 0x411
CPU revision : 7
Hardware : The Gumstix Platform

Maybe the first thing would be to configure the kernel to support only those features included in my hardware setup.

Speex encoder on n800’s DSP

I’ve been wanting to run things on OMAP‘s DSP processor since the day I tested an OMAP1510 development board some years ago. Finally after a Proof of concept G.711 dsptask mail by Simon Pickering I decided to cut’n’paste that and try.

I knew the Speex had already been ported to the DSP (TMS320C55) used by OMAP1 (770) and OMAP2 (n800) so I started porting it to the DSP Gateway to be able to use it in my n800.

The DSP Gateway’s DSP tasks are seen as /dev/dsptask/<taskname> devices on ARM side and are interacted with read, write, and ioctl calls. Very linux stylish and convenient in my opinion. On the DSP code one struct defines callbacks for these calls. The code overhead on DSP side is some tens of lines.

Speex has speex_alloc functions that can be overwritten if the default memory allocation is not suitable. In the existing DSP port these were overwritten with functions using preallocated global char arrays that are used for all allocations, freeing is not possible. The DSP char is 16 bits as is int. The long is 32 bits and a pointer is 23 bits. Long long is 40 bits. I had some problems with calculating with pointers (casting a pointer to long didn’t produce valid looking value) in the existing implementation so I rewrote the allocation functions to use arrays and indexes. Also the existing implementation printed pointer values as %x which seemed to print completely different values than %p. I did use dbg() however, not fprintf.

The dbg() prints will be shown in dmesg or syslog on the ARM side if the kernel is compiled with mbox debug. The n800 stock kernel is not, but it’s almost trivial to compile a kernel of your own. My kernel with mbox debugs and built-in ext3 is here.

Other than the allocation functions there was not much to port, couple of functions calling the speex’ init and encode functions. I did have an odd problem though: the DSP seemed to jam after some tens of seconds and the DSP kernel was rebooted. After I added poll_disable(task) in my encoding callback function, the jamming was gone. The function will disable the polling for 10 seconds. Afaik, that should be called only if the completion of the function takes more that 10 seconds, which it doesn’t.

My speex patch against the git head is available, if somebody wants to test it. There can be some weirdness as this is my first test with the DSP stuff and I don’t even know how to use the git ;)

If my measurements are correct it takes roughly 40 ms to encode one 20 ms frame without compiler optimizations. With -o3 it takes a bit over 20 ms. The speex is meant to be portable and has a header defining some math functions. The functions are ported to different CPUs like ARMv5 and Blackfin. Maybe some DSP guru quickly ports those to the TMS320C55 too? :)

I think the best place for DSP information for the tablets is in maemo.org wiki as I hope it will be kept up to date with the latest projects and tweaks. One thing to be added there would be a note about the skeleton page. I used the Active Block Receiving and Active Block Sending.

N800 and GCC options

I was a a bit surprised to hear that Nokia doesn’t compile the Maemo stuff with any ARMv6 specific GCC options. According to someone in IRC the gain is insignificant compared to increased size (and thus booting time) when not using thumb mode.

I decided to test this out and compiled a bunch of packages with -mcpu=arm1136j-s -mfpu=vfp -mfloat-abi=softfp GCC options and without -mthumb.

The performance tests included measuring rootfs booting time, gtk-perf, cairo-perf, encoding and decoding with theora and decoding with vorbis. Memory comsumption was not measured, even though it should have been. None of the tests were made with scientific accurance and there can be errors in the tests, although zuh double checked most of the tests. There aren’t much details here, but I should have them written down, so ask if you have any questions.


thumb

I took some of the gtk, hildon, glib, xlib, etc libraries and binaries that were compiled with -mthumb and compared the sizes. The sizes increased 23% in average, the minimum increase being 8% and the maximum 30%.

Booting time was calculated by measuring the time between setting the clock in /etc/init.d/rcS and running the last init.d script. This is not very accurate since processes are started to background etc. The booting time increased roughly 8% (2 seconds on my MMC).

Encoding with theora was a bit of a surprise. The encoding time with theora compiled with no GCC options and with –disable-float was even slightly faster than with floats and the mentioned ARMv6 GCC options. Decoding with theora seemed to be roughly 5% faster with the new options.

The biggest practical difference in this test came with vorbis decoding. Decoding with ARMv6 options took only 30% of the time when compared to no options.

Gtk-perf doesn’t cover many widgets but hopefully shows the direction of the performance differences. The improvement was around 14%.

Cairo-perf doesn’t give one nice number to for making hasty conclusions, but the improvements varied from 1.05x to 7x, while the average was 1.8x. cairo-perf-diff-files reported over 800 speedups and two slowdowns.

zuh writes about memory comsumption, thumb mode swithing, gtk-perf and cairo-perf in more detail in Movial‘s syslog.

For me the disk space isn’t an issue and I don’t boot the device so often that the two second delay in bootup really matters. So, for me the little speedups are welcome. I can even tolerate the memory loss reported by zuh.