Booting the Nexus 4 from “scratch”

I recently decided I’d like to see if it was possible to boot the Nexus 4 from scratch – the Android build system seems to use a prebuilt bootloader.img.

A few other people have wondered about this, but have since lost interest

If this was a PC I’d be looking at the GRUB source code or similar, but the Nexus 4 was initially a mystery. There’s no proper references to a bootloader in the AOSP source, but there used to be:

A listing of deleted files in GitThe Nexus 4 is significantly newer than the G1, so what the hell is booting Android these days?

For Qualcomm devices and a few others, the answer is the Little Kernel Bootloader, or LK for short. Qualcomm actually publish quite a nice guide for their DragonBoard, which happens to run the same SoC as the Nexus.

After futzing around for a while trying to find source code, I found it in some unknown branch of – seriously, I had to run

git log --all -- **/msm8960*

and checkout a commit that looked reasonable:

git branch --contains [hash]

gave me nothing

The next step was to cross compile the lk source for the ARM processor in the Nexus.

git clone --depth=1

export TOOLCHAIN_PREFIX=arm-eabi-
export PATH=$PATH:/home/ubuntu/arm-eabi-4.8/bin/
cd lk
make msm8960

…which produced quite a bit less than I was expecting

ubuntu@ip-172-30-0-141:~/lk/build-msm8960$ ls -lah
total 8.7M
drwxrwxr-x 9 ubuntu ubuntu 4.0K Jul 31 17:09 .
drwxrwxr-x 15 ubuntu ubuntu 4.0K Jul 31 17:08 ..
drwxrwxr-x 3 ubuntu ubuntu 4.0K Jul 31 17:08 app
-rw-rw-r-- 1 ubuntu ubuntu 282K Jul 31 17:09 appsboot.mbn
-rwxrwxr-x 1 ubuntu ubuntu 282K Jul 31 17:09 appsboot.raw
drwxrwxr-x 3 ubuntu ubuntu 4.0K Jul 31 17:08 arch
-rw-rw-r-- 1 ubuntu ubuntu 1.4K Jul 31 17:08 config.h
drwxrwxr-x 7 ubuntu ubuntu 4.0K Jul 31 17:08 dev
drwxrwxr-x 2 ubuntu ubuntu 4.0K Jul 31 17:08 kernel
drwxrwxr-x 7 ubuntu ubuntu 4.0K Jul 31 17:08 lib
-rwxrwxr-x 1 ubuntu ubuntu 1.7M Jul 31 17:09 lk
-rwxrwxr-x 1 ubuntu ubuntu 282K Jul 31 17:09 lk.bin
-rw-rw-r-- 1 ubuntu ubuntu 4.1M Jul 31 17:09 lk.debug.lst
-rw-rw-r-- 1 ubuntu ubuntu 2.0M Jul 31 17:09 lk.lst
-rw-rw-r-- 1 ubuntu ubuntu 46K Jul 31 17:09 lk.size
-rw-rw-r-- 1 ubuntu ubuntu 87K Jul 31 17:09 lk.sym
-rwxrwxr-x 1 ubuntu ubuntu 18K Jul 31 17:09 mkheader
drwxrwxr-x 4 ubuntu ubuntu 4.0K Jul 31 17:08 platform
-rw-rw-r-- 1 ubuntu ubuntu 2.1K Jul 31 17:09 system-onesegment.ld
drwxrwxr-x 3 ubuntu ubuntu 4.0K Jul 31 17:08 target

Nothing that looks like a bootloader.img there. I know that that particular file should start with “BOOTLDR!”, so let’s check for it.

grep -ir BOOTLDR

Nothing. Shit. Looks like we’ll have to do this the hard way.

If you download the stock images from Google, you’ll notice that they haven’t been changed very often:

897b2c89ab564caf5bb4fe6b90d3526b occam-jdq39/bootloader-mako-makoz10o.img
d56825a3b22b2fe9334b5efa4d117206 occam-jwr66y/bootloader-mako-makoz20i.img
ada04d55afd815674d586a60877587e8 occam-kot49h/bootloader-mako-makoz30d.img
ada04d55afd815674d586a60877587e8 occam-krt16s/bootloader-mako-makoz20i.img
ada04d55afd815674d586a60877587e8 occam-ktu84l/bootloader-mako-makoz30d.img
ada04d55afd815674d586a60877587e8 occam-ktu84p/bootloader-mako-makoz30d.img
a66f24fa47871e6e68c34952a6fb9587 occam-lmy47o/bootloader-mako-makoz30f.img
a66f24fa47871e6e68c34952a6fb9587 occam-lmy47v/bootloader-mako-makoz30f.img
a66f24fa47871e6e68c34952a6fb9587 occam-lrx21t/bootloader-mako-makoz30f.img
a66f24fa47871e6e68c34952a6fb9587 occam-lrx22c/bootloader-mako-makoz30f.img

I decided to concentrate on the makoz30f binary as it’s the same one my Nexus 4 is running. I knew there was an old tool called split_bootimg that could pull Android images apart, so I gave it a shot.

ubuntu@ip-172-30-0-141:~$ perl ~/images/occam-lmy47v/bootloader-mako-makoz30f.img
Android Magic not found in /home/ubuntu/images/occam-lmy47v/bootloader-mako-makoz30f.img. Giving up

Damnit. That tool works on kernel images, which are pretty similar across devices and manufacturers, not bootloaders, which are manufacturer and even device-specific.

I tried staring at split_bootimg’s Perl source and at the bootloader in a hex editor, but nothing immediately stood out, and I’m impatient. To Google!

…which felt a bit like cheating – I Googled “bootloader.img format” and got

ubuntu@ip-172-30-0-141:~$ ./bootunldr ~/images/occam-lmy47v/bootloader-mako-makoz30f.img
#0 sbl1 (94440 bytes)
#1 sbl2 (145448 bytes)
#2 sbl3 (1430160 bytes)
#3 tz (193388 bytes)
#4 rpm (144892 bytes)
#5 aboot (309856 bytes)

048cb7cffe6d1e68d3ed88f2d8fefa31 aboot
aad39fa6f8c661fd21afe01c47f3ddae rpm
1e752230dd972f7d30e5dc508e724842 sbl1
150f5f58c44ebaffb01923beed5260a1 sbl2
890e8e606af016e3ae239af1494821c0 sbl3
1d5c541be1018bb9b6f0183f4c60745c tz

Holy shit, progress!

At this point I noticed a conspicuous lack of source code. LK is the “aboot” part up there, but I didn’t have a way to build any of the others.

Emailing Qualcomm wasn’t a lot of help, because I haven’t won the lottery recently, and I’m allergic to NDAs.


Having grown tired of large corporations (I also emailed LG), I then rewrote the unpacker in Python, because I don’t trust any C code that I write. Having verified that I got the same binaries as above, I wrote a re-packer that could take the proprietary blobs from Qualcomm and add a Little Kernel/aboot file that I built myself. It can unpack the bootloader.img from the stock image and repack it, and the MD5s even match!

The source is here:

This is where I stopped: I would not recommend anyone create a custom bootloader for the Nexus 4 and attempt to flash it. The reason, and the reason I call this little project a failure is that there’s no easy way to recover the bootloader if it fails to work. The bootloader controls access to adb fastboot, and if that doesn’t work you’re pretty much screwed. See my update for the other problem (oops!)

If you do brick your Nexus 4, your options are:

While I was researching this article I found the following reference boards in varying states of availability:

  • Qualcomm APQ604 reference board
  • Compulab QS600
  • Inforce IF6410

You could probably do a lot of the same testing on these boards and recovery wouldn’t be quite as difficult.

Unfortunately, Inforce requires a purchase before you can download the BSP, CompuLab lists the bootloader source as “coming soon” (and also don’t really want to talk to you unless you are going to buy something)

Addendum: there’s a minor problem with my plans –
Basically this means I need another angle of attack. Luckily another Redditor pointed me towards – there’s no instructions so it looks like I’ll have to write a part 2.

If you want to fund more projects like this, send Bitcoins to 17RugTAi9LdxMUcgVhpWVRRvVsWg11P6V5

If cooking food, rather than ROMs is more your thing, try a recipe from The Cinnamon Scrolls

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s