Linux bringup on NXP (formerly Philips) LPC2294
This is a summery of all operations done in order to run uClinux on Philips LPC2294
uClinux is a version of Linux for system without MMU (Memory Management Unit) In recent releases it works also
for system with MMU's.
LPC2294 is an ARM 7 TDMI processor from philips. ARM7 processors lack MMU and thus in order to run Linux we must use uClinux. However, in recent version of the kernel MMUless support is integrated into vanila kernel.
We used vanila kernel with philips specific patches and uClinux file system.
Step 1 - Compiling U-boot
We started the work on March 2006 when Tadiran Telecom got a board from Phytec.
The first job was to compile a boot loader to run linux.
We chose U-boot since it is a known boot loader that I (Ori Idan) has a lot of experience with.
We got an Application note from philips with all steps needed to run uClinux on this board.
We downloaded U-boot 1.1.3 and then added a patch (supplied by philips) to add support for LPC2294 After the patch it compiled without errors.
However when tried to program it on the chip it did not work.
It took us a while to understand that we need to program it to addresses 0x80000000 although the base address as stated by U-boot is 0x81400000.
The reason is that U-boot starts with copying itself to RAM memory.
On our first board we could not run it since the board had much less memory, we tried changing the load address and program it agian and it worked.
We also tried to use a higher baud rate then the default of 9600 that did not work. Also onboard network adapter did not work.
Step 2 - Compiling uClinux
After we had a boot loader we went on to compile uClinux.
uClinux contains both the kernel and a coresponding file system. We downloaded the version recomended by the Philips application note.
We downloaded kernel 2.6.11 and replaced the kernel in the uClinux package (this was also recomended in the application note).
We then downloaded few patches as recomended by the application. note.
After applying the patches we compiled the kernel and the file system.
We could not program it to our board since it did not have enough RAM and Flash.
We had to wait to get a new board with enough memory on it.
In the mean time we went on to see if we can run Linux from flash.
It appears that the kernel has an option called XIP (eXecute In Place) however that option was not ported by those who did the LPC2294 port.
I checked if I can do it myself but with no success yet. We will return to it later.
After we got the board with more memory we tried to program Linux using U-boot, since we had only serial interface to U-boot we expected it to take a long time, however for some unknown reason we ended up with only the first line from the S record file programed.
I did not spend much time checking why since our task is to get linux working and it does not matter how...
We finaly programmed it using the Keil ULINK software.
In order to do it I wrote a small utility that converts the binary image to an Intel Hex file.
However it did not work since U-boot requires a uImage and not a kernel Image.
After a short research I wrote a small script that generated the right images and converted them to an Intel hex file.
It seems that u-boot did recognize the files and tried to copy them to RAM but when trying to run Linux all system froze.
My assumption is that Linux is called and for some reason does not work.
From the document it seems that we had to download Linux to address 0x81008000 and not 0x81000000 as we did initaly. Changing the load address did not make it.
Step 3 - Trying different approaches
Frustrated from U-boot we went on to look for different ways to boot. We found a site of a german guy who seems to have done all this job. He built his own board and used his own bootloader.
We downloaded the bootloader and tried to change it to our board. The bootloader Makefile did not even compile it.
I had to rewrite large parts of the Makefile and large part of the code to get it to compile.
However after compiling and linking and programming it to flash it did not even display a prompt.
Step 4 - It is working...
After finding a way to debug the code at assembly level, we found that U-boot actually jumps to the right address as we thought, but there it gets an illegal opcode.
This was due to a fullish mistake... we did not load the right image, for some reason it seems we loaded only the data and not text and data sections of the object file.
After loading the right file the kernel started to speak.
However, the work is far from being done, since as the kernel got to the stage it looks for the ram disk it did not find it.
Step 5 - finding the RAM disk
We tried to debug the kernel to see how it knows where to find the right disk.
This code is not a trivial code but we found that we put the RAM disk at a different location then what the kernel expected.
After loading the RAM disk to the right location, we did see some progress, it said a file system was found and mounted.
Step 6 - running init
The first step after mounting root file system is running init.
The kernel tried running init and compalined init was not found.
Very strange since the file system was built correctly. We tried rebuilding it again and again but with no luck, we tried passing other init options to the kernel such as: init=/bin/sh
Remember that on our system passing options means recompiling the kernel and downloading it again.
Since downloading worked only on a Windows system, we had to use two computers, one with Linux as a development station and another with windows as a programmer, so downloading kernel took about 10 minutes each time.
After many trials that did not succeed, we contacted the guy who did the port for this processor, he helped
us finding that the kernel did not have support for flat object files that are needed for uClinux.