Firefox OS/Performance/Modifying boot.img: Difference between revisions
Line 23: | Line 23: | ||
unmkbootimg boot.img | unmkbootimg boot.img | ||
</pre> <!--./unmkbootimg --kernel zImage --ramdisk initramfs.cpio.gz --input boot.img--> | </pre> <!--./unmkbootimg --kernel zImage --ramdisk initramfs.cpio.gz --input boot.img--> | ||
Along with outputting the files <code>zImage</code> (the kernel) and <code>initramfs.cpio.gz</code> (the ramdisk), this | Along with outputting the files <code>zImage</code> (the kernel) and <code>initramfs.cpio.gz</code> (the ramdisk), this program also displays the required command to rebuild the boot partition with the same configuration it was found in, e.g.: | ||
<pre> | <pre> | ||
mkbootimg --kernel zImage --ramdisk initramfs.cpio.gz --base 0 --pagesize 2048 --cmdline 'androidboot.hardware=aphone' -o new_boot.img | mkbootimg --kernel zImage --ramdisk initramfs.cpio.gz --base 0 --pagesize 2048 --cmdline 'androidboot.hardware=aphone' -o new_boot.img |
Revision as of 17:12, 16 July 2014
Modifying boot.img
This page is meant to illustrate the general steps necessary to make changes to the ramdisk in the boot partition of the device. This may be desired for a number of reasons such as making changes to the init rc scripts or the init program itself, without changing the kernel.
Ideally, the build system would build the kernel and ramdisk, and then create a boot.img which one could then flash. In this case, it's simply a matter of making whatever changes are necessary (and of course init would be automatically included as well). On the flame however, it was not quite so easy.
Obtaining a boot.img
To retrieve the boot.img from the device one can simply find the boot partition in the filesystem, and use |adb pull|
.
For the flame, for example:
adb pull /dev/block/platform/msm_sdcc.1/by-name/boot .
Where the file specified above is a friendly symlink to |/dev/block/mmcblk0p7|
. For certain other devices (such as the hamachi) the partitions lived under |/dev/mtd/|
and the mappings could be found by executing |cat /proc/mtd|
on the device.
Alternatively
If one already has an image from the OEM or elsewhere, pulling the boot partition from the device is not necessary.
Splitting apart the boot.img
The boot partition contains 2-3 distinct entities: The kernel, the ramdisk, and optionally based on how the kernel was configured, the device tree binary. The instructions outlined here for unpacking a boot.img are mostly sufficient, except it does not account for the device tree section (which is necessary on a Flame). For more information on the structure of this partition in general see: https://github.com/xiaolu/mkbootimg_tools/blob/master/dtbtool.txt .
To get the kernel and the ramdisk from the boot.img, one can make use of the tool unmkbootimg invoked as such:
unmkbootimg boot.img
Along with outputting the files zImage
(the kernel) and initramfs.cpio.gz
(the ramdisk), this program also displays the required command to rebuild the boot partition with the same configuration it was found in, e.g.:
mkbootimg --kernel zImage --ramdisk initramfs.cpio.gz --base 0 --pagesize 2048 --cmdline 'androidboot.hardware=aphone' -o new_boot.img
If you are going through this procedure it is unlikely that you want to change the kernel, but you will want the ramdisk for later, so it would be wise to keep those files emitted from unmkbootimg
somewhere safe.
The device tree binary is the last section (after which is zero padding if the image was pulled from the device). A device tree is basically a data structure for describing the hardware of the device to the kernel, and It is generally compiled to a binary format more suitable for machines to read than humans. It signals its beginning in the boot partition with the 4 byte magic |QCDT|
. To extract this blob I simply used dd on the partition image skipping to whatever offset the magic was found at, and then trimming the trailing zeros similarly. A command such as this can be used to find the offset:
strings -o boot.img | grep QCDT | awk '{print $1}'
And then one can use dd as such:
dd if=boot.img of=dtblob skip='$DT_OFFSET' bs=1
This is not the most elegant of procedures, however I have not as of yet found a better way. (The correct solution I suppose would be extending the unmkbootimg
utility appropriately).
So now that we have all three parts we continue on. We will keep the kernel and device tree around unchanged for rebuilding the boot.img. The ramdisk on the other hand, we will unpack into a directory, make changes, and repackage. This is where files such as init and init.rc (and various other *.rc's) live.
Firstly, unpack the ramdisk into a directory:
mkdir initramfs_dir cd initramfs_dir gunzip -c ../initramfs.cpio.gz | cpio -i
Make the desired changes (such as replacing init and modifying init.rc), and then repackage:
$SRC_TOP/out/host/$HOST_NAME/bin/mkbootfs . | gzip > ../newinitramfs.cpio.gz
One can make the mkbootfs
tool by invoking |./build.sh mkbootfs|
from the FirefoxOS source tree;
Now with the command we got from the unmkbootimg
utility, we can reconstruct the partition using mkbootimg
such that it retains the same settings and kernel parameters. As well, if applicable make sure to add |--dt dtblobname|
to the end of the command. The utility mkbootimg
can be built in the FirefoxOS source tree by invoking |./build.sh mkbootimg|
and the resulting binary is found in |$SRC_TOP/out/host/$HOST_NAME/bin/|