Port Linux 2.6.38 to AT91RM9200 board

There are lots of articles and tips on how to port Linux 2.6 to a customized board.  Not single article will help me finish the job. Actually I read lots of post, watched lots videos on www.youtube.com, finally I got it work.

First we need to understand boot loader, kernel, file system, their relationships.

A boot loader is trying to load a Linux kernel, why do we need a boot loader? Why not just start Linux kernel straight way, one answer, we can’t.

Linux is big, when it starts, it expects memory to be ready. We need someway of load kernel to memory on powering up a development board.

Just call it boot loader, we can load kernel from flash, hard drive, from TFTP server, etc.

First of all, you need to download cross compile tool chain, without tool chain, we can’t do anything, there are ready made binaries for development board, if you are using AT91RM9200DK or EK, most of the chances, someone already made it works, all the kernel, bootloader, file system is ready. My board is customized from a AT91RM9200DK board, it has a small flash, 2 serial ports, a usb, a 3G modem. So I have to compile the kernel at least, to create new MTD flash partition, reduce serial support.

Download tool chain from here

http://www.friendlyarm.net/dl.php?file=arm-linux-gcc-4.4.3.tgz

 

I downloaded Linux 2.6.38, and its patches for AT91RM9200. Build its kernel by set arch and cross compiler.

Download kernel from here

https://www.kernel.org/pub/linux/kernel/v2.6/

Download patch from here

http://maxim.org.za/at91_26.html

 

Apply patches patch -p1 xxx.patch

 

Open Kernel source code, find Makefile from its root directory, find following 2 lines:

ARCH ?=$(SUBARCH)
CROSS_COMPILE ?=

Change it to:

ARCH ?=arm
CROSS_COMPILE ?=/home/lewis/Linux2.6/opt/FriendlyARM/toolschain/4.4.3/bin/arm-linux-

 

To compile the kernel, you need to make a .config file at Makefile folder, we run following command:

make at91rm9200dk_defconfig

After that we could run make, but you may want to change a few things, by running make menuconfig

After this, a vmlinux will be created, run “file vmlinux”, you should see this:

vmlinux: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, BuildID[sha1]=94cce7ae7a99f808a2655a4d160311bf8322cd77, not stripped

uboot need compressed uImage,  I use following command create it:

OBJCOPY        = $(CROSS_COMPILE)objcopy

$(OBJCOPY) -O binary -S vmlinux linux.bin
gzip -f -v9 linux.bin
./mkimage -A arm -O linux -C gzip -a 0x20008000 -e 0x20008000 -d linux.bin.gz uImage

ObjCopy will strip the kernel debug information.

mkimage will create a boot able image.

BusyBox

Download Latest BusyBox

I copied an old file system over, then recompiled busybox 1.22.1, install the compiled busybox by using make install command.

 

Then from my old uboot 1.0.0, I use tftp download latest kernel to on board ram. Then run bootm, kernel starts, what an excitement.

But it could not boot from flash, which in uboot environment I have setttings like following:

bootargs root=/dev/mtdblock2 rootfstype=jffs2 console=ttyS0,115200 mem=16M

 

As you can see, I am booting from mtdblock2, then I have to tell kernel I have 3 partitions, I tried change the file at

/home/lewis/Linux2.6/linux-2.6.38/drivers/mtd/devices

Then boot the kernel again, I can see I got 3 partitions now. But the kernel could not find my file system. Then I decided to try boot from NFS first, then I changed uboot bootargs:

setenv bootargs root=/dev/nfs rw nfsroot=192.168.1.4:/home/lewis/src/nfs/rootfs ip=192.168.1.52:192.168.1.4:192.168.1.1:255.255.255.0:x::off init=linuxrc

 

Now my kernel and file system can starts.

After kernel is loaded, it will call first user program “init”, which is the first process, we use busybox create it for us, then it load rc.cfgnet at /etc folder.

Error 1:

If use tftp download this image to board, then boot up, it might complain

Error: unrecognized/unsupported machine ID (r1 = 0x000000fb).

 

This kind of error message happens if the machine ID which is set in U-Boot doesn’t match the kernel’s ID(s). Unfortunately a standard U-Boot sets the machine ID on AT91RM9200DK boards not to MACH_TYPE_AT91RM9200DK but to the generic MACH_TYPE_AT91RM9200.

Go to: linux-2.6.38/arch/arm/mach-at91, find board-rm9200dk.c, locate the lines

change MACHINE_START(AT91RM9200DK, “Atmel AT91RM9200-DK”)

to MACHINE_START(AT91RM9200, “Atmel AT91RM9200-DK”)

 

Error 2:

VFS: Cannot open root device “nfs” or unknown-block(0,255)

Looks like our kernel do not have NFS support.

Run make menuconfig

Use the ARM EABI ot compile the kernel, this way new kernel will support old compiled program?

Maximum number of legacy PTY in use, I choose 2

I choose Basic memory-mapped GPIO controllers support

Network File System

I choose NFS client support

Root file system on NFS

Now save it, make clean, make

 

 

 

 

 

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

Up ↑

%d bloggers like this: