Android kernel: Find the base address to use with mkbootimg for your phone

This is old hat for serious Android hackers, but for me it took long enough to find (no help from Google or grep) that I’ll post it here. If you’re building your own Android kernel, the last step in the process is to pack the kernel binary and gzipped ramdisk together into a boot image with mkbootimg. Here’s where to find the base address to use for the “–base” parameter for your device.

First, a few links: This is a good intro to kernel building (although you’ll want to get the kernel source code for your actual device, in my case from LG). Here’s a great walkthrough of the entire process of grabbing your device’s config, building and repacking (caveat: it’s for a specific device, so don’t use his mtd layout or base address setting without checking yours first). Finally, a better explanation of unpacking and repacking boot images that’ll clear up the aforementioned caveat.

Running on a boot image pulled from your device will tell you what parameters to use with mkbootimg. But what about the base memory address? If you’re lucky, it’s in a technical spec or posted in a forum, and Google will turn it up, but for my device, that didn’t work (and if it had, forum posts that only say “use this number” would have left me wondering why).

The answer

The answer is going to be in the kernel source (either in the config, or hardcoded) for your device’s cpu. So, arch/arm is the place to look.

I’ll skip to the end: grep for PHYS_OFFSET and that should find your answer.

In my case, LG uses a kernel config variable, CONFIG_PHYS_OFFSET, to set PHYS_OFFSET. LG’s build system separates out various cpu- and model-specific kernel configuration parameters, which I found in arch/arm/configs. If you’ve got an LG device, your model-specific config is there.

LG’s README for my phone says to make thunderc-sprint-perf_defconfig before building the kernel (My phone, the Optimus S, is thunderc), so its config is in the matching arch/arm/configs file thunderc-sprint-perf_defconfig. And, that’s where the default value of CONFIG_PHYS_OFFSET for my phone is actually defined: 0x12200000. Hooray!

Of course, I didn’t even know I was looking for PHYS_OFFSET at the time, I was just looking for anything that looked like a memory address. For you, it should be much easier, and it shouldn’t matter whether your kernel source is organized like LG’s or not. Just grep all of arch/arm for PHYS_OFFSET and that should lead you to your base address.

The best part is, once I had my answer, Googling for “12200000” returned all sorts of useful info, if I’d only had the solution to start with. The kicker is that, had I only read the very same forum thread I linked above all the way through, I would have found more than enough info to track down the answer!

Sort of like, if you want to know the meaning of life and you Google for it, you turn up all sorts of garbage. But once you know the answer is 42, the question is easy to find.

Which, now that I think about it, is basically how Watson works. But that’s going way off topic.

While we’re at it

Can’t leave without mentioning one of my favorite hobbyhorses, compression. When you’re gzipping your ramdisk (or almost anything else you’re just zipping once like this), use “gzip -9“!

(And then, if you’re a nut like me, advdef -z -4 to deflate the resulting file a few percent more.)

Not that it makes a huge difference in the case of the ramdisk (39K saved in my 863K gzipped ramdisk), but I’ve read umpteen posts on the subject in the 24 hours, and nobody does it. The “-9” is only 3 extra characters to type!

So many Android ROM packagers like to say how many megabytes they’ve shaved off the stock OS to free up space in /data, but then their APKs are all zipped with default settings.

I recompressed my APKs with the 7z deflate algorithm (either use 7z to make your .zips, or advzip -z -4 them) and freed up 9 MB just in /data/app (or 12%, I started with 76 MB). That’s 9 MB for free, on my /data which had only 35 MB left.

Sure, anybody can do this, but it’s not the user’s job to re-zip their apps. Android developers, you can do better!

Filed under: Systems.  Tagged: , , .


  • […] building your own Android kernel, the last step in the process is to pack the kernel binary… [full post] sticks lyncd codeandroidsystems 0 0 0 0 0 [15 […]

  • Thanks a ton for this post. I was unsure why my boot.img was not working on the Viewpad 7 and with the help of this post, the viewpad was up and running with my recompiled kernel in a matter of minutes.

    Thank you!
    Thank you!
    Thank you!

  • Thank you x 1000!!
    That answered the million-dollar question: “Why my fucking spanking-new boot.img doesn’t work!”

  • Hmmm… It’s 0x00200000 for my Huawei U8150. Great tip :)

  • Thanks for the comments, everybody. I know this is an obscure problem, but it took me long enough to figure out that I thought posting it would help somebody. Glad it has!

  • I *wish* I had seen this before I devolved into comparing a stock boot image against the output of mkbootimg in a hex editor and manually calculating the difference – your process was much more rational. What would have helped is some sort of a comment in mkbootimg.c mentioning CONFIG_PHYS_OFFSET around line 117 instead of just /* default load addresses */. Thanks for the explanation of your process.


    0x48000000 for boot.img (kernel 3.0.16)
    0x40400000 for recovery.img (kernel 2.6.35)