143d520f3SAlex Deymo /* SPDX-License-Identifier: BSD-3-Clause */ 29ace3fc8SSebastian Siewior /* 39ace3fc8SSebastian Siewior * This is from the Android Project, 443d520f3SAlex Deymo * Repository: https://android.googlesource.com/platform/system/tools/mkbootimg 543d520f3SAlex Deymo * File: include/bootimg/bootimg.h 643d520f3SAlex Deymo * Commit: e55998a0f2b61b685d5eb4a486ca3a0c680b1a2f 79ace3fc8SSebastian Siewior * 843d520f3SAlex Deymo * Copyright (C) 2007 The Android Open Source Project 99ace3fc8SSebastian Siewior */ 109ace3fc8SSebastian Siewior 119ace3fc8SSebastian Siewior #ifndef _ANDROID_IMAGE_H_ 129ace3fc8SSebastian Siewior #define _ANDROID_IMAGE_H_ 139ace3fc8SSebastian Siewior 149ace3fc8SSebastian Siewior #define ANDR_BOOT_MAGIC "ANDROID!" 15745aeb1aSJoseph Chen #define VENDOR_BOOT_MAGIC "VNDRBOOT" 169ace3fc8SSebastian Siewior #define ANDR_BOOT_MAGIC_SIZE 8 17745aeb1aSJoseph Chen #define VENDOR_BOOT_MAGIC_SIZE 8 189ace3fc8SSebastian Siewior #define ANDR_BOOT_NAME_SIZE 16 19745aeb1aSJoseph Chen #define VENDOR_BOOT_NAME_SIZE 16 209ace3fc8SSebastian Siewior #define ANDR_BOOT_ARGS_SIZE 512 21210a7176SAlex Deymo #define ANDR_BOOT_EXTRA_ARGS_SIZE 1024 22745aeb1aSJoseph Chen #define VENDOR_BOOT_ARGS_SIZE 2048 23745aeb1aSJoseph Chen #define ANDR_BOOT_IMG_PAGE_SIZE 4096 24745aeb1aSJoseph Chen #define ANDR_BOOT_IMG_HDR_SIZE (ANDR_BOOT_IMG_PAGE_SIZE) 25745aeb1aSJoseph Chen #define TOTAL_BOOT_ARGS_SIZE (ANDR_BOOT_ARGS_SIZE + ANDR_BOOT_EXTRA_ARGS_SIZE + \ 26745aeb1aSJoseph Chen VENDOR_BOOT_ARGS_SIZE + 1) 27745aeb1aSJoseph Chen #define VENDOR_BOOT_HDR_SIZE 2112 289ace3fc8SSebastian Siewior 2943d520f3SAlex Deymo /* 3043d520f3SAlex Deymo * It is expected that callers would explicitly specify which version of the 3143d520f3SAlex Deymo * boot image header they need to use. 3243d520f3SAlex Deymo */ 3343d520f3SAlex Deymo typedef struct andr_img_hdr andr_img_hdr; 3443d520f3SAlex Deymo 3543d520f3SAlex Deymo /* The bootloader expects the structure of andr_img_hdr with header 3643d520f3SAlex Deymo * version 0 to be as follows: */ 379ace3fc8SSebastian Siewior struct andr_img_hdr { 3843d520f3SAlex Deymo /* Must be ANDR_BOOT_MAGIC. */ 399ace3fc8SSebastian Siewior char magic[ANDR_BOOT_MAGIC_SIZE]; 409ace3fc8SSebastian Siewior 419ace3fc8SSebastian Siewior u32 kernel_size; /* size in bytes */ 429ace3fc8SSebastian Siewior u32 kernel_addr; /* physical load addr */ 439ace3fc8SSebastian Siewior 449ace3fc8SSebastian Siewior u32 ramdisk_size; /* size in bytes */ 459ace3fc8SSebastian Siewior u32 ramdisk_addr; /* physical load addr */ 469ace3fc8SSebastian Siewior 479ace3fc8SSebastian Siewior u32 second_size; /* size in bytes */ 489ace3fc8SSebastian Siewior u32 second_addr; /* physical load addr */ 499ace3fc8SSebastian Siewior 509ace3fc8SSebastian Siewior u32 tags_addr; /* physical addr for kernel tags */ 519ace3fc8SSebastian Siewior u32 page_size; /* flash page size we assume */ 5209f4e561SJoseph Chen 5343d520f3SAlex Deymo /* Version of the boot image header. */ 5409f4e561SJoseph Chen u32 header_version; 55210a7176SAlex Deymo 5643d520f3SAlex Deymo /* Operating system version and security patch level. 5743d520f3SAlex Deymo * For version "A.B.C" and patch level "Y-M-D": 5843d520f3SAlex Deymo * (7 bits for each of A, B, C; 7 bits for (Y-2000), 4 bits for M) 5943d520f3SAlex Deymo * os_version = A[31:25] B[24:18] C[17:11] (Y-2000)[10:4] M[3:0] */ 60210a7176SAlex Deymo u32 os_version; 619ace3fc8SSebastian Siewior 629ace3fc8SSebastian Siewior char name[ANDR_BOOT_NAME_SIZE]; /* asciiz product name */ 639ace3fc8SSebastian Siewior 649ace3fc8SSebastian Siewior char cmdline[ANDR_BOOT_ARGS_SIZE]; 659ace3fc8SSebastian Siewior 669ace3fc8SSebastian Siewior u32 id[8]; /* timestamp / checksum / sha1 / etc */ 67210a7176SAlex Deymo 68210a7176SAlex Deymo /* Supplemental command line data; kept here to maintain 6943d520f3SAlex Deymo * binary compatibility with older versions of mkbootimg. */ 70210a7176SAlex Deymo char extra_cmdline[ANDR_BOOT_EXTRA_ARGS_SIZE]; 7109f4e561SJoseph Chen 72745aeb1aSJoseph Chen /* Fields in boot_img_hdr_v1(Android-9) and newer. */ 7343d520f3SAlex Deymo u32 recovery_dtbo_size; /* size in bytes for recovery DTBO/ACPIO image */ 7443d520f3SAlex Deymo u64 recovery_dtbo_offset; /* offset to recovery dtbo/acpio in boot image */ 7543d520f3SAlex Deymo u32 header_size; 7643d520f3SAlex Deymo 77745aeb1aSJoseph Chen /* Fields in boot_img_hdr_v2(Android-10) and newer. */ 7843d520f3SAlex Deymo u32 dtb_size; /* size in bytes for DTB image */ 7943d520f3SAlex Deymo u64 dtb_addr; /* physical load address for DTB image */ 80745aeb1aSJoseph Chen 81745aeb1aSJoseph Chen /* 82745aeb1aSJoseph Chen * [Rockchip compatibility] 83745aeb1aSJoseph Chen * 84745aeb1aSJoseph Chen * boot_img_hdr_v3(Android-11) is not compatible with boot_img_hdr_v012, 85745aeb1aSJoseph Chen * we have to partly merge fields from boot_img_hdr_v3 and vendor_boot_img_hdr_v3 86745aeb1aSJoseph Chen * into this structure to compatible with boot_img_hdr_v012. 87745aeb1aSJoseph Chen */ 88*e7498cb0SJoseph Chen u32 boot_ramdisk_size; /* size in bytes */ 89745aeb1aSJoseph Chen u32 vendor_ramdisk_size; /* size in bytes */ 90745aeb1aSJoseph Chen u32 vendor_page_size; 91745aeb1aSJoseph Chen u32 vendor_header_version; 92745aeb1aSJoseph Chen u32 vendor_header_size; 93745aeb1aSJoseph Chen /* 94745aeb1aSJoseph Chen * Don't define 'char total_cmdline[TOTAL_BOOT_ARGS_SIZE]' to avoid 95745aeb1aSJoseph Chen * this structrue is over size than page_size. 96745aeb1aSJoseph Chen */ 97745aeb1aSJoseph Chen char *total_cmdline; 98745aeb1aSJoseph Chen } __attribute__((packed)); 99745aeb1aSJoseph Chen 100745aeb1aSJoseph Chen struct boot_img_hdr_v3 { 101745aeb1aSJoseph Chen /* Must be ANDR_BOOT_MAGIC. */ 102745aeb1aSJoseph Chen uint8_t magic[ANDR_BOOT_MAGIC_SIZE]; 103745aeb1aSJoseph Chen 104745aeb1aSJoseph Chen uint32_t kernel_size; /* size in bytes */ 105745aeb1aSJoseph Chen uint32_t ramdisk_size; /* size in bytes */ 106745aeb1aSJoseph Chen 107745aeb1aSJoseph Chen /* Operating system version and security patch level. 108745aeb1aSJoseph Chen * For version "A.B.C" and patch level "Y-M-D": 109745aeb1aSJoseph Chen * (7 bits for each of A, B, C; 7 bits for (Y-2000), 4 bits for M) 110745aeb1aSJoseph Chen * os_version = A[31:25] B[24:18] C[17:11] (Y-2000)[10:4] M[3:0] */ 111745aeb1aSJoseph Chen uint32_t os_version; 112745aeb1aSJoseph Chen 113745aeb1aSJoseph Chen uint32_t header_size; 114745aeb1aSJoseph Chen 115745aeb1aSJoseph Chen uint32_t reserved[4]; 116745aeb1aSJoseph Chen 117745aeb1aSJoseph Chen uint32_t header_version; 118745aeb1aSJoseph Chen 119745aeb1aSJoseph Chen uint8_t cmdline[ANDR_BOOT_ARGS_SIZE + ANDR_BOOT_EXTRA_ARGS_SIZE]; 120745aeb1aSJoseph Chen } __attribute__((packed)); 121745aeb1aSJoseph Chen 122745aeb1aSJoseph Chen struct vendor_boot_img_hdr_v3 { 123745aeb1aSJoseph Chen /* Must be VENDOR_BOOT_MAGIC. */ 124745aeb1aSJoseph Chen uint8_t magic[VENDOR_BOOT_MAGIC_SIZE]; 125745aeb1aSJoseph Chen 126745aeb1aSJoseph Chen /* Version of the vendor boot image header. */ 127745aeb1aSJoseph Chen uint32_t header_version; 128745aeb1aSJoseph Chen 129745aeb1aSJoseph Chen uint32_t page_size; /* flash page size we assume */ 130745aeb1aSJoseph Chen 131745aeb1aSJoseph Chen uint32_t kernel_addr; /* physical load addr */ 132745aeb1aSJoseph Chen uint32_t ramdisk_addr; /* physical load addr */ 133745aeb1aSJoseph Chen 134745aeb1aSJoseph Chen uint32_t vendor_ramdisk_size; /* size in bytes */ 135745aeb1aSJoseph Chen 136745aeb1aSJoseph Chen uint8_t cmdline[VENDOR_BOOT_ARGS_SIZE]; 137745aeb1aSJoseph Chen 138745aeb1aSJoseph Chen uint32_t tags_addr; /* physical addr for kernel tags (if required) */ 139745aeb1aSJoseph Chen uint8_t name[VENDOR_BOOT_NAME_SIZE]; /* asciiz product name */ 140745aeb1aSJoseph Chen 141745aeb1aSJoseph Chen uint32_t header_size; 142745aeb1aSJoseph Chen 143745aeb1aSJoseph Chen uint32_t dtb_size; /* size in bytes for DTB image */ 144745aeb1aSJoseph Chen uint64_t dtb_addr; /* physical load address for DTB image */ 145210a7176SAlex Deymo } __attribute__((packed)); 1469ace3fc8SSebastian Siewior 14743d520f3SAlex Deymo /* When a boot header is of version 0, the structure of boot image is as 14843d520f3SAlex Deymo * follows: 14943d520f3SAlex Deymo * 1509ace3fc8SSebastian Siewior * +-----------------+ 1519ace3fc8SSebastian Siewior * | boot header | 1 page 1529ace3fc8SSebastian Siewior * +-----------------+ 1539ace3fc8SSebastian Siewior * | kernel | n pages 1549ace3fc8SSebastian Siewior * +-----------------+ 1559ace3fc8SSebastian Siewior * | ramdisk | m pages 1569ace3fc8SSebastian Siewior * +-----------------+ 1579ace3fc8SSebastian Siewior * | second stage | o pages 1589ace3fc8SSebastian Siewior * +-----------------+ 1599ace3fc8SSebastian Siewior * 1609ace3fc8SSebastian Siewior * n = (kernel_size + page_size - 1) / page_size 1619ace3fc8SSebastian Siewior * m = (ramdisk_size + page_size - 1) / page_size 1629ace3fc8SSebastian Siewior * o = (second_size + page_size - 1) / page_size 1639ace3fc8SSebastian Siewior * 1649ace3fc8SSebastian Siewior * 0. all entities are page_size aligned in flash 1659ace3fc8SSebastian Siewior * 1. kernel and ramdisk are required (size != 0) 1669ace3fc8SSebastian Siewior * 2. second is optional (second_size == 0 -> no second) 1679ace3fc8SSebastian Siewior * 3. load each element (kernel, ramdisk, second) at 1689ace3fc8SSebastian Siewior * the specified physical address (kernel_addr, etc) 1699ace3fc8SSebastian Siewior * 4. prepare tags at tag_addr. kernel_args[] is 1709ace3fc8SSebastian Siewior * appended to the kernel commandline in the tags. 1719ace3fc8SSebastian Siewior * 5. r0 = 0, r1 = MACHINE_TYPE, r2 = tags_addr 1729ace3fc8SSebastian Siewior * 6. if second_size != 0: jump to second_addr 1739ace3fc8SSebastian Siewior * else: jump to kernel_addr 1749ace3fc8SSebastian Siewior */ 17543d520f3SAlex Deymo 17643d520f3SAlex Deymo /* When the boot image header has a version of 2, the structure of the boot 17743d520f3SAlex Deymo * image is as follows: 17843d520f3SAlex Deymo * 17943d520f3SAlex Deymo * +---------------------+ 18043d520f3SAlex Deymo * | boot header | 1 page 18143d520f3SAlex Deymo * +---------------------+ 18243d520f3SAlex Deymo * | kernel | n pages 18343d520f3SAlex Deymo * +---------------------+ 18443d520f3SAlex Deymo * | ramdisk | m pages 18543d520f3SAlex Deymo * +---------------------+ 18643d520f3SAlex Deymo * | second stage | o pages 18743d520f3SAlex Deymo * +---------------------+ 18843d520f3SAlex Deymo * | recovery dtbo/acpio | p pages 18943d520f3SAlex Deymo * +---------------------+ 19043d520f3SAlex Deymo * | dtb | q pages 19143d520f3SAlex Deymo * +---------------------+ 19243d520f3SAlex Deymo 19343d520f3SAlex Deymo * n = (kernel_size + page_size - 1) / page_size 19443d520f3SAlex Deymo * m = (ramdisk_size + page_size - 1) / page_size 19543d520f3SAlex Deymo * o = (second_size + page_size - 1) / page_size 19643d520f3SAlex Deymo * p = (recovery_dtbo_size + page_size - 1) / page_size 19743d520f3SAlex Deymo * q = (dtb_size + page_size - 1) / page_size 19843d520f3SAlex Deymo * 19943d520f3SAlex Deymo * 0. all entities are page_size aligned in flash 20043d520f3SAlex Deymo * 1. kernel, ramdisk and DTB are required (size != 0) 20143d520f3SAlex Deymo * 2. recovery_dtbo/recovery_acpio is required for recovery.img in non-A/B 20243d520f3SAlex Deymo * devices(recovery_dtbo_size != 0) 20343d520f3SAlex Deymo * 3. second is optional (second_size == 0 -> no second) 20443d520f3SAlex Deymo * 4. load each element (kernel, ramdisk, second, dtb) at 20543d520f3SAlex Deymo * the specified physical address (kernel_addr, etc) 20643d520f3SAlex Deymo * 5. If booting to recovery mode in a non-A/B device, extract recovery 20743d520f3SAlex Deymo * dtbo/acpio and apply the correct set of overlays on the base device tree 20843d520f3SAlex Deymo * depending on the hardware/product revision. 20943d520f3SAlex Deymo * 6. prepare tags at tag_addr. kernel_args[] is 21043d520f3SAlex Deymo * appended to the kernel commandline in the tags. 21143d520f3SAlex Deymo * 7. r0 = 0, r1 = MACHINE_TYPE, r2 = tags_addr 21243d520f3SAlex Deymo * 8. if second_size != 0: jump to second_addr 21343d520f3SAlex Deymo * else: jump to kernel_addr 21443d520f3SAlex Deymo */ 21543d520f3SAlex Deymo 216745aeb1aSJoseph Chen /* When the boot image header has a version of 3, the structure of the boot 217745aeb1aSJoseph Chen * image is as follows: 218745aeb1aSJoseph Chen * 219745aeb1aSJoseph Chen * +---------------------+ 220745aeb1aSJoseph Chen * | boot header | 4096 bytes 221745aeb1aSJoseph Chen * +---------------------+ 222745aeb1aSJoseph Chen * | kernel | m pages 223745aeb1aSJoseph Chen * +---------------------+ 224745aeb1aSJoseph Chen * | ramdisk | n pages 225745aeb1aSJoseph Chen * +---------------------+ 226745aeb1aSJoseph Chen * 227745aeb1aSJoseph Chen * m = (kernel_size + 4096 - 1) / 4096 228745aeb1aSJoseph Chen * n = (ramdisk_size + 4096 - 1) / 4096 229745aeb1aSJoseph Chen * 230745aeb1aSJoseph Chen * Note that in version 3 of the boot image header, page size is fixed at 4096 bytes. 231745aeb1aSJoseph Chen * 232745aeb1aSJoseph Chen * The structure of the vendor boot image (introduced with version 3 and 233745aeb1aSJoseph Chen * required to be present when a v3 boot image is used) is as follows: 234745aeb1aSJoseph Chen * 235745aeb1aSJoseph Chen * +---------------------+ 236745aeb1aSJoseph Chen * | vendor boot header | o pages 237745aeb1aSJoseph Chen * +---------------------+ 238745aeb1aSJoseph Chen * | vendor ramdisk | p pages 239745aeb1aSJoseph Chen * +---------------------+ 240745aeb1aSJoseph Chen * | dtb | q pages 241745aeb1aSJoseph Chen * +---------------------+ 242745aeb1aSJoseph Chen * 243745aeb1aSJoseph Chen * o = (2112 + page_size - 1) / page_size 244745aeb1aSJoseph Chen * p = (vendor_ramdisk_size + page_size - 1) / page_size 245745aeb1aSJoseph Chen * q = (dtb_size + page_size - 1) / page_size 246745aeb1aSJoseph Chen * 247745aeb1aSJoseph Chen * 0. all entities in the boot image are 4096-byte aligned in flash, all 248745aeb1aSJoseph Chen * entities in the vendor boot image are page_size (determined by the vendor 249745aeb1aSJoseph Chen * and specified in the vendor boot image header) aligned in flash 250745aeb1aSJoseph Chen * 1. kernel, ramdisk, vendor ramdisk, and DTB are required (size != 0) 251745aeb1aSJoseph Chen * 2. load the kernel and DTB at the specified physical address (kernel_addr, 252745aeb1aSJoseph Chen * dtb_addr) 253745aeb1aSJoseph Chen * 3. load the vendor ramdisk at ramdisk_addr 254745aeb1aSJoseph Chen * 4. load the generic ramdisk immediately following the vendor ramdisk in 255745aeb1aSJoseph Chen * memory 256745aeb1aSJoseph Chen * 5. set up registers for kernel entry as required by your architecture 257745aeb1aSJoseph Chen * 6. if the platform has a second stage bootloader jump to it (must be 258745aeb1aSJoseph Chen * contained outside boot and vendor boot partitions), otherwise 259745aeb1aSJoseph Chen * jump to kernel_addr 260745aeb1aSJoseph Chen */ 261745aeb1aSJoseph Chen 2629ace3fc8SSebastian Siewior #endif 263