Tuesday, April 20, 2010

An endianess problem with uClinux on uc5272

I have been struggling in the past few days trying to run a uClinux cramfs image on a Coldfire uc5272 board. I know, the uc5272 is pretty old, with its uCbootloader at version 1.7.7. I'm trying to run a 2.6.x kernel image on it, so it's interesting to see how a pretty new kernel running on a pretty old hardware.

uCbootloader has special support for cramfs image. Unlike u-boot or most of the other bootloaders, uCbootloader understands cramfs and can "ls" its contents, can "cat" file contents. And the actual kernel file, linux.bin, is embedded in the rootfs "/" directory. uCbootloader will uncompress the image, retrieve linux.bin out of the rootfs and run it, and the kernel in turn mount the fs.

u-boot and most other bootloader requires that the kernel file is out of the rootfs, usually on top of rootfs in the image. The kernel got loaded first, and then the rootfs got mounted by the kernel.

I have tried a few builds but none of them works. "ls" shows an error "Not a valid file system", and "go" doesn't uncompress the image. After a while I realized that either the image is not valid, or the uCbootloader somehow doesn't like the image, one way or the other. Nothing to do the kernel, because it's not even there yet.

I started to doubt the endianess of the image. I used "od" to display the magic number of the image, it's 0x28cd3d45, little endian, which is the host's endianess. It's supposed to be right. There is a convention that cramfs image is always little endian, even for big endian CPU. The kernel is supposed to do the swapping.

So what's going wrong, what about the uCbootloader? It doesn't complain "wrong magic number" etc. But it's old right? So I did a little experiment, I change the order of the first 4 bytes of the image to make it looks like a big endian image (the first 4 bytes as a long, is the magic number of cramfs). And "ls" works! Though it's all messy codes, but it seems to accept it as cramfs.

Then I used /sbin/mkfs.cramfs on my Ubuntu 9.10 to build a big endian image. This one support different endianess by a "-N" option. The image is downloaded and programed into flash, and "ls" shows its contents correctly. Beautiful! And "go" command uncompress the image, load the kernel from "/" dir and run. It stops there though, complaining illegal instructions. This is not supprising , because the kernel is built in little endian.

So, it's a good exercise at least. I have 2 things to go further, one is update the uCbootloader to 1.7.8. And the other is to build a big endian kernel.

1 comment:

  1. Interesting result! When I configure the kernel before I rebuild a new image, under the mtd driver advanced option, I chose big endian swap. After the kernel generated, I use mkfs.cramfs to make a big endian image. This image is working on uc5272!

    ReplyDelete