├── .gitignore ├── .github └── FUNDING.yml ├── Makefile ├── NOTICE ├── bootimg-info.c └── bootimg.h /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | bootimg-info.exe 3 | bootimg-info 4 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: osm0sis # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: https://www.paypal.me/osm0sis # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ifeq ($(CC),cc) 2 | CC = gcc 3 | endif 4 | AR = ar rc 5 | ifeq ($(windir),) 6 | EXT = 7 | RM = rm -f 8 | CP = cp 9 | else 10 | EXT = .exe 11 | RM = del 12 | CP = copy /y 13 | endif 14 | 15 | CFLAGS += -ffunction-sections -O3 16 | 17 | INC = -I. 18 | 19 | ifneq (,$(findstring darwin,$(CROSS_COMPILE))) 20 | UNAME_S := Darwin 21 | else 22 | UNAME_S := $(shell uname -s) 23 | endif 24 | ifeq ($(UNAME_S),Darwin) 25 | LDFLAGS += -Wl,-dead_strip 26 | else 27 | LDFLAGS += -Wl,--gc-sections -s 28 | endif 29 | 30 | all:bootimg-info$(EXT) 31 | 32 | static: 33 | $(MAKE) CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS) -static" 34 | 35 | bootimg-info$(EXT):bootimg-info.o 36 | $(CROSS_COMPILE)$(CC) -o $@ $^ $(LDFLAGS) 37 | 38 | %.o:%.c 39 | $(CROSS_COMPILE)$(CC) -o $@ $(CFLAGS) -c $< $(INC) -Werror 40 | 41 | install: 42 | install -m 755 bootimg-info$(EXT) $(PREFIX)/bin 43 | 44 | clean: 45 | $(RM) bootimg-info 46 | $(RM) *.a *.~ *.exe *.o 47 | 48 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Adapted from unpackbootimg, Copyright 2014, CyanogenMod 2 | 3 | Portions Copyright 2008, The Android Open Source Project 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | * Neither the name of Google Inc. nor the names of its contributors may 13 | be used to endorse or promote products derived from this software 14 | without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR 17 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 | EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 | OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 | OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /bootimg-info.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "bootimg.h" 6 | 7 | int usage() 8 | { 9 | printf("usage: bootimg-info boot.img\n"); 10 | return 1; 11 | } 12 | 13 | void print_os_version(uint32_t hdr_os_ver) 14 | { 15 | int a = 0, b = 0, c = 0, y = 0, m = 0; 16 | if (hdr_os_ver != 0) { 17 | int os_version = 0, os_patch_level = 0; 18 | os_version = hdr_os_ver >> 11; 19 | os_patch_level = hdr_os_ver&0x7ff; 20 | 21 | a = (os_version >> 14)&0x7f; 22 | b = (os_version >> 7)&0x7f; 23 | c = os_version&0x7f; 24 | 25 | y = (os_patch_level >> 4) + 2000; 26 | m = os_patch_level&0xf; 27 | } 28 | if ((a < 128) && (b < 128) && (c < 128) && (y >= 2000) && (y < 2128) && (m > 0) && (m <= 12)) { 29 | printf(" os_version : %d.%d.%-5d (%08x)\n", a, b, c, hdr_os_ver); 30 | printf(" (os_patch_level) : %d-%02d\n", y, m); 31 | } else { 32 | printf(" unused : %-10d (%08x)\n", hdr_os_ver, hdr_os_ver); 33 | } 34 | } 35 | 36 | void print_id(boot_img_hdr_v2 *hdr) 37 | { 38 | int SHA256_DIGEST_SIZE = 32; 39 | uint8_t id[SHA256_DIGEST_SIZE]; 40 | memcpy(&id, hdr->id, sizeof(id)); 41 | printf(" id : "); 42 | int i; 43 | for (i = 0; i < SHA256_DIGEST_SIZE; ++i) { 44 | printf("%02hhx", id[i]); 45 | } 46 | printf("\n\n"); 47 | } 48 | 49 | int main(int argc, char** argv) 50 | { 51 | char *filename = NULL; 52 | argc--; 53 | if (argc > 0) { 54 | char *val = argv[1]; 55 | filename = val; 56 | } 57 | if (filename == NULL) { 58 | return usage(); 59 | } 60 | FILE *f = fopen(filename, "rb"); 61 | if (!f) { 62 | printf("bootimg-info: File not found!\n"); 63 | return 1; 64 | } 65 | 66 | char tmp[BOOT_MAGIC_SIZE]; 67 | char *magic = NULL; 68 | 69 | int i; 70 | int seeklimit = 65536; // arbitrary byte limit to search in input file for boot image magic 71 | for (i = 0; i <= seeklimit; i++) { 72 | fseek(f, i, SEEK_SET); 73 | if(fread(tmp, BOOT_MAGIC_SIZE, 1, f)){}; 74 | if (memcmp(tmp, BOOT_MAGIC, BOOT_MAGIC_SIZE) == 0) { 75 | magic = BOOT_MAGIC; 76 | break; 77 | } 78 | if (memcmp(tmp, VENDOR_BOOT_MAGIC, VENDOR_BOOT_MAGIC_SIZE) == 0) { 79 | magic = VENDOR_BOOT_MAGIC; 80 | break; 81 | } 82 | } 83 | if (i > seeklimit) { 84 | printf("bootimg-info: No boot image magic found!\n"); 85 | return 1; 86 | } 87 | 88 | printf(" Android Boot Image Info Utility\n\n"); 89 | 90 | printf(" Printing information for \"%s\":\n\n", filename); 91 | 92 | printf(" header:\n"); 93 | 94 | boot_img_hdr_v4 header; 95 | fseek(f, i, SEEK_SET); 96 | if(fread(&header, sizeof(header), 1, f)){}; 97 | 98 | int hdr_ver_max = 8; // arbitrary maximum header version value; when greater assume the field is appended dt size 99 | 100 | int base = 0; 101 | 102 | if (!strcmp(magic, BOOT_MAGIC)) { 103 | if ((header.header_version < 3) || (header.header_version > hdr_ver_max)) { 104 | // boot_img_hdr_v2 in the backported header supports all boot_img_hdr versions and cross-compatible variants below 3 105 | 106 | fseek(f, i, SEEK_SET); 107 | boot_img_hdr_v2 header; 108 | if(fread(&header, sizeof(header), 1, f)){}; 109 | 110 | base = header.kernel_addr - 0x00008000; 111 | 112 | printf(" magic : ANDROID!\n"); 113 | printf(" kernel_size : %-10d (%08x)\n", header.kernel_size, header.kernel_size); 114 | printf(" kernel_addr : 0x%08x\n\n", header.kernel_addr); 115 | 116 | printf(" ramdisk_size : %-10d (%08x)\n", header.ramdisk_size, header.ramdisk_size); 117 | printf(" ramdisk_addr : 0x%08x\n", header.ramdisk_addr); 118 | printf(" second_size : %-10d (%08x)\n", header.second_size, header.second_size); 119 | printf(" second_addr : 0x%08x\n\n", header.second_addr); 120 | 121 | printf(" tags_addr : 0x%08x\n", header.tags_addr); 122 | printf(" page_size : %-10d (%08x)\n", header.page_size, header.page_size); 123 | if (header.dt_size > hdr_ver_max) { 124 | printf(" dt_size : %-10d (%08x)\n", header.dt_size, header.dt_size); 125 | } else { 126 | printf(" header_version : %-10d (%08x)\n", header.header_version, header.header_version); 127 | } 128 | print_os_version(header.os_version); printf("\n"); 129 | 130 | printf(" name : %s\n\n", header.name); 131 | 132 | printf(" cmdline : %.*s\n\n", BOOT_ARGS_SIZE, header.cmdline); 133 | 134 | print_id(&header); 135 | 136 | printf(" extra_cmdline : %.*s\n\n", BOOT_EXTRA_ARGS_SIZE, header.extra_cmdline); 137 | 138 | if (header.header_version <= hdr_ver_max) { 139 | if (header.header_version > 0) { 140 | printf(" recovery_dtbo_size : %-10d (%08x)\n", header.recovery_dtbo_size, header.recovery_dtbo_size); 141 | printf(" recovery_dtbo_offset : %-10"PRId64" (%016"PRIx64")\n", header.recovery_dtbo_offset, header.recovery_dtbo_offset); 142 | printf(" header_size : %-10d (%08x)\n\n", header.header_size, header.header_size); 143 | } 144 | if (header.header_version > 1) { 145 | printf(" dtb_size : %-10d (%08x)\n", header.dtb_size, header.dtb_size); 146 | printf(" dtb_addr : 0x%08"PRIx64" (%016"PRIx64")\n\n", header.dtb_addr, header.dtb_addr); 147 | } 148 | } 149 | 150 | printf(" Other:\n"); 151 | printf(" magic offset : %-10d (%08x)\n\n", i, i); 152 | printf(" base address : 0x%08x\n\n", base); 153 | 154 | printf(" kernel offset : 0x%08x\n", header.kernel_addr - base); 155 | printf(" ramdisk offset : 0x%08x\n", header.ramdisk_addr - base); 156 | printf(" second offset : 0x%08x\n", header.second_addr - base); 157 | printf(" tags offset : 0x%08x\n", header.tags_addr - base); 158 | if (header.header_version <= hdr_ver_max && header.header_version > 1) { 159 | printf(" dtb offset : 0x%08"PRIx64"\n", header.dtb_addr - base); 160 | } 161 | 162 | } else { 163 | // boot_img_hdr_v3 and above are no longer backwards compatible 164 | 165 | printf(" magic : ANDROID!\n"); 166 | printf(" kernel_size : %-10d (%08x)\n", header.kernel_size, header.kernel_size); 167 | printf(" ramdisk_size : %-10d (%08x)\n\n", header.ramdisk_size, header.ramdisk_size); 168 | 169 | print_os_version(header.os_version); 170 | printf(" header_size : %-10d (%08x)\n", header.header_size, header.header_size); 171 | printf(" reserved[1] : %-10d (%08x)\n", header.reserved[0], header.reserved[0]); 172 | printf(" reserved[2] : %-10d (%08x)\n\n", header.reserved[1], header.reserved[1]); 173 | 174 | printf(" reserved[3] : %-10d (%08x)\n", header.reserved[2], header.reserved[2]); 175 | printf(" reserved[4] : %-10d (%08x)\n", header.reserved[3], header.reserved[3]); 176 | printf(" header_version : %-10d (%08x)\n", header.header_version, header.header_version); 177 | printf(" cmdline : %.*s\n", BOOT_ARGS_SIZE+BOOT_EXTRA_ARGS_SIZE, header.cmdline); 178 | if (header.header_version > 3) { 179 | printf(" signature_size : %-10d (%08x)\n", header.signature_size, header.signature_size); 180 | } 181 | printf("\n"); 182 | 183 | printf(" Other:\n"); 184 | printf(" magic offset : %-10d (%08x)\n", i, i); 185 | } 186 | 187 | } else { 188 | // vendor_boot_img_hdr started at v3 and is not cross-compatible with boot_img_hdr 189 | 190 | fseek(f, i, SEEK_SET); 191 | vendor_boot_img_hdr_v4 header; 192 | if(fread(&header, sizeof(header), 1, f)){}; 193 | 194 | vendor_ramdisk_table_entry_v4 rdt_entry; 195 | int rdt_offset; 196 | int bc_offset; 197 | if (header.header_version > 3) { 198 | rdt_offset = ((header.header_size + header.page_size - 1) / header.page_size 199 | + (header.vendor_ramdisk_size + header.page_size - 1) / header.page_size 200 | + (header.dtb_size + header.page_size - 1) / header.page_size) * header.page_size; 201 | 202 | bc_offset = ((header.header_size + header.page_size - 1) / header.page_size 203 | + (header.vendor_ramdisk_size + header.page_size - 1) / header.page_size 204 | + (header.dtb_size + header.page_size - 1) / header.page_size 205 | + (header.vendor_ramdisk_table_size + header.page_size - 1) / header.page_size) * header.page_size; 206 | } 207 | 208 | base = header.kernel_addr - 0x00008000; 209 | 210 | printf(" magic : VNDRBOOT\n"); 211 | printf(" header_version : %-10d (%08x)\n", header.header_version, header.header_version); 212 | printf(" page_size : %-10d (%08x)\n\n", header.page_size, header.page_size); 213 | 214 | printf(" kernel_addr : 0x%08x\n", header.kernel_addr); 215 | printf(" ramdisk_addr : 0x%08x\n", header.ramdisk_addr); 216 | printf(" vendor_ramdisk_size : %-10d (%08x)\n", header.vendor_ramdisk_size, header.vendor_ramdisk_size); 217 | printf(" cmdline : %.*s\n", VENDOR_BOOT_ARGS_SIZE, header.cmdline); 218 | printf(" tags_addr : 0x%08x\n\n", header.tags_addr); 219 | 220 | printf(" name : %s\n\n", header.name); 221 | 222 | printf(" header_size : %-10d (%08x)\n", header.header_size, header.header_size); 223 | printf(" dtb_size : %-10d (%08x)\n", header.dtb_size, header.dtb_size); 224 | printf(" dtb_addr : 0x%08"PRIx64" (%016"PRIx64")\n\n", header.dtb_addr, header.dtb_addr); 225 | 226 | if (header.header_version > 3) { 227 | printf(" vendor_ramdisk_table_size : %-10d (%08x)\n", header.vendor_ramdisk_table_size, header.vendor_ramdisk_table_size); 228 | printf(" vendor_ramdisk_table_entry_num : %-10d (%08x)\n", header.vendor_ramdisk_table_entry_num, header.vendor_ramdisk_table_entry_num); 229 | printf(" vendor_ramdisk_table_entry_size : %-10d (%08x)\n", header.vendor_ramdisk_table_entry_size, header.vendor_ramdisk_table_entry_size); 230 | printf(" bootconfig_size : %-10d (%08x)\n\n", header.bootconfig_size, header.bootconfig_size); 231 | 232 | fseek(f, rdt_offset, SEEK_SET); 233 | int rdt_entry_cur; 234 | for (rdt_entry_cur = 1; rdt_entry_cur <= header.vendor_ramdisk_table_entry_num; rdt_entry_cur++) { 235 | if(fread(&rdt_entry, header.vendor_ramdisk_table_entry_size, 1, f)){}; 236 | char *rdt_type_name; 237 | switch (rdt_entry.ramdisk_type) { 238 | case 0: 239 | rdt_type_name = "NONE"; 240 | break; 241 | case 1: 242 | rdt_type_name = "PLATFORM"; 243 | break; 244 | case 2: 245 | rdt_type_name = "RECOVERY"; 246 | break; 247 | case 3: 248 | rdt_type_name = "DLKM"; 249 | break; 250 | } 251 | 252 | printf(" vendor_ramdisk_table_entry: %d\n", rdt_entry_cur); 253 | printf(" ramdisk_size : %-10d (%08x)\n", rdt_entry.ramdisk_size, rdt_entry.ramdisk_size); 254 | printf(" ramdisk_offset : %-10d (%08x)\n", rdt_entry.ramdisk_offset, rdt_entry.ramdisk_offset); 255 | printf(" ramdisk_type : %-10d (%08x): %s\n", rdt_entry.ramdisk_type, rdt_entry.ramdisk_type, rdt_type_name); 256 | printf(" ramdisk_name : %s\n\n", rdt_entry.ramdisk_name); 257 | 258 | printf(" board_id : %ls\n\n", rdt_entry.board_id); 259 | } 260 | 261 | fseek(f, bc_offset, SEEK_SET); 262 | char bootconfig[header.bootconfig_size]; 263 | if(fread(bootconfig, header.bootconfig_size, 1, f)){}; 264 | 265 | printf(" bootconfig: %.*s\n", header.bootconfig_size, bootconfig); 266 | } 267 | 268 | printf(" Other:\n"); 269 | printf(" magic offset : %-10d (%08x)\n\n", i, i); 270 | 271 | printf(" base address : 0x%08x\n\n", base); 272 | 273 | printf(" kernel offset : 0x%08x\n", header.kernel_addr - base); 274 | printf(" ramdisk offset : 0x%08x\n", header.ramdisk_addr - base); 275 | printf(" tags offset : 0x%08x\n", header.tags_addr - base); 276 | printf(" dtb offset : 0x%08"PRIx64"\n", header.dtb_addr - base); 277 | if (header.header_version > 3) { 278 | printf("\n"); 279 | 280 | printf(" vendor ramdisk table offset : %-10d (%08x)\n", rdt_offset, rdt_offset); 281 | printf(" bootconfig offset : %-10d (%08x)\n", bc_offset, bc_offset); 282 | } 283 | } 284 | 285 | printf("\n"); 286 | fclose(f); 287 | return 0; 288 | } 289 | -------------------------------------------------------------------------------- /bootimg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 The Android Open Source Project 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, 5 | * are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this 8 | * list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * 3. Neither the name of the copyright holder nor the names of its contributors 15 | * may be used to endorse or promote products derived from this software without 16 | * specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 22 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #pragma once 31 | 32 | #include 33 | 34 | #define BOOT_MAGIC "ANDROID!" 35 | #define BOOT_MAGIC_SIZE 8 36 | #define BOOT_NAME_SIZE 16 37 | #define BOOT_ARGS_SIZE 512 38 | #define BOOT_EXTRA_ARGS_SIZE 1024 39 | 40 | #define VENDOR_BOOT_MAGIC "VNDRBOOT" 41 | #define VENDOR_BOOT_MAGIC_SIZE 8 42 | #define VENDOR_BOOT_ARGS_SIZE 2048 43 | #define VENDOR_BOOT_NAME_SIZE 16 44 | 45 | #define VENDOR_RAMDISK_TYPE_NONE 0 46 | #define VENDOR_RAMDISK_TYPE_PLATFORM 1 47 | #define VENDOR_RAMDISK_TYPE_RECOVERY 2 48 | #define VENDOR_RAMDISK_TYPE_DLKM 3 49 | #define VENDOR_RAMDISK_NAME_SIZE 32 50 | #define VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE 16 51 | 52 | /* 53 | * It is expected that callers would explicitly specify which version of the 54 | * boot image header they need to use. 55 | */ 56 | typedef struct boot_img_hdr_v0 boot_img_hdr; 57 | typedef struct boot_img_hdr_v0 boot_img_hdr_v0; 58 | typedef struct boot_img_hdr_v1 boot_img_hdr_v1; 59 | typedef struct boot_img_hdr_v2 boot_img_hdr_v2; 60 | typedef struct boot_img_hdr_v3 boot_img_hdr_v3; 61 | typedef struct boot_img_hdr_v4 boot_img_hdr_v4; 62 | typedef struct vendor_boot_img_hdr_v3 vendor_boot_img_hdr_v3; 63 | typedef struct vendor_boot_img_hdr_v4 vendor_boot_img_hdr_v4; 64 | typedef struct vendor_ramdisk_table_entry_v4 vendor_ramdisk_table_entry_v4; 65 | 66 | /* When a boot header is of version 0, the structure of boot image is as 67 | * follows: 68 | * 69 | * +-----------------+ 70 | * | boot header | 1 page 71 | * +-----------------+ 72 | * | kernel | n pages 73 | * +-----------------+ 74 | * | ramdisk | m pages 75 | * +-----------------+ 76 | * | second stage | o pages 77 | * +-----------------+ 78 | * 79 | * and on some hardware: 80 | * +-----------------+ 81 | * | device tree | p pages 82 | * +-----------------+ 83 | * 84 | * n = (kernel_size + page_size - 1) / page_size 85 | * m = (ramdisk_size + page_size - 1) / page_size 86 | * o = (second_size + page_size - 1) / page_size 87 | * 88 | * and on some hardware: 89 | * p = (dt_size + page_size - 1) / page_size 90 | * 91 | * 0. all entities are page_size aligned in flash 92 | * 1. kernel and ramdisk are required (size != 0) 93 | * 2. second is optional (second_size == 0 -> no second) 94 | * 3. load each element (kernel, ramdisk, second) at 95 | * the specified physical address (kernel_addr, etc) 96 | * 4. prepare tags at tag_addr. kernel_args[] is 97 | * appended to the kernel commandline in the tags. 98 | * 5. r0 = 0, r1 = MACHINE_TYPE, r2 = tags_addr 99 | * 6. if second_size != 0: jump to second_addr 100 | * else: jump to kernel_addr 101 | */ 102 | struct boot_img_hdr_v0 { 103 | // Must be BOOT_MAGIC. 104 | uint8_t magic[BOOT_MAGIC_SIZE]; 105 | 106 | uint32_t kernel_size; /* size in bytes */ 107 | uint32_t kernel_addr; /* physical load addr */ 108 | 109 | uint32_t ramdisk_size; /* size in bytes */ 110 | uint32_t ramdisk_addr; /* physical load addr */ 111 | 112 | uint32_t second_size; /* size in bytes */ 113 | uint32_t second_addr; /* physical load addr */ 114 | 115 | uint32_t tags_addr; /* physical addr for kernel tags (if required) */ 116 | uint32_t page_size; /* flash page size we assume */ 117 | 118 | // Version of the boot image header. 119 | // Alternately this is used as device tree size on some hardware. 120 | union { 121 | uint32_t header_version; 122 | uint32_t dt_size; /* size in bytes */ 123 | }; 124 | 125 | // Operating system version and security patch level. 126 | // For version "A.B.C" and patch level "Y-M-D": 127 | // (7 bits for each of A, B, C; 7 bits for (Y-2000), 4 bits for M) 128 | // os_version = A[31:25] B[24:18] C[17:11] (Y-2000)[10:4] M[3:0] 129 | uint32_t os_version; 130 | 131 | uint8_t name[BOOT_NAME_SIZE]; /* asciiz product name */ 132 | 133 | uint8_t cmdline[BOOT_ARGS_SIZE]; /* asciiz kernel commandline */ 134 | 135 | uint32_t id[8]; /* timestamp / checksum / sha1 / etc */ 136 | 137 | // Supplemental command line data; kept here to maintain 138 | // binary compatibility with older versions of mkbootimg. 139 | // Asciiz. 140 | uint8_t extra_cmdline[BOOT_EXTRA_ARGS_SIZE]; 141 | } __attribute__((packed)); 142 | 143 | /* When a boot header is of version 1, the structure of boot image is as 144 | * follows: 145 | * 146 | * +---------------------+ 147 | * | boot header | 1 page 148 | * +---------------------+ 149 | * | kernel | n pages 150 | * +---------------------+ 151 | * | ramdisk | m pages 152 | * +---------------------+ 153 | * | second stage | o pages 154 | * +---------------------+ 155 | * | recovery dtbo/acpio | p pages 156 | * +---------------------+ 157 | 158 | * n = (kernel_size + page_size - 1) / page_size 159 | * m = (ramdisk_size + page_size - 1) / page_size 160 | * o = (second_size + page_size - 1) / page_size 161 | * p = (recovery_dtbo_size + page_size - 1) / page_size 162 | * 163 | * 0. all entities are page_size aligned in flash 164 | * 1. kernel and ramdisk are required (size != 0) 165 | * 2. recovery_dtbo/recovery_acpio is required for recovery.img in non-A/B 166 | * devices(recovery_dtbo_size != 0) 167 | * 3. second is optional (second_size == 0 -> no second) 168 | * 4. load each element (kernel, ramdisk, second) at 169 | * the specified physical address (kernel_addr, etc) 170 | * 5. If booting to recovery mode in a non-A/B device, extract recovery 171 | * dtbo/acpio and apply the correct set of overlays on the base device tree 172 | * depending on the hardware/product revision. 173 | * 6. set up registers for kernel entry as required by your architecture 174 | * 7. if second_size != 0: jump to second_addr 175 | * else: jump to kernel_addr 176 | */ 177 | struct boot_img_hdr_v1 { 178 | // Must be BOOT_MAGIC. 179 | uint8_t magic[BOOT_MAGIC_SIZE]; 180 | 181 | uint32_t kernel_size; /* size in bytes */ 182 | uint32_t kernel_addr; /* physical load addr */ 183 | 184 | uint32_t ramdisk_size; /* size in bytes */ 185 | uint32_t ramdisk_addr; /* physical load addr */ 186 | 187 | uint32_t second_size; /* size in bytes */ 188 | uint32_t second_addr; /* physical load addr */ 189 | 190 | uint32_t tags_addr; /* physical addr for kernel tags (if required) */ 191 | uint32_t page_size; /* flash page size we assume */ 192 | 193 | // Version of the boot image header. 194 | // Alternately this is used as device tree size on some hardware. 195 | // Kept here for backwards compatibility. 196 | union { 197 | uint32_t header_version; 198 | uint32_t dt_size; /* size in bytes */ 199 | }; 200 | 201 | // Operating system version and security patch level. 202 | // For version "A.B.C" and patch level "Y-M-D": 203 | // (7 bits for each of A, B, C; 7 bits for (Y-2000), 4 bits for M) 204 | // os_version = A[31:25] B[24:18] C[17:11] (Y-2000)[10:4] M[3:0] 205 | uint32_t os_version; 206 | 207 | uint8_t name[BOOT_NAME_SIZE]; /* asciiz product name */ 208 | 209 | uint8_t cmdline[BOOT_ARGS_SIZE]; /* asciiz kernel commandline */ 210 | 211 | uint32_t id[8]; /* timestamp / checksum / sha1 / etc */ 212 | 213 | // Supplemental command line data; kept here to maintain 214 | // binary compatibility with older versions of mkbootimg. 215 | // Asciiz. 216 | uint8_t extra_cmdline[BOOT_EXTRA_ARGS_SIZE]; 217 | 218 | uint32_t recovery_dtbo_size; /* size in bytes for recovery DTBO/ACPIO image */ 219 | uint64_t recovery_dtbo_offset; /* offset to recovery dtbo/acpio in boot image */ 220 | uint32_t header_size; 221 | } __attribute__((packed)); 222 | 223 | /* When the boot image header has a version of 2, the structure of the boot 224 | * image is as follows: 225 | * 226 | * +---------------------+ 227 | * | boot header | 1 page 228 | * +---------------------+ 229 | * | kernel | n pages 230 | * +---------------------+ 231 | * | ramdisk | m pages 232 | * +---------------------+ 233 | * | second stage | o pages 234 | * +---------------------+ 235 | * | recovery dtbo/acpio | p pages 236 | * +---------------------+ 237 | * | dtb | q pages 238 | * +---------------------+ 239 | 240 | * n = (kernel_size + page_size - 1) / page_size 241 | * m = (ramdisk_size + page_size - 1) / page_size 242 | * o = (second_size + page_size - 1) / page_size 243 | * p = (recovery_dtbo_size + page_size - 1) / page_size 244 | * q = (dtb_size + page_size - 1) / page_size 245 | * 246 | * 0. all entities are page_size aligned in flash 247 | * 1. kernel, ramdisk and DTB are required (size != 0) 248 | * 2. recovery_dtbo/recovery_acpio is required for recovery.img in non-A/B 249 | * devices(recovery_dtbo_size != 0) 250 | * 3. second is optional (second_size == 0 -> no second) 251 | * 4. load each element (kernel, ramdisk, second, dtb) at 252 | * the specified physical address (kernel_addr, etc) 253 | * 5. If booting to recovery mode in a non-A/B device, extract recovery 254 | * dtbo/acpio and apply the correct set of overlays on the base device tree 255 | * depending on the hardware/product revision. 256 | * 6. set up registers for kernel entry as required by your architecture 257 | * 7. if second_size != 0: jump to second_addr 258 | * else: jump to kernel_addr 259 | */ 260 | struct boot_img_hdr_v2 { 261 | // Must be BOOT_MAGIC. 262 | uint8_t magic[BOOT_MAGIC_SIZE]; 263 | 264 | uint32_t kernel_size; /* size in bytes */ 265 | uint32_t kernel_addr; /* physical load addr */ 266 | 267 | uint32_t ramdisk_size; /* size in bytes */ 268 | uint32_t ramdisk_addr; /* physical load addr */ 269 | 270 | uint32_t second_size; /* size in bytes */ 271 | uint32_t second_addr; /* physical load addr */ 272 | 273 | uint32_t tags_addr; /* physical addr for kernel tags (if required) */ 274 | uint32_t page_size; /* flash page size we assume */ 275 | 276 | // Version of the boot image header. 277 | // Alternately this is used as device tree size on some hardware. 278 | // Kept here for backwards compatibility. 279 | union { 280 | uint32_t header_version; 281 | uint32_t dt_size; /* size in bytes */ 282 | }; 283 | 284 | // Operating system version and security patch level. 285 | // For version "A.B.C" and patch level "Y-M-D": 286 | // (7 bits for each of A, B, C; 7 bits for (Y-2000), 4 bits for M) 287 | // os_version = A[31:25] B[24:18] C[17:11] (Y-2000)[10:4] M[3:0] 288 | uint32_t os_version; 289 | 290 | uint8_t name[BOOT_NAME_SIZE]; /* asciiz product name */ 291 | 292 | uint8_t cmdline[BOOT_ARGS_SIZE]; /* asciiz kernel commandline */ 293 | 294 | uint32_t id[8]; /* timestamp / checksum / sha1 / etc */ 295 | 296 | // Supplemental command line data; kept here to maintain 297 | // binary compatibility with older versions of mkbootimg. 298 | // Asciiz. 299 | uint8_t extra_cmdline[BOOT_EXTRA_ARGS_SIZE]; 300 | 301 | uint32_t recovery_dtbo_size; /* size in bytes for recovery DTBO/ACPIO image */ 302 | uint64_t recovery_dtbo_offset; /* offset to recovery dtbo/acpio in boot image */ 303 | uint32_t header_size; 304 | 305 | uint32_t dtb_size; /* size in bytes for DTB image */ 306 | uint64_t dtb_addr; /* physical load address for DTB image */ 307 | } __attribute__((packed)); 308 | 309 | /* When the boot image header has a version of 3, the structure of the boot 310 | * image is as follows: 311 | * 312 | * +---------------------+ 313 | * | boot header | 4096 bytes 314 | * +---------------------+ 315 | * | kernel | m pages 316 | * +---------------------+ 317 | * | ramdisk | n pages 318 | * +---------------------+ 319 | * 320 | * m = (kernel_size + 4096 - 1) / 4096 321 | * n = (ramdisk_size + 4096 - 1) / 4096 322 | * 323 | * Note that in version 3 of the boot image header, page size is fixed at 4096 bytes. 324 | * 325 | * The structure of the vendor boot image (introduced with version 3 and 326 | * required to be present when a v3 boot image is used) is as follows: 327 | * 328 | * +---------------------+ 329 | * | vendor boot header | o pages 330 | * +---------------------+ 331 | * | vendor ramdisk | p pages 332 | * +---------------------+ 333 | * | dtb | q pages 334 | * +---------------------+ 335 | 336 | * o = (2112 + page_size - 1) / page_size 337 | * p = (vendor_ramdisk_size + page_size - 1) / page_size 338 | * q = (dtb_size + page_size - 1) / page_size 339 | * 340 | * 0. all entities in the boot image are 4096-byte aligned in flash, all 341 | * entities in the vendor boot image are page_size (determined by the vendor 342 | * and specified in the vendor boot image header) aligned in flash 343 | * 1. kernel, ramdisk, vendor ramdisk, and DTB are required (size != 0) 344 | * 2. load the kernel and DTB at the specified physical address (kernel_addr, 345 | * dtb_addr) 346 | * 3. load the vendor ramdisk at ramdisk_addr 347 | * 4. load the generic ramdisk immediately following the vendor ramdisk in 348 | * memory 349 | * 5. set up registers for kernel entry as required by your architecture 350 | * 6. if the platform has a second stage bootloader jump to it (must be 351 | * contained outside boot and vendor boot partitions), otherwise 352 | * jump to kernel_addr 353 | */ 354 | struct boot_img_hdr_v3 { 355 | // Must be BOOT_MAGIC. 356 | uint8_t magic[BOOT_MAGIC_SIZE]; 357 | 358 | uint32_t kernel_size; /* size in bytes */ 359 | uint32_t ramdisk_size; /* size in bytes */ 360 | 361 | // Operating system version and security patch level. 362 | // For version "A.B.C" and patch level "Y-M-D": 363 | // (7 bits for each of A, B, C; 7 bits for (Y-2000), 4 bits for M) 364 | // os_version = A[31:25] B[24:18] C[17:11] (Y-2000)[10:4] M[3:0] 365 | uint32_t os_version; 366 | 367 | uint32_t header_size; 368 | 369 | uint32_t reserved[4]; 370 | 371 | // Version of the boot image header. 372 | uint32_t header_version; 373 | 374 | // Asciiz kernel commandline. 375 | uint8_t cmdline[BOOT_ARGS_SIZE + BOOT_EXTRA_ARGS_SIZE]; 376 | } __attribute__((packed)); 377 | 378 | struct vendor_boot_img_hdr_v3 { 379 | // Must be VENDOR_BOOT_MAGIC. 380 | uint8_t magic[VENDOR_BOOT_MAGIC_SIZE]; 381 | 382 | // Version of the vendor boot image header. 383 | uint32_t header_version; 384 | 385 | uint32_t page_size; /* flash page size we assume */ 386 | 387 | uint32_t kernel_addr; /* physical load addr */ 388 | uint32_t ramdisk_addr; /* physical load addr */ 389 | 390 | uint32_t vendor_ramdisk_size; /* size in bytes */ 391 | 392 | uint8_t cmdline[VENDOR_BOOT_ARGS_SIZE]; /* asciiz kernel commandline */ 393 | 394 | uint32_t tags_addr; /* physical addr for kernel tags (if required) */ 395 | uint8_t name[VENDOR_BOOT_NAME_SIZE]; /* asciiz product name */ 396 | 397 | uint32_t header_size; 398 | 399 | uint32_t dtb_size; /* size in bytes for DTB image */ 400 | uint64_t dtb_addr; /* physical load address for DTB image */ 401 | } __attribute__((packed)); 402 | 403 | /* When the boot image header has a version of 4, the structure of the boot 404 | * image is as follows: 405 | * 406 | * +---------------------+ 407 | * | boot header | 4096 bytes 408 | * +---------------------+ 409 | * | kernel | m pages 410 | * +---------------------+ 411 | * | ramdisk | n pages 412 | * +---------------------+ 413 | * | boot signature | g pages 414 | * +---------------------+ 415 | * 416 | * m = (kernel_size + 4096 - 1) / 4096 417 | * n = (ramdisk_size + 4096 - 1) / 4096 418 | * g = (signature_size + 4096 - 1) / 4096 419 | * 420 | * Note that in version 4 of the boot image header, page size is fixed at 4096 421 | * bytes. 422 | * 423 | * The structure of the vendor boot image version 4, which is required to be 424 | * present when a version 4 boot image is used, is as follows: 425 | * 426 | * +------------------------+ 427 | * | vendor boot header | o pages 428 | * +------------------------+ 429 | * | vendor ramdisk section | p pages 430 | * +------------------------+ 431 | * | dtb | q pages 432 | * +------------------------+ 433 | * | vendor ramdisk table | r pages 434 | * +------------------------+ 435 | * | bootconfig | s pages 436 | * +------------------------+ 437 | * 438 | * o = (2128 + page_size - 1) / page_size 439 | * p = (vendor_ramdisk_size + page_size - 1) / page_size 440 | * q = (dtb_size + page_size - 1) / page_size 441 | * r = (vendor_ramdisk_table_size + page_size - 1) / page_size 442 | * s = (vendor_bootconfig_size + page_size - 1) / page_size 443 | * 444 | * Note that in version 4 of the vendor boot image, multiple vendor ramdisks can 445 | * be included in the vendor boot image. The bootloader can select a subset of 446 | * ramdisks to load at runtime. To help the bootloader select the ramdisks, each 447 | * ramdisk is tagged with a type tag and a set of hardware identifiers 448 | * describing the board, soc or platform that this ramdisk is intended for. 449 | * 450 | * The vendor ramdisk section is consist of multiple ramdisk images concatenated 451 | * one after another, and vendor_ramdisk_size is the size of the section, which 452 | * is the total size of all the ramdisks included in the vendor boot image. 453 | * 454 | * The vendor ramdisk table holds the size, offset, type, name and hardware 455 | * identifiers of each ramdisk. The type field denotes the type of its content. 456 | * The vendor ramdisk names are unique. The hardware identifiers are specified 457 | * in the board_id field in each table entry. The board_id field is consist of a 458 | * vector of unsigned integer words, and the encoding scheme is defined by the 459 | * hardware vendor. 460 | * 461 | * For the different type of ramdisks, there are: 462 | * - VENDOR_RAMDISK_TYPE_NONE indicates the value is unspecified. 463 | * - VENDOR_RAMDISK_TYPE_PLATFORM ramdisks contain platform specific bits, so 464 | * the bootloader should always load these into memory. 465 | * - VENDOR_RAMDISK_TYPE_RECOVERY ramdisks contain recovery resources, so 466 | * the bootloader should load these when booting into recovery. 467 | * - VENDOR_RAMDISK_TYPE_DLKM ramdisks contain dynamic loadable kernel 468 | * modules. 469 | * 470 | * Version 4 of the vendor boot image also adds a bootconfig section to the end 471 | * of the image. This section contains Boot Configuration parameters known at 472 | * build time. The bootloader is responsible for placing this section directly 473 | * after the generic ramdisk, followed by the bootconfig trailer, before 474 | * entering the kernel. 475 | * 476 | * 0. all entities in the boot image are 4096-byte aligned in flash, all 477 | * entities in the vendor boot image are page_size (determined by the vendor 478 | * and specified in the vendor boot image header) aligned in flash 479 | * 1. kernel, ramdisk, and DTB are required (size != 0) 480 | * 2. load the kernel and DTB at the specified physical address (kernel_addr, 481 | * dtb_addr) 482 | * 3. load the vendor ramdisks at ramdisk_addr 483 | * 4. load the generic ramdisk immediately following the vendor ramdisk in 484 | * memory 485 | * 5. load the bootconfig immediately following the generic ramdisk. Add 486 | * additional bootconfig parameters followed by the bootconfig trailer. 487 | * 6. set up registers for kernel entry as required by your architecture 488 | * 7. if the platform has a second stage bootloader jump to it (must be 489 | * contained outside boot and vendor boot partitions), otherwise 490 | * jump to kernel_addr 491 | */ 492 | struct boot_img_hdr_v4 { 493 | // Must be BOOT_MAGIC. 494 | uint8_t magic[BOOT_MAGIC_SIZE]; 495 | 496 | uint32_t kernel_size; /* size in bytes */ 497 | uint32_t ramdisk_size; /* size in bytes */ 498 | 499 | // Operating system version and security patch level. 500 | // For version "A.B.C" and patch level "Y-M-D": 501 | // (7 bits for each of A, B, C; 7 bits for (Y-2000), 4 bits for M) 502 | // os_version = A[31:25] B[24:18] C[17:11] (Y-2000)[10:4] M[3:0] 503 | uint32_t os_version; 504 | 505 | uint32_t header_size; 506 | 507 | uint32_t reserved[4]; 508 | 509 | // Version of the boot image header. 510 | uint32_t header_version; 511 | 512 | // Asciiz kernel commandline. 513 | uint8_t cmdline[BOOT_ARGS_SIZE + BOOT_EXTRA_ARGS_SIZE]; 514 | 515 | uint32_t signature_size; /* size in bytes */ 516 | } __attribute__((packed)); 517 | 518 | struct vendor_boot_img_hdr_v4 { 519 | // Must be VENDOR_BOOT_MAGIC. 520 | uint8_t magic[VENDOR_BOOT_MAGIC_SIZE]; 521 | 522 | // Version of the vendor boot image header. 523 | uint32_t header_version; 524 | 525 | uint32_t page_size; /* flash page size we assume */ 526 | 527 | uint32_t kernel_addr; /* physical load addr */ 528 | uint32_t ramdisk_addr; /* physical load addr */ 529 | 530 | uint32_t vendor_ramdisk_size; /* size in bytes */ 531 | 532 | uint8_t cmdline[VENDOR_BOOT_ARGS_SIZE]; /* asciiz kernel commandline */ 533 | 534 | uint32_t tags_addr; /* physical addr for kernel tags (if required) */ 535 | uint8_t name[VENDOR_BOOT_NAME_SIZE]; /* asciiz product name */ 536 | 537 | uint32_t header_size; 538 | 539 | uint32_t dtb_size; /* size in bytes for DTB image */ 540 | uint64_t dtb_addr; /* physical load address for DTB image */ 541 | 542 | uint32_t vendor_ramdisk_table_size; /* size in bytes for the vendor ramdisk table */ 543 | uint32_t vendor_ramdisk_table_entry_num; /* number of entries in the vendor ramdisk table */ 544 | uint32_t vendor_ramdisk_table_entry_size; /* size in bytes for a vendor ramdisk table entry */ 545 | uint32_t bootconfig_size; /* size in bytes for the bootconfig section */ 546 | } __attribute__((packed)); 547 | 548 | struct vendor_ramdisk_table_entry_v4 { 549 | uint32_t ramdisk_size; /* size in bytes for the ramdisk image */ 550 | uint32_t ramdisk_offset; /* offset to the ramdisk image in vendor ramdisk section */ 551 | uint32_t ramdisk_type; /* type of the ramdisk */ 552 | uint8_t ramdisk_name[VENDOR_RAMDISK_NAME_SIZE]; /* asciiz ramdisk name */ 553 | 554 | // Hardware identifiers describing the board, soc or platform which this 555 | // ramdisk is intended to be loaded on. 556 | uint32_t board_id[VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE]; 557 | } __attribute__((packed)); 558 | --------------------------------------------------------------------------------