Splitting and Packing Android Boot images

After wandering twisty little passages, all alike concerning rooting Android devices I decided the best way forward for devices with unlocked bootloaders was to root via modifying the default.prop values in the boot image. There are a number of different scripts available on various sites which purport to unpack and pack Android boot images, but it seemed that the best approach was to go to the source and see how Android dealt with boot images.

I created spbootimg and pkbootimg from the official mkbootimg in order that it would properly handle official android boot images at least.

spbootimg

usage: spbootimg
       -i|--input 

spbootimg splits an Android boot image file into separate files:

* <bootimg-filename>-kernel – kernel
* <bootimg-filename>-first-ramdisk – ramdisk
* <bootimg-filename>-second-ramdisk – only created if it existed in the input boot image file.
* <bootimg-filename-header> – text file containing constants discovered in the boot image

You can download the source for spbootimg and pkbootimg and build it yourself. I don’t provide binaries because I do not wish people who do not understand the consequences of their actions to brick their devices.

pkbootimg

usage: pkbootimg
       --kernel 
       --kernel-addr 
--ramdisk --ramdisk-addr
[ --second <2ndbootloader-filename>] [ --cmdline ] [ --board ] [ --pagesize ] --second-addr
--tags-addr
-o|--output

pkbootimg takes the output of spbootimg: a kernel file, a ramdisk file, an optional ramdisk file; and using the command line, board, page size and address information discovered in the original boot image, packs them into a new boot image which can be flashed onto a device using fastboot.

default.prop

Looking at the source for adb.c, we see that at a minimum we need a build of adb where ALLOW_ADBD_ROOT was set and either of the following was set in the ramdisk’s default.prop:

ro.secure=0

or

ro.debuggable=1
service.adb.root=1

ro.secure=0 will result in adbd running as root by default. ro.debuggable=1 and service.adb.root=1 will allow you to run adbd as root via the adb root command.

If your device’s version of adb was not built with ALLOW_ADBD_ROOT set, you will need to build your own version and place it in the ramdisk at sbin/adbd.

Once you are able to run adb as root via adb root, you will be able to remount the /system/ directory as writable and can install anything you wish.

su

Some of the automation used in mozilla requires the use of a version of the su command which has the same command line syntax as sh. In particular, we require that su support calling commands via su -c "command args...". You can possibly build your own version of su which will run commands as root without access control or you can use one of the available “Superuser” apps which manage access to su and provide some degree of security. I’ve found Koushik Dutta’s Superuser to work well with Android up to 4.4.

If you use Koushik’s Superuser, you will need at least version 1.0.3.0 and will need to make sure that the install-recovery.sh script is properly installed so that Koushik’s su runs as a daemon. This is automatically handled if you install Superuser.apk via a recovery image, but if you install Superuser manually, you will need to make sure to unpack Superuser.apk and manually install:

  • su to /system/xbin/su
  • install-recovery.sh to /system/etc/install-recovery.sh
  • Superuser.apk to /system/app/Superuser.apk