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
I downloaded Linux 2.6.38, and its patches for AT91RM9200. Build its kernel by set arch and cross compiler.
Download kernel from here
Download patch from here
Apply patches patch -p1 xxx.patch
Open Kernel source code, find Makefile from its root directory, find following 2 lines:
Change it to:
To compile the kernel, you need to make a .config file at Makefile folder, we run following command:
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.
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
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.
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”)
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