Garux : a Linux bootloader for the Palm OS

Introduction

What is Garux ?

Garux is a loadlin-alike Linux bootloader for the Palm OS. Its job is to stop the Palm OS, and to start a Linux kernel right after.

Why is it so specific ?

Most bootloaders are started at very early stage, virtually right on boot (i.e. when you press the power button). As you probably know, when a Palm PDA is started, it boots off its ROM chip (we mean started as after a hard reset). Using a standard bootloader such as U-boot would then mean to overwrite the ROM of the PDA, that is to say the Palm OS. This is either impossible (some PDAs like the Tungsten E cannot be flashed), either very risky, since a single bug would turn your PDA into a useless doorstop.
That's why Garux was invented : it is a bootloader that is ran on top of Palm OS. Its job is to unload the Palm OS from memory, and to start a Linux kernel image.
However, Garux has a specificity that makes him very different from other bootloaders : it embbeds its own kernel image. That means Garux has to be rebuilt from its source code every time you want it to load a different kernel image. This might sound pretty harsh at first, but it's indeed very usefull : it let you distribute a simple .prc file which contains all the end-user needs.

Current status

Garux is now supporting a wide range of PDAs :

Palm Tungsten E

First PDA to be supported by Garux. Should work

Palm Tungsten T

Not yet tested. Should work

Palm Tungsten T3

Not yet tested. Should work

Palm Tungsten LifeDrive

Should work

Tools needed to compile Garux

In order to be able to compile software that will run on the Palm OS, you'll need a PalmOS SDK. There is a free Palm OS SDK called prc-tools which uses the Gnu Compiler Collection. You'll need this to be able to compile Garux.
Whatsoever, if newer Palm OS devices sports different kinds of processors (X-Scale, OMAP, etc...), former one used to run a 68000 processor. In order to keep a binary compatibility, newer devices runs a 68k emulator. And even though, they are still faster than their predecessor because their CPUs are way faster (and also because the Palm OS itself doesn't use emulation but is coded natively for the host CPU). However, Palm OS applications can be compiled natively for ARM : you'll gain speed, but you'll lose backward compatibility as a tradeoff. But compiling ARM binaries isn't that easy : you must create a 68k binary which bundles your ARM binary as a ressource. All of this has been done in Garux, so you won't have to bother about it.

How does Garux work ?

What have we done ?

Here are the problem we ran into, and here is how we solved them :

In order to boot it, we obviously needed to send a kernel image to the Palm OS. However, Palm OS databases cannot be bigger than 64Kbytes. This problem was simply solved by splitting the kernel in 64Kb chunks, and re-joining them 6Blater on.

We needed to get out of the 68k emulator, because any application is started as if it was a 68k app. This is not so hard, because the Palm OS has provision for this : we just used the PceNativeCall function to call the ARM part of Garux.

We had to setup the machine properly (i.e. turn off interrupts, turn off MMU, set up registers according to Linux expectancies). That was not a very hard job for two reasons : that's fully documented, and anyway most of this could be copied straight from u-boot

Last, but not least : we had to actually launch the kernel. That can sound dumb, but it was not as easy as it might have seemed. For this very simple reason : we had turned off the MMU. That's why the kernel image address we had was no longer valid. Here is how we solved it : first of all, we disassembled the Palm OS itself so as to get an idea of the virtual to physical memory mapping. Thnks to a disassembly of the DAL.prc file (we cannot distribute this one because it's copyrighted), we managed to find where the mapping was stored. Altering the memory mapping, we created a linear-mapped memory area that wasn't used by the Palm OS in normal use, but that was still large enough to contain a kernel image plus a small piece of code. Before disabling the MMU we copied our kernel image to this location, plus the end of the bootloader. We then jumped to the end of the bootloader, and disabled the MMU. In effect, disabling the MMU must be done from a linear-mapped memory address, otherwise the PC isn't valid once we stopped the MMU.

Ressources

Appart from this documentation, this website also offers :

A CVS repository which is anonymously-readable. You may check this CVS out if you're interested in porting Linux to another PDA or if you want to add features to Garux.