mirror of
https://github.com/ggrandou/abootimg.git
synced 2024-11-23 09:53:32 +08:00
293 lines
8.0 KiB
Plaintext
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, ...)
|
||
|
|
||
|
|