summaryrefslogtreecommitdiffstats
path: root/mkbootimg
diff options
context:
space:
mode:
authorHridya Valsaraju <hridya@google.com>2018-03-20 15:26:00 -0700
committerHridya Valsaraju <hridya@google.com>2018-03-28 12:53:21 -0700
commit147b355bb34cbd457a260c585be93193cef43b8e (patch)
tree8d03d64931ab6d4bf693fc27bd1fde4d72584019 /mkbootimg
parent7102f7c98d2aaa393cc6ddc44cf277c5b9b71bf1 (diff)
downloadsystem_core-147b355bb34cbd457a260c585be93193cef43b8e.tar.gz
system_core-147b355bb34cbd457a260c585be93193cef43b8e.tar.bz2
system_core-147b355bb34cbd457a260c585be93193cef43b8e.zip
Add a recovery DTBO section to boot image
For non-A/B devices, the recovery partition should be self-sufficient and not depend on any other partition. Since recovery may need access to devices added to the DT by overlays(for eg.display), we need to make sure that the the recovery image also contains the information from the DTBO image. The following fields are added to the boot image header for this purpose: -boot header version -header size -recovery dtbo size -recovery dtbo address Bug: 74763691 Test: unpack_bootimage --boot_img $OUT/recovery.img diff out/extracted_dtbo $TOP/device/google/wahoo-kernel/dtbo.img Change-Id: I1969859038b84fac1e4a71f79f2f546b9cacffc8
Diffstat (limited to 'mkbootimg')
-rw-r--r--mkbootimg/bootimg.h113
-rwxr-xr-xmkbootimg/mkbootimg18
2 files changed, 100 insertions, 31 deletions
diff --git a/mkbootimg/bootimg.h b/mkbootimg/bootimg.h
index 60834fed9..1be8c229c 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 @@ struct boot_img_hdr
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 @@ struct boot_img_hdr
} __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 5a13da26b..ac20d0503 100755
--- a/mkbootimg/mkbootimg
+++ b/mkbootimg/mkbootimg
@@ -57,7 +57,7 @@ def write_header(args):
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 @@ def write_header(args):
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 @@ def parse_cmdline():
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 @@ def parse_cmdline():
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 @@ def parse_cmdline():
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 @@ def write_data(args):
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()