Build Donut Kernel for G1 by Michael Mitchell and Frank Sposaro - 5.11.10
The objectives of this page are as follows:
Background Information
Your phone has several devices which hold different parts of the filesystem. You view them by using the "adb shell" shell command to open up a remote terminal to your phone:
:>adb shell #cat /proc/mtd dev: size erasesize name mtd0: 00040000 00020000 "misc" mtd1: 00500000 00020000 "recovery" mtd2: 00280000 00020000 "boot" mtd3: 04380000 00020000 "system" mtd4: 04380000 00020000 "cache" mtd5: 04ac0000 00020000 "userdata"
mtd1 is the recovery image and is flashed with /system/recovery.img on every shutdown.
Keep this in mind if your phone isn't holding the changes a cross reboots.
The boot and recovery images are NOT proper filesystems.
They are specially formatted for Android consisting of a 2k header, followed by a gzipped kernel, followed by a ramdisk,
followed by a second stage loader (optional, as of writing this has yet to be used).
+-----------------+ | boot header | 1 page +-----------------+ | kernel | n pages +-----------------+ | ramdisk | m pages +-----------------+ | second stage | o pages +-----------------+ n = (kernel_size + page_size - 1) / page_size m = (ramdisk_size + page_size - 1) / page_size o = (second_size + page_size - 1) / page_size 0. all entities are page_size aligned in flash 1. kernel and ramdisk are required (size != 0) 2. second is optional (second_size == 0 -> no second)
Getting Android Source
The source for Android is hosted on a git repository. However, the kernel and framework are in two independant trees and are
built separately. Let's first get some tools after creating your working directory.
sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl \ zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev \ ia32-libs x11proto-core-dev libx11-dev lib32readline5-dev lib32z-dev \ libstdc++6-4.3-dev git clone git://android.git.kernel.org/tools/repo.git
This gets the repo tool which can be used to download the framework. To git the source for the framework run your repo tool and sync it (note: we compiled the donut branch "-b donut" in this demo):
repo init -u git://android.git.kernel.org/platform/manifest.git -b donut repo sync
Additional Instructions for framework can be found at Android Source.
To get the kernel and switch to donut branch execute:
git clone git://android.git.kernel.org/kernel/msm.git cd msm git checkout android-msm-2.6.29-donut
The following is a listing of what was downloaded.
michael@illamdlin:~/donut$ ls bionic build development frameworks msm packages system bootable dalvik external hardware Makefile prebuilt vendor
Before attempting to compile you must ensure that you are using java jdk1.5. It will not work with 1.6 or later. You can check your version by the following. Check the android source cite for more information about versions for java-alternatives
sposaro@mobiprog:~/android-source$ java -version java version "1.5.0_22" Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_22-b03) Java HotSpot(TM) 64-Bit Server VM (build 1.5.0_22-b03, mixed mode)
Compiling Android Source
Before starting it is helpful to configure your environment additonally. Our target platform is the G1 which runs an ARM processor, however like the majority our machines are x86. So we need to get ready cross compile. Make sure the arm-eabi tool is included in your path.
$HOME/donut/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin
It is also helpful to have a pre built config file. We copied the config file from a working phone by doing the following. Here's what we got .config
adb pull /proc/config.gz . gunzip config.gz cp config $HOME/donut/msm/.config
Compile Kernel Code
Now we are ready to compile the kernel code. Change into the kernel (msm) directory. Run make with the cross compile flags.
make ARCH=arm CROSS_COMPILE=arm-eabi-
So it compiled without errors (hopefully). Your kernel image (called zImage) is now made.
root@illamdlin:/home/michael/donut/msm/arch/arm/boot# ls bootp compressed Image install.sh Makefile zImage
Compile Android Code
Now you can run the make command from the framework directory.
After first running make, we got some annoying compile errors complaining about invalid conversion
from const char * to char * in development/emulator/qtools.
We simply added a const_cast
So what happened? Where did everything go? It compiled much more than just the files needed to
boot Android. It also compiled all the tools and a listing of prebuilt apps. Everything is
placed in a new folder called 'out'.
The .txt files are checking if the file system is case sensitive.
The directories are divided into files for the host machine and
files for your target phone.
We will not be directly using the files in host/common.
They are intermediate java files.
In this we find more directories of files we aren't using with the exception of the bin.
The bin has all the tools used for Android, including the ones downloaded with the Android
SDK. In additon is has important programs for creating and deploying our images, such as
fastboot and mkbootimg, that we will look at later.
It successfully finished on our dual core machine (note the -j3 option so you know this may take a while):
cd $HOME/donut
time make -j3
real 39m24.893s
user 64m51.760s
sys 5m1.240s
Let's take so time to get familar to what was acutally built:
michael@illamdlin:~/donut/out$ ls
casecheck.txt CaseCheck.txt host target
michael@illamdlin:~/donut/out$ ls host/
common linux-x86
michael@illamdlin:~/donut/out$ ls host/common/
obj
michael@illamdlin:~/donut/out$ ls host/common/obj/
JAVA_LIBRARIES
michael@illamdlin:~/donut/out$ ls host/linux-x86/
bin framework lib obj
Lastly, let's check out the target files. Here are some,
but the most important is ramdisk.img
michael@illamdlin:~/donut/out/target/product/dream-open$ ls
android-info.txt data obj
boot.img installed-files.txt previous_build_config.mk
clean_steps.mk kernel ramdisk.img
Flashing Custom Images to Device
We have to get root access. Follow these directions, pretty good
just note that when you type 'telnetd' nothing appears to happen.
Just continue with the directions, you have started a telnet daemon
running in the background.
You will also need to make sure that you have a boot loader that allows for the 'fastboot' command created in your out/host/bin that we looked at earlier . Download the HardSPL bootloader and name is update.zip and move it to the sdcard.
HardSPL VER: HSPL10.95.3000 ZIP: splhard1_update_signed.zip MD5: 6502af25b9e9fbe1322cc405559af1ca
download splhard1_update_signed.zip adb push splhard1_update_signed.zip sdcard/update.zip
Boot the phone into recovery mode by holding the power and camera buttons.
Then alt+l buttons and choose to apply update.zip.
Move the the ramdisk.img from the framework out directory and place it next to the kernel image. We only did this to a void having a long cmd to navigate.
pwd $HOME/donut/out/target/product/dream-open$ cp ramdisk.img /home/michael/donut/msm/arch/arm/boot/
Time to zip together all the layers shown in the background information into one.
pwd: $HOME/donut/msm/arch/arm/boot mkbootimg --cmdline 'no_console_suspend=1 console=null' \ --kernel zImage --ramdisk ramdisk.img -o boot-new.img
You start the phone with your image on there by using the fastboot command. The fastboot command has two different options, boot or flash image. Using boot for testing is good because if there was an error then you can restore the phone by restarting. Flashing will always start the phone with that image. --NOTE: You must be root to run these commands
pwd :$HOME/donut/msm/arch/arm/boot fastboot boot boot-new.img or fastboot flash boot-new.img fastboot reboot
You should see the name of your machine and kernel version when you check the settings->about phone options.