Custom Kernels

From WebOS Internals
Redirect page
Jump to navigation Jump to search

These instructions are obsolete and likely incorrect

See Building_Apps_and_Kernels instead.

Everything below here should be ignored

Some caveats and warnings:

At this point, the kernels I've compiled seem to work fine. These steps assume that root access is enabled on your Pre, and a secure ssh access mechanism is available.

This procedure has only been verified to work on WebOS 1.0.3 through 1.0.4 and 1.1.3. Any prior or future releases may not work.

If anything goes wrong during the installation, your device may end up in a state where the kernel can't boot, in which case you can use bootie to change the boot kernel to the previous one.

NOTE: currently, unless you plan to do that just out of scientific interest, there's no real reason to build a custom kernel as everything is available in the "standard" one. In fact these instructions should build exactly (well, not //exactly// because Palm may be using a different version of the compiler) the same kernel you already have on the device.

Custom Kernel

Download and install the cross-compiler

1. Download the appropriate ARM toolchain for your the platform you'll be building on. So far, all testing has been done using the IA32 Linux toolchain, 2009q1 release. NOTE: The compiler used by palm is actually this one. The IA32 Linux toolchain, 2007q3-51 release

2. Un-tar the toolchain distribution to a convenient location on your system. I extracted it to a temporary directory and moved the arm-2009q1 subdirectory to /usr/local/arm, with subdirectories arm-none-linux-gnueabi, bin lib, libexec, share, and usr below.

tar xjvf arm-2009q1-203-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2
sudo mv arm-2009q1 /usr/local/arm

3. To use the toolchain properly for kernel builds (and anything else you want to cross-compile for the Pre) you'll want to have some environment variables set. The following, based on the setup-env script from the openmoko toolchain, is what I use to setup my Pre cross-compile environment.

export PRETOOL_DIR="/usr/local/arm"
(echo "$PATH" | grep -q "${PRETOOL_DIR}") || export PATH="${PRETOOL_DIR}/bin:${PATH}"
export STRIP="arm-none-linux-gnueabi-strip"
export LD="arm-none-linux-gnueabi-ld"
export CC="arm-none-linux-gnueabi-gcc -march=armv4t -mtune=arm920t"
export CPPFLAGS="-isystem${PRETOOL_DIR}/arm/arm-none-linux-gnueabi/include"
export RANLIB="arm-none-linux-gnueabi-ranlib"
export CXX="arm-none-linux-gnueabi-g++ -march=armv4t -mtune=arm920t"
export OBJCOPY="arm-none-linux-gnueabi-objcopy"
export PKG_CONFIG_PATH="${PRETOOL_DIR}/usr/local/lib/pkgconfig"
export PKG_CONFIG_SYSROOT_DIR="${PRETOOL_DIR}/arm/arm-none-linux-gnueabi"
#export LDFLAGS="-L${PRETOOL_DIR}/usr/local/lib -Wl,-rpath-link,${PRETOOL_DIR}/arm/arm-none-linux-gnueabi/lib -Wl,-O1"
export CCLD="arm-none-linux-gnueabi-gcc -march=armv4t -mtune=arm920t"
export MAKE="make"
export CFLAGS="-isystem${PRETOOL_DIR}/usr/local/include -fexpensive-optimizations -fomit-frame-pointer -frename-registers -Os"
export CXXFLAGS="-isystem${PRETOOL_DIR}/arm/arm-none-linux-gnueabi/include -fexpensive-optimizations -fomit-frame-pointer -frename-registers -Os -fpermissive -fvisibility-inlines-hidden"
export F77="arm-none-linux-gnueabi-g77 -march=armv4t -mtune=arm920t"
export AS="arm-none-linux-gnueabi-as"
export AR="arm-none-linux-gnueabi-ar"
export CPP="arm-none-linux-gnueabi-gcc -E"
export OBJDUMP="arm-none-linux-gnueabi-objdump"
export CONFIG_SITE="${PRETOOL_DIR}/arm/site-config"

To use it, just change PRETOOL_DIR to the root directory of your toolchain, then source it into your shell:

. /usr/local/pre/setup-env

Build U-Boot and install the mkimage utility

To build the kernel as a uImage file, you will need the mkimage utility, which is part of U-Boot. If mkimage is already on your system, great. It wasn't on mine, so here's what I did to install it.

1. Download the latest U-boot release.

2. Extract the tarball

tar xjvf ../u-boot-2009.06.tar.bz2

3. Configure U-Boot for the Pre. I don't know that the mkimage utility is architecture-specific, but I used the config that looked like it most closely matched the Pre's architecture just to be safe:

cd u-boot-2009.06
make omap3_beagle_config

4. u-boot seems to want the commands in a slightly different format so make some links in /usr/local/arm/bin

cd /usr/local/arm/bin
ln -s arm-none-linux-gnueabi-gcc arm-linux-gcc
ln -s arm-none-linux-gnueabi-ar arm-linux-ar
ln -s arm-none-linux-gnueabi-ld arm-linux-ld
ln -s arm-none-linux-gnueabi-objcopy arm-linux-objcopy
ln -s arm-none-linux-gnueabi-objdump arm-linux-objdump
ln -s arm-none-linux-gnueabi-nm arm-linux-nm

5. The mkimage utility should now be built in the tools subdirectory. To make it available for the kernel build, I just manually copied it into /usr/local/bin. Just make sure it's available somewhere in your PATH, or the kernel build will fail.

Download, patch, configure, and build the kernel.

6. From Palm's Open Source Packages page, download the Linux 2.6.24 kernel tarball and Palm's kernel modifications.

7. Extract the kernel tarball somewhere on your system, and gunzip the compressed patch file in the linux-2.6.24 directory.

cd linux-2.6.24
gunzip linux-2.6.24-patch.gz                                                

8. Apply Palm's kernel patches to the kernel source tree.

patch -p1 < linux-2.6.24-patch

9. Configure the kernel

Your Pre should have a config file in the /boot directory that is ostensibly what was used to build the original kernel. This file is virtually identical to the file arch/arm/configs/omap_sirloin_3430_defconfig in the patched kernel tree. Copy either file (I used the defconfig) to a file named ".config" in the top level of your source tree.

NOTE: if you change the vermagic, you won't be able to load binary-only modules. Until you can rebuild all the modules, it's probably a good idea to leave CONFIG_LOCALVERSION="-joplin-3430"

Modules These are the modules that look to be binary only.


Now, you're ready to build.

10. Build the kernel

make && make uImage

This will take some time. Assuming you followed the above steps, and assuming I didn't miss anything in documenting them, you should have a uImage file in arch/arm/boot once the "make uImage" command completes. The uImage target requires the mkimage mentioned earlier. Again, make sure it's in your path.

Now that the kernel's built, it's time to install it on the Pre.

Install the kernel on your Pre (here be dragons)

The following steps are crucial. I've done my best to capture the steps I went through, but I make no promises. If you botch the kernel install, you're probably looking at wiping your phone clean with WebOS doctor and restoring all your files/settings. You've been warned.

These instructions assume you've installed and configured the sudo package. If you prefer, you can just do everything as root.

1. Copy it over

There are a bunch of ways to copy files onto the Pre. I use scp to copy the arch/arm/boot/uImage and files into the /tmp directory first.

scp -P 222 arch/arm/boot/uImage userid@
scp -P 222 drivers/usb/gadget/composite/g_composite.ko userid@

2. Fix file ownership and permissions

Next, I ssh in to my Pre and change the owner/group of the files to root, and make sure the permissions are set properly.

sudo chown root:root /tmp/uImage-2.6.24-palm-joplin-3430-custom /tmp/

3. Prepare modules for new kernel

The above mentioned modules will only load when we have the same LOCALVERSION set. The defconfig does that for you. Still the g_composite module did not load for me with a custom kernel due to symbol problems. Luckily the source is included in the kernel patch and already built as module. We need to make a backup of our modules directory and then replace the old g_composite.ko with our selfbuild one.

cd /lib/modules
sudo cp -rp 2.6.24-palm-joplin-3430 2.6.24-palm-joplin-3430-backup
sudo mv /tmp/g_composite.ko 2.6.24-palm-joplin-3430/kernel/drivers/usb/gadget/composite/

4. Switcheroo time!

Now, you're going to to mount the /boot partition read-write, remove the uImage symbolic link, replace it with a link to your new kernel, and remount the /boot partition read-only.

cd /boot
sudo mount -o remount,rw /boot
sudo rm uImage
sudo ln -s uImage-2.6.24-palm-joplin-3430 uImage
sudo mount -o remount,ro /boot

5. Double check the files and permissions

Just because I'm paranoid, I always take a look at the /boot directory to make sure everything is in order. The uImage symbolic link should properly point to your new kernel file, and the permissions should match those of the original kernel. Here's what mine looks like after replacing the kernel:

-rw-r--r--    1 root     root      1098470 May 22 16:24
drwxr-xr-x    2 root     root         4096 Dec 31  1999 bin
-rw-r--r--    1 root     root        53756 Jun 16 21:47 boot.bin
-rw-r--r--    1 root     root            8 Jun 16 21:47 bootheader
-rw-r--r--    1 root     root        43372 May 22 16:24 config-2.6.24-palm-joplin-3430
drwxr-xr-x    2 root     root         4096 Dec 31  1999 dev
drwxr-xr-x    3 root     root         4096 Dec 31  1999 etc
drwxr-xr-x    2 root     root         4096 Dec 31  1999 lib
drwx------    2 root     root        16384 Dec 31  1999 lost+found
drwxr-xr-x    2 root     root         4096 Dec 31  1999 proc
drwxr-xr-x    2 root     root         4096 Dec 31  1999 realroot
drwxr-xr-x    2 root     root         4096 Dec 31  1999 sbin
drwxr-xr-x    2 root     root         4096 Dec 31  1999 sys
lrwxrwxrwx    1 root     root           30 Jun 24 12:16 uImage -> uImage-2.6.24-palm-joplin-3430
-rw-r--r--    1 root     root      2217848 May 22 16:24 uImage-2.6.24-palm-joplin-3430
-rw-r--r--    1 root     root      2226296 Jun 24 00:17 uImage-2.6.24-palm-joplin-3430-backup
drwxr-xr-x    5 root     root         4096 Dec 31  1999 usr

The moment of truth

1. Reset your Pre

Hold Orange-Sym-R to reboot. If all goes well, you'll see the flashing Palm logo and eventually WebOS will come up. ssh into your Pre and run uname -a to confirm that the new kernel is indeed running. If it is, congrats, you're running your own kernel. Happy hunting!