Add a recovery DTBO section to boot image am: 147b355bb3
am: 86f4bafa5e
Change-Id: I8c0a7b66977c002987546d338046d2d32c57017d
diff --git a/mkbootimg/bootimg.h b/mkbootimg/bootimg.h
index 60834fe..1be8c22 100644
--- a/mkbootimg/bootimg.h
+++ b/mkbootimg/bootimg.h
@@ -20,16 +20,18 @@
#ifndef _BOOT_IMAGE_H_
#define _BOOT_IMAGE_H_
-typedef struct boot_img_hdr boot_img_hdr;
-
#define BOOT_MAGIC "ANDROID!"
#define BOOT_MAGIC_SIZE 8
#define BOOT_NAME_SIZE 16
#define BOOT_ARGS_SIZE 512
#define BOOT_EXTRA_ARGS_SIZE 1024
-struct boot_img_hdr
-{
+#define BOOT_HEADER_VERSION_ZERO 0
+/*
+ * Bootloader expects the structure of boot_img_hdr with header version
+ * BOOT_HEADER_VERSION_ZERO to be as follows:
+ */
+struct boot_img_hdr_v0 {
uint8_t magic[BOOT_MAGIC_SIZE];
uint32_t kernel_size; /* size in bytes */
@@ -43,7 +45,10 @@
uint32_t tags_addr; /* physical addr for kernel tags */
uint32_t page_size; /* flash page size we assume */
- uint32_t unused; /* reserved for future expansion: MUST be 0 */
+ /*
+ * version for the boot image header.
+ */
+ uint32_t header_version;
/* operating system version and security patch level; for
* version "A.B.C" and patch level "Y-M-D":
@@ -64,31 +69,79 @@
} __attribute__((packed));
/*
-** +-----------------+
-** | 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
-**
-** 0. all entities are page_size aligned in flash
-** 1. kernel and ramdisk are required (size != 0)
-** 2. second is optional (second_size == 0 -> no second)
-** 3. load each element (kernel, ramdisk, second) at
-** the specified physical address (kernel_addr, etc)
-** 4. prepare tags at tag_addr. kernel_args[] is
-** appended to the kernel commandline in the tags.
-** 5. r0 = 0, r1 = MACHINE_TYPE, r2 = tags_addr
-** 6. if second_size != 0: jump to second_addr
-** else: jump to kernel_addr
-*/
+ * It is expected that callers would explicitly specify which version of the
+ * boot image header they need to use.
+ */
+typedef struct boot_img_hdr_v0 boot_img_hdr;
+
+/* When a boot header is of version BOOT_HEADER_VERSION_ZERO, the structure of boot image is as
+ * follows:
+ *
+ * +-----------------+
+ * | 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
+ *
+ * 0. all entities are page_size aligned in flash
+ * 1. kernel and ramdisk are required (size != 0)
+ * 2. second is optional (second_size == 0 -> no second)
+ * 3. load each element (kernel, ramdisk, second) at
+ * the specified physical address (kernel_addr, etc)
+ * 4. prepare tags at tag_addr. kernel_args[] is
+ * appended to the kernel commandline in the tags.
+ * 5. r0 = 0, r1 = MACHINE_TYPE, r2 = tags_addr
+ * 6. if second_size != 0: jump to second_addr
+ * else: jump to kernel_addr
+ */
+
+#define BOOT_HEADER_VERSION_ONE 1
+
+struct boot_img_hdr_v1 : public boot_img_hdr_v0 {
+ uint32_t recovery_dtbo_size; /* size in bytes for recovery DTBO image */
+ uint64_t recovery_dtbo_offset; /* physical load addr */
+ uint32_t header_size;
+} __attribute__((packed));
+
+/* When the boot image header has a version of BOOT_HEADER_VERSION_ONE, the structure of the boot
+ * image is as follows:
+ *
+ * +-----------------+
+ * | boot header | 1 page
+ * +-----------------+
+ * | kernel | n pages
+ * +-----------------+
+ * | ramdisk | m pages
+ * +-----------------+
+ * | second stage | o pages
+ * +-----------------+
+ * | recovery dtbo | p 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
+ * p = (recovery_dtbo_size + page_size - 1) / page_size
+ *
+ * 0. all entities are page_size aligned in flash
+ * 1. kernel and ramdisk are required (size != 0)
+ * 2. recovery_dtbo is required for recovery.img in non-A/B devices(recovery_dtbo_size != 0)
+ * 3. second is optional (second_size == 0 -> no second)
+ * 4. load each element (kernel, ramdisk, second, recovery_dtbo) at
+ * the specified physical address (kernel_addr, etc)
+ * 5. prepare tags at tag_addr. kernel_args[] is
+ * appended to the kernel commandline in the tags.
+ * 6. r0 = 0, r1 = MACHINE_TYPE, r2 = tags_addr
+ * 7. if second_size != 0: jump to second_addr
+ * else: jump to kernel_addr
+ */
#if 0
typedef struct ptentry ptentry;
diff --git a/mkbootimg/mkbootimg b/mkbootimg/mkbootimg
index 5a13da2..ac20d05 100755
--- a/mkbootimg/mkbootimg
+++ b/mkbootimg/mkbootimg
@@ -57,7 +57,7 @@
args.base + args.second_offset, # physical load addr
args.base + args.tags_offset, # physical addr for kernel tags
args.pagesize, # flash page size we assume
- 0, # future expansion: MUST be 0
+ args.header_version, # version of bootimage header
(args.os_version << 11) | args.os_patch_level)) # os version and patch level
args.output.write(pack('16s', args.board.encode())) # asciiz product name
args.output.write(pack('512s', args.cmdline[:512].encode()))
@@ -66,10 +66,20 @@
update_sha(sha, args.kernel)
update_sha(sha, args.ramdisk)
update_sha(sha, args.second)
+
+ if args.header_version > 0:
+ update_sha(sha, args.recovery_dtbo)
+
img_id = pack('32s', sha.digest())
args.output.write(img_id)
args.output.write(pack('1024s', args.cmdline[512:].encode()))
+
+ if args.header_version > 0:
+ args.output.write(pack('I', filesize(args.recovery_dtbo))) # size in bytes
+ args.output.write(pack('Q', args.base + args.recovery_dtbo_offset)) # physical load addr
+ args.output.write(pack('I', args.output.tell() + 4)) # size of boot header
+
pad_file(args.output, args.pagesize)
return img_id
@@ -132,6 +142,7 @@
required=True)
parser.add_argument('--ramdisk', help='path to the ramdisk', type=FileType('rb'))
parser.add_argument('--second', help='path to the 2nd bootloader', type=FileType('rb'))
+ parser.add_argument('--recovery_dtbo', help='path to the recovery DTBO', type=FileType('rb'))
parser.add_argument('--cmdline', help='extra arguments to be passed on the '
'kernel command line', default='', action=ValidateStrLenAction, maxlen=1536)
parser.add_argument('--base', help='base address', type=parse_int, default=0x10000000)
@@ -139,6 +150,8 @@
parser.add_argument('--ramdisk_offset', help='ramdisk offset', type=parse_int, default=0x01000000)
parser.add_argument('--second_offset', help='2nd bootloader offset', type=parse_int,
default=0x00f00000)
+ parser.add_argument('--recovery_dtbo_offset', help='recovery dtbo offset', type=parse_int,
+ default=0x0f000000)
parser.add_argument('--os_version', help='operating system version', type=parse_os_version,
default=0)
parser.add_argument('--os_patch_level', help='operating system patch level',
@@ -150,6 +163,7 @@
choices=[2**i for i in range(11,15)], default=2048)
parser.add_argument('--id', help='print the image ID on standard output',
action='store_true')
+ parser.add_argument('--header_version', help='boot image header version', type=parse_int, default=0)
parser.add_argument('-o', '--output', help='output file name', type=FileType('wb'),
required=True)
return parser.parse_args()
@@ -160,6 +174,8 @@
write_padded_file(args.output, args.ramdisk, args.pagesize)
write_padded_file(args.output, args.second, args.pagesize)
+ if args.header_version > 0:
+ write_padded_file(args.output, args.recovery_dtbo, args.pagesize)
def main():
args = parse_cmdline()