abootimg/README
2010-11-26 11:09:19 +01:00

293 lines
8.0 KiB
Plaintext

abootimg - manipulate Android Boot Images.
------------------------------------------
(c) 2010 Gilles Grandou <gilles@grandou.net>
* Android Boot Images
---------------------
It a special partition format defined by the Android Open Source Porject.
See bootimg.h in the source tree for more information about the structure.
It's used by Android Bootloaders to boot the OS.
Boot images mainly convey:
- a kernel image
- a ramdisk image
- optionaly, a 2nd stage bootloader
- the cmdline passed to the kernel when booting.
The official tool used to create boot images is part of the Android Project,
available here:
http://android.git.kernel.org/?p=platform/system/core.git;a=tree;f=mkbootimg
abootimg can work directly on block devices, or, the safest way, on a file image.
File images can be read/written with dd:
$ dd if=/dev/mmcblk0p2 of=boot.img
$ dd if=boot.img of=/dev/mmcblk0p2
You obviously need to have right access to the block device (using su, sudo,
...).
Android Boot Image contains an 32 bytes Id. The specification does not actually
mandates any specific implementation of this Id (it can be a timestamp, a CRC
checksum, a SHA hash, ...). Bootloader appears to do nothing of this Id, it's
solely here for tracking purpose. Currently abootimg does nothing with it, it's
never touched/modified.
* Building abootimg
-------------------
On a linux system, it's simply as:
$ make
blkid library is needed to perform some sanity checks when writing boot image
directly on a block device (to avoid writing a valid existing filesystem).
* Looking at an Android Boot Image
----------------------------------
Basic Information can be extracted from a boot image, using:
$ abootimg -i <bootimg>
Here is an example:
$ ./abootimg -i boot.img
Android Boot Image Info:
* file name = boot.img
* image size = 8388608 bytes (8.00 MB)
page size = 2048 bytes
* Boot Name = ""
* kernel size = 3002744 bytes (2.86 MB)
ramdisk size = 1639626 bytes (1.56 MB)
* load addresses:
kernel: 0x10008000
ramdisk: 0x11000000
tags: 0x10000100
* cmdline = mem=448M@0M nvmem=64M@448M vmalloc=320M video=tegrafb console=tty0 usbcore.old_scheme_first=1 quiet splash elevator=noop tegraboot=sdmmc cmdpart=1:7168:10240,2:17408:16384,3:35840:614400,4:4004864:27096064
* id = 0x07571070 0x13950a6a 0x185c996f 0x9ab7b64d 0xcccd09bd 0x00000000 0x00000000 0x00000000
* Extracting elements from an Android Boot Image
------------------------------------------------
All parts of boot image can be extracted with:
$ abootimg -x <bootimg> [<bootimg.cfg> [<kernel> [<ramdisk> [<secondstage>]]]]
Parts name are optional. Default ones are used if none are given:
* bootimg.cfg for the configuration file
* zImage for the Kernel image
* initrd.img for the Ramdisk
* stage2.img for the Second Stage image
Here is an example:
$ abootimg -x boot.img
writing boot image config in bootimg.cfg
extracting kernel in zImage
extracting ramdisk in initrd.img
* Boot Configuration file
-------------------------
It's an editable ascii file which is basically a dump of the header content,
to be able to rebuild a compatible image later.
Each entry takes one line and is in the form of:
<entry> = <value>
You can put any number of spaces/tab before/after the =
<value> is evalued starting from the fisrt non space character following the =
until the end of line
Numerical values can be given in decimal (12345) or hexadecimal (0x1234abcd).
Known configuration entries are:
* bootsize
Indicate the size of the boot image to produce
* pagesize
All sizes have to be a multiple of the page size.
Standard page size is 2048 bytes. I don't know if other page size
are supported by Android bootloader
* kerneladdr, ramdiskaddr, secondaddr, tagsaddr
Address in RAM used to load the kernel, ramdisk, 2nd stage
bootloader, and tags table.
* name
name given to the boot image.
not really used by bootloader, but it's can be usefull to keep
track of what the image actually contains
* cmdline
contains the command line passed to the kernel when booting
* Updating an existing Android Boot Image
-----------------------------------------
An existing valid Boot Image can be updated with:
$ abootimg -u <bootimg> [-c "param=value"] [-f <bootimg.cfg>] [-k <kernel>] [-r <ramdisk>] [-s <secondstage>]
Any part of the image can be individully updated. As an example:
$ abootimg -u boot.img -k zImage.new
will update the kernel
$ abootimg -u boot.img -r initrd.new.img
will update the image
$ abootimg -u boot.img -k zImage.new -r initrd.new.img
will update both
Image configuration can be updated either by giving a configuration file
(-f option) or by giving individual config entries on the command line (-c).
Severial config entries (-c) can be given on comamd line.
As an example:
$ abootimg -u boot.img -f bootimg.new.cfg
will update the configuration without touching the kernel
nor the ramdisk
$ abootimg -u boot.img -c "cmdline = mem=448M@0M nvmem=64M@448M vmalloc=320M \
video=tegrafb console=tty0 usbcore.old_scheme_first=1 quiet splash elevator=noop \
tegraboot=sdmmc tegrapart=recovery:700:a00:800,boot:1100:1000:800,mbr:2100:200:800,\
system:2300:25800:800,cache:27b00:32000:800,misc:59b00:400:800,userdata:5a000:9a600:800"
update the boot conmand line
$ abootimg -u boot.img -c "bootsize=0x500000"
update the boot image size to 5MB.
It's usefull if you want to shrink an existing image to make it
fit in another smaller boot partition.
(On Toshiba AC100, it allows you to take a part06.img and
transform it to fit inside part05)
The original boot image has to be valid, otherwise abootimg will refuse to
update it.
* Creating a new Android Boot Image from scratch
------------------------------------------------
A new boot image can be create with:
$ abootimg --create <bootimg> [-c "param=value"] [-f <bootimg.cfg>] -k <kernel> -r <ramdisk> [-s <secondstage>]
Parameters are the same than above for update. The only difference is that
kernel and ramdisk are mandatory.
* Working directly of Block Devices
-----------------------------------
Instead of manipulating Boot Image regular file, you can work directly on boot
block device.
Note that, on AC100, the current kernel needs to be patched in order to have
direct access to boot partitions (partitions 5 and 6).
Some examples:
$ sudo abootimg -i /dev/mmcblk0p2
read the current boot partition
$ sudo abootimg -u /dev/mmcblk0p2 -k arch/arm/boot/zImage
update the boot partition with the kernel you have just built
$ sudo abootimg -u /dev/mmcblk0p2 -c "cmdline=..."
update the boot partition with a new boot cmdline
$ sudo abootimg --create /dev/mmcblk0p2 -f boot.cfg -k zImage -r initrd.img
overwrite the boot partition (which can be damaged) with a
brand new image
If abootimg has to write to a block device (-u and --create), some sanity
check are performed:
* you oviously need read/write access to the block device (so use su,
sudo, ...)
* the actual partition must not be identified as containing a valid
filesystem as recognised by blkid library. Specifically, it cannot
contains a ext2/3 filesystem (this avoids you to ovewrite your root
filesystem by mistake)
* the updated/created boot image has to be same size than the block
device you try to write on.
* in case of update, the current boot partition has to contain a valid
Android Boot Image.
Failing any of these tests will abort the operation on block device.
It's by definition more risky to manipulate block device, as a bad
manipulation can as bad manipulation can make your system unbootable if you
don't fix it before the next reboot.
On the other hand, manipulating the block device allows abootimg to prevent
most of the stupid mistakes which can be made when writing boot image with dd
(overwriting another filesystem, writing a boot image bigger than the
partition, writing the wrong file or an invalid partition, ...)