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!" 15*745aeb1aSJoseph Chen #define VENDOR_BOOT_MAGIC "VNDRBOOT" 169ace3fc8SSebastian Siewior #define ANDR_BOOT_MAGIC_SIZE 8 17*745aeb1aSJoseph Chen #define VENDOR_BOOT_MAGIC_SIZE 8 189ace3fc8SSebastian Siewior #define ANDR_BOOT_NAME_SIZE 16 19*745aeb1aSJoseph Chen #define VENDOR_BOOT_NAME_SIZE 16 209ace3fc8SSebastian Siewior #define ANDR_BOOT_ARGS_SIZE 512 21210a7176SAlex Deymo #define ANDR_BOOT_EXTRA_ARGS_SIZE 1024 22*745aeb1aSJoseph Chen #define VENDOR_BOOT_ARGS_SIZE 2048 23*745aeb1aSJoseph Chen #define ANDR_BOOT_IMG_PAGE_SIZE 4096 24*745aeb1aSJoseph Chen #define ANDR_BOOT_IMG_HDR_SIZE (ANDR_BOOT_IMG_PAGE_SIZE) 25*745aeb1aSJoseph Chen #define TOTAL_BOOT_ARGS_SIZE (ANDR_BOOT_ARGS_SIZE + ANDR_BOOT_EXTRA_ARGS_SIZE + \ 26*745aeb1aSJoseph Chen VENDOR_BOOT_ARGS_SIZE + 1) 27*745aeb1aSJoseph 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 72*745aeb1aSJoseph 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 77*745aeb1aSJoseph 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 */ 80*745aeb1aSJoseph Chen 81*745aeb1aSJoseph Chen /* 82*745aeb1aSJoseph Chen * [Rockchip compatibility] 83*745aeb1aSJoseph Chen * 84*745aeb1aSJoseph Chen * boot_img_hdr_v3(Android-11) is not compatible with boot_img_hdr_v012, 85*745aeb1aSJoseph Chen * we have to partly merge fields from boot_img_hdr_v3 and vendor_boot_img_hdr_v3 86*745aeb1aSJoseph Chen * into this structure to compatible with boot_img_hdr_v012. 87*745aeb1aSJoseph Chen */ 88*745aeb1aSJoseph Chen u32 vendor_ramdisk_size; /* size in bytes */ 89*745aeb1aSJoseph Chen u32 vendor_page_size; 90*745aeb1aSJoseph Chen u32 vendor_header_version; 91*745aeb1aSJoseph Chen u32 vendor_header_size; 92*745aeb1aSJoseph Chen /* 93*745aeb1aSJoseph Chen * Don't define 'char total_cmdline[TOTAL_BOOT_ARGS_SIZE]' to avoid 94*745aeb1aSJoseph Chen * this structrue is over size than page_size. 95*745aeb1aSJoseph Chen */ 96*745aeb1aSJoseph Chen char *total_cmdline; 97*745aeb1aSJoseph Chen } __attribute__((packed)); 98*745aeb1aSJoseph Chen 99*745aeb1aSJoseph Chen struct boot_img_hdr_v3 { 100*745aeb1aSJoseph Chen /* Must be ANDR_BOOT_MAGIC. */ 101*745aeb1aSJoseph Chen uint8_t magic[ANDR_BOOT_MAGIC_SIZE]; 102*745aeb1aSJoseph Chen 103*745aeb1aSJoseph Chen uint32_t kernel_size; /* size in bytes */ 104*745aeb1aSJoseph Chen uint32_t ramdisk_size; /* size in bytes */ 105*745aeb1aSJoseph Chen 106*745aeb1aSJoseph Chen /* Operating system version and security patch level. 107*745aeb1aSJoseph Chen * For version "A.B.C" and patch level "Y-M-D": 108*745aeb1aSJoseph Chen * (7 bits for each of A, B, C; 7 bits for (Y-2000), 4 bits for M) 109*745aeb1aSJoseph Chen * os_version = A[31:25] B[24:18] C[17:11] (Y-2000)[10:4] M[3:0] */ 110*745aeb1aSJoseph Chen uint32_t os_version; 111*745aeb1aSJoseph Chen 112*745aeb1aSJoseph Chen uint32_t header_size; 113*745aeb1aSJoseph Chen 114*745aeb1aSJoseph Chen uint32_t reserved[4]; 115*745aeb1aSJoseph Chen 116*745aeb1aSJoseph Chen uint32_t header_version; 117*745aeb1aSJoseph Chen 118*745aeb1aSJoseph Chen uint8_t cmdline[ANDR_BOOT_ARGS_SIZE + ANDR_BOOT_EXTRA_ARGS_SIZE]; 119*745aeb1aSJoseph Chen } __attribute__((packed)); 120*745aeb1aSJoseph Chen 121*745aeb1aSJoseph Chen struct vendor_boot_img_hdr_v3 { 122*745aeb1aSJoseph Chen /* Must be VENDOR_BOOT_MAGIC. */ 123*745aeb1aSJoseph Chen uint8_t magic[VENDOR_BOOT_MAGIC_SIZE]; 124*745aeb1aSJoseph Chen 125*745aeb1aSJoseph Chen /* Version of the vendor boot image header. */ 126*745aeb1aSJoseph Chen uint32_t header_version; 127*745aeb1aSJoseph Chen 128*745aeb1aSJoseph Chen uint32_t page_size; /* flash page size we assume */ 129*745aeb1aSJoseph Chen 130*745aeb1aSJoseph Chen uint32_t kernel_addr; /* physical load addr */ 131*745aeb1aSJoseph Chen uint32_t ramdisk_addr; /* physical load addr */ 132*745aeb1aSJoseph Chen 133*745aeb1aSJoseph Chen uint32_t vendor_ramdisk_size; /* size in bytes */ 134*745aeb1aSJoseph Chen 135*745aeb1aSJoseph Chen uint8_t cmdline[VENDOR_BOOT_ARGS_SIZE]; 136*745aeb1aSJoseph Chen 137*745aeb1aSJoseph Chen uint32_t tags_addr; /* physical addr for kernel tags (if required) */ 138*745aeb1aSJoseph Chen uint8_t name[VENDOR_BOOT_NAME_SIZE]; /* asciiz product name */ 139*745aeb1aSJoseph Chen 140*745aeb1aSJoseph Chen uint32_t header_size; 141*745aeb1aSJoseph Chen 142*745aeb1aSJoseph Chen uint32_t dtb_size; /* size in bytes for DTB image */ 143*745aeb1aSJoseph Chen uint64_t dtb_addr; /* physical load address for DTB image */ 144210a7176SAlex Deymo } __attribute__((packed)); 1459ace3fc8SSebastian Siewior 14643d520f3SAlex Deymo /* When a boot header is of version 0, the structure of boot image is as 14743d520f3SAlex Deymo * follows: 14843d520f3SAlex Deymo * 1499ace3fc8SSebastian Siewior * +-----------------+ 1509ace3fc8SSebastian Siewior * | boot header | 1 page 1519ace3fc8SSebastian Siewior * +-----------------+ 1529ace3fc8SSebastian Siewior * | kernel | n pages 1539ace3fc8SSebastian Siewior * +-----------------+ 1549ace3fc8SSebastian Siewior * | ramdisk | m pages 1559ace3fc8SSebastian Siewior * +-----------------+ 1569ace3fc8SSebastian Siewior * | second stage | o pages 1579ace3fc8SSebastian Siewior * +-----------------+ 1589ace3fc8SSebastian Siewior * 1599ace3fc8SSebastian Siewior * n = (kernel_size + page_size - 1) / page_size 1609ace3fc8SSebastian Siewior * m = (ramdisk_size + page_size - 1) / page_size 1619ace3fc8SSebastian Siewior * o = (second_size + page_size - 1) / page_size 1629ace3fc8SSebastian Siewior * 1639ace3fc8SSebastian Siewior * 0. all entities are page_size aligned in flash 1649ace3fc8SSebastian Siewior * 1. kernel and ramdisk are required (size != 0) 1659ace3fc8SSebastian Siewior * 2. second is optional (second_size == 0 -> no second) 1669ace3fc8SSebastian Siewior * 3. load each element (kernel, ramdisk, second) at 1679ace3fc8SSebastian Siewior * the specified physical address (kernel_addr, etc) 1689ace3fc8SSebastian Siewior * 4. prepare tags at tag_addr. kernel_args[] is 1699ace3fc8SSebastian Siewior * appended to the kernel commandline in the tags. 1709ace3fc8SSebastian Siewior * 5. r0 = 0, r1 = MACHINE_TYPE, r2 = tags_addr 1719ace3fc8SSebastian Siewior * 6. if second_size != 0: jump to second_addr 1729ace3fc8SSebastian Siewior * else: jump to kernel_addr 1739ace3fc8SSebastian Siewior */ 17443d520f3SAlex Deymo 17543d520f3SAlex Deymo /* When the boot image header has a version of 2, the structure of the boot 17643d520f3SAlex Deymo * image is as follows: 17743d520f3SAlex Deymo * 17843d520f3SAlex Deymo * +---------------------+ 17943d520f3SAlex Deymo * | boot header | 1 page 18043d520f3SAlex Deymo * +---------------------+ 18143d520f3SAlex Deymo * | kernel | n pages 18243d520f3SAlex Deymo * +---------------------+ 18343d520f3SAlex Deymo * | ramdisk | m pages 18443d520f3SAlex Deymo * +---------------------+ 18543d520f3SAlex Deymo * | second stage | o pages 18643d520f3SAlex Deymo * +---------------------+ 18743d520f3SAlex Deymo * | recovery dtbo/acpio | p pages 18843d520f3SAlex Deymo * +---------------------+ 18943d520f3SAlex Deymo * | dtb | q pages 19043d520f3SAlex Deymo * +---------------------+ 19143d520f3SAlex Deymo 19243d520f3SAlex Deymo * n = (kernel_size + page_size - 1) / page_size 19343d520f3SAlex Deymo * m = (ramdisk_size + page_size - 1) / page_size 19443d520f3SAlex Deymo * o = (second_size + page_size - 1) / page_size 19543d520f3SAlex Deymo * p = (recovery_dtbo_size + page_size - 1) / page_size 19643d520f3SAlex Deymo * q = (dtb_size + page_size - 1) / page_size 19743d520f3SAlex Deymo * 19843d520f3SAlex Deymo * 0. all entities are page_size aligned in flash 19943d520f3SAlex Deymo * 1. kernel, ramdisk and DTB are required (size != 0) 20043d520f3SAlex Deymo * 2. recovery_dtbo/recovery_acpio is required for recovery.img in non-A/B 20143d520f3SAlex Deymo * devices(recovery_dtbo_size != 0) 20243d520f3SAlex Deymo * 3. second is optional (second_size == 0 -> no second) 20343d520f3SAlex Deymo * 4. load each element (kernel, ramdisk, second, dtb) at 20443d520f3SAlex Deymo * the specified physical address (kernel_addr, etc) 20543d520f3SAlex Deymo * 5. If booting to recovery mode in a non-A/B device, extract recovery 20643d520f3SAlex Deymo * dtbo/acpio and apply the correct set of overlays on the base device tree 20743d520f3SAlex Deymo * depending on the hardware/product revision. 20843d520f3SAlex Deymo * 6. prepare tags at tag_addr. kernel_args[] is 20943d520f3SAlex Deymo * appended to the kernel commandline in the tags. 21043d520f3SAlex Deymo * 7. r0 = 0, r1 = MACHINE_TYPE, r2 = tags_addr 21143d520f3SAlex Deymo * 8. if second_size != 0: jump to second_addr 21243d520f3SAlex Deymo * else: jump to kernel_addr 21343d520f3SAlex Deymo */ 21443d520f3SAlex Deymo 215*745aeb1aSJoseph Chen /* When the boot image header has a version of 3, the structure of the boot 216*745aeb1aSJoseph Chen * image is as follows: 217*745aeb1aSJoseph Chen * 218*745aeb1aSJoseph Chen * +---------------------+ 219*745aeb1aSJoseph Chen * | boot header | 4096 bytes 220*745aeb1aSJoseph Chen * +---------------------+ 221*745aeb1aSJoseph Chen * | kernel | m pages 222*745aeb1aSJoseph Chen * +---------------------+ 223*745aeb1aSJoseph Chen * | ramdisk | n pages 224*745aeb1aSJoseph Chen * +---------------------+ 225*745aeb1aSJoseph Chen * 226*745aeb1aSJoseph Chen * m = (kernel_size + 4096 - 1) / 4096 227*745aeb1aSJoseph Chen * n = (ramdisk_size + 4096 - 1) / 4096 228*745aeb1aSJoseph Chen * 229*745aeb1aSJoseph Chen * Note that in version 3 of the boot image header, page size is fixed at 4096 bytes. 230*745aeb1aSJoseph Chen * 231*745aeb1aSJoseph Chen * The structure of the vendor boot image (introduced with version 3 and 232*745aeb1aSJoseph Chen * required to be present when a v3 boot image is used) is as follows: 233*745aeb1aSJoseph Chen * 234*745aeb1aSJoseph Chen * +---------------------+ 235*745aeb1aSJoseph Chen * | vendor boot header | o pages 236*745aeb1aSJoseph Chen * +---------------------+ 237*745aeb1aSJoseph Chen * | vendor ramdisk | p pages 238*745aeb1aSJoseph Chen * +---------------------+ 239*745aeb1aSJoseph Chen * | dtb | q pages 240*745aeb1aSJoseph Chen * +---------------------+ 241*745aeb1aSJoseph Chen * 242*745aeb1aSJoseph Chen * o = (2112 + page_size - 1) / page_size 243*745aeb1aSJoseph Chen * p = (vendor_ramdisk_size + page_size - 1) / page_size 244*745aeb1aSJoseph Chen * q = (dtb_size + page_size - 1) / page_size 245*745aeb1aSJoseph Chen * 246*745aeb1aSJoseph Chen * 0. all entities in the boot image are 4096-byte aligned in flash, all 247*745aeb1aSJoseph Chen * entities in the vendor boot image are page_size (determined by the vendor 248*745aeb1aSJoseph Chen * and specified in the vendor boot image header) aligned in flash 249*745aeb1aSJoseph Chen * 1. kernel, ramdisk, vendor ramdisk, and DTB are required (size != 0) 250*745aeb1aSJoseph Chen * 2. load the kernel and DTB at the specified physical address (kernel_addr, 251*745aeb1aSJoseph Chen * dtb_addr) 252*745aeb1aSJoseph Chen * 3. load the vendor ramdisk at ramdisk_addr 253*745aeb1aSJoseph Chen * 4. load the generic ramdisk immediately following the vendor ramdisk in 254*745aeb1aSJoseph Chen * memory 255*745aeb1aSJoseph Chen * 5. set up registers for kernel entry as required by your architecture 256*745aeb1aSJoseph Chen * 6. if the platform has a second stage bootloader jump to it (must be 257*745aeb1aSJoseph Chen * contained outside boot and vendor boot partitions), otherwise 258*745aeb1aSJoseph Chen * jump to kernel_addr 259*745aeb1aSJoseph Chen */ 260*745aeb1aSJoseph Chen 2619ace3fc8SSebastian Siewior #endif 262