Unpack/repack boot.img/ramdisk for Android

Dissection of a boot image

As declared in mkbootimg/bootimg.h:

/*
** +-----------------+ 
** | 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
#define BOOT_MAGIC "ANDROID!"

struct boot_img_hdr
{
    unsigned char magic[BOOT_MAGIC_SIZE];

    unsigned kernel_size;  /* size in bytes */
    unsigned kernel_addr;  /* physical load addr */

    unsigned ramdisk_size; /* size in bytes */
    unsigned ramdisk_addr; /* physical load addr */

    unsigned second_size;  /* size in bytes */
    unsigned second_addr;  /* physical load addr */

    unsigned tags_addr;    /* physical addr for kernel tags */
    unsigned page_size;    /* flash page size we assume */
    unsigned unused[2];    /* future expansion: should be 0 */

    unsigned char name[BOOT_NAME_SIZE]; /* asciiz product name */

    unsigned char cmdline[BOOT_ARGS_SIZE];

    unsigned id[8]; /* timestamp / checksum / sha1 / etc */
};

 

Unpack boot.img

note: if you have only ramdisk you can exec only number 10

  1. Open boot.img with hex editor
  2. Make sure you find android magic “ANDROID!” and delete all before that
  3. Check if the header is 2K or 4K (check when kerner starts many 00s followed by data)
  4. Remove header
  5. Find GZIP majic ([00 00 1F 8B])
  6. Copy all before [1F 8B] to kernel.img
  7. Copy all after including [1F 8B] to ramdisk.img
  8. mkdir ramdisk
  9. cd ramdisk
  10. gunzip -c ../ramdisk.img | cpio -i

Pack boot.img

note: if you want to pack just the ramdisk you can exec only number 1

  1. (in ramdisk dir) find . | cpio -o -H newc | gzip > ../ramdisk.img
  2. cd ..
  3. mkbootimg –cmdline ” –board ” –kernel boot.img-kernel –ramdisk ramdisk.img –base 0x10000000 –pagesize 2048 –kernel_offset 0x00008000 –ramdisk_offset 0x01000000 -o new_boot.img

The parameters cmdline, board, pagesize, kernel_offset, ramdisk_offset may vary and can be obtained from the header as shown above.

The parameter base(physical base address) can can be relatively calculated from the other values or obtained as explained in this article.

mkbootimg binary can be downloaded from here: http://web.djodjo.org/?a=download:android:tools:x86_linux:alltools. There you can also find unsecurebootimg.pl, which can unpack boot image or just ramdisk image and also perform some changes to make boot image with insecure adb settings and pack it again.

enjoy 🙂