Add boot / vendor boot image header version 4

The format of boot image v4 is the same as v3.
Vendor boot v4 supports packaging multiple vendor ramdisks by having an
additional section containing a vendor ramdisk table.
The table describes the metadata of each ramdisk, and the offset of each
ramdisk in the vendor ramdisk section.
With these information the bootloader can select a subset of the
ramdisks to load at runtime, and skip loading ramdisks that it knows are
not needed.
The bootloader can also choose to ignore the vendor ramdisk table and
just load the entire vendor ramdisk section. This would have the same
effect as loading all ramdisks in the table.
This lays the foundation for golden boot images.

Bug: 162864255
Test: Presubmit build test
Change-Id: Id3debe7163d802a35aead6f6c076c3ff69c303ee
diff --git a/include/bootimg/bootimg.h b/include/bootimg/bootimg.h
index c60acbf..6aa3910 100644
--- a/include/bootimg/bootimg.h
+++ b/include/bootimg/bootimg.h
@@ -29,6 +29,12 @@
 #define VENDOR_BOOT_ARGS_SIZE 2048
 #define VENDOR_BOOT_NAME_SIZE 16
 
+#define VENDOR_RAMDISK_TYPE_NONE 0
+#define VENDOR_RAMDISK_TYPE_PLATFORM 1
+#define VENDOR_RAMDISK_TYPE_RECOVERY 2
+#define VENDOR_RAMDISK_TYPE_DLKM 3
+#define VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE 16
+
 /* When a boot header is of version 0, the structure of boot image is as
  * follows:
  *
@@ -298,3 +304,94 @@
     uint32_t dtb_size; /* size in bytes for DTB image */
     uint64_t dtb_addr; /* physical load address for DTB image */
 } __attribute__((packed));
+
+/* When the boot image header has a version of 4, the structure of the boot
+ * image is the same as version 3:
+ *
+ * +---------------------+
+ * | boot header         | 4096 bytes
+ * +---------------------+
+ * | kernel              | m pages
+ * +---------------------+
+ * | ramdisk             | n pages
+ * +---------------------+
+ *
+ * m = (kernel_size + 4096 - 1) / 4096
+ * n = (ramdisk_size + 4096 - 1) / 4096
+ *
+ * Note that in version 4 of the boot image header, page size is fixed at 4096
+ * bytes.
+ *
+ * The structure of the vendor boot image version 4, which is required to be
+ * present when a version 4 boot image is used, is as follows:
+ *
+ * +------------------------+
+ * | vendor boot header     | o pages
+ * +------------------------+
+ * | vendor ramdisk section | p pages
+ * +------------------------+
+ * | dtb                    | q pages
+ * +------------------------+
+ * | vendor ramdisk table   | r pages
+ * +------------------------+
+ *
+ * o = (2124 + page_size - 1) / page_size
+ * p = (vendor_ramdisk_size + page_size - 1) / page_size
+ * q = (dtb_size + page_size - 1) / page_size
+ * r = (vendor_ramdisk_table_size + page_size - 1) / page_size
+ *
+ * Note that in version 4 of the vendor boot image, multiple vendor ramdisks can
+ * be included in the vendor boot image. The bootloader can select a subset of
+ * ramdisks to load at runtime. To help the bootloader select the ramdisks, each
+ * ramdisk is tagged with a type tag and a set of hardware identifiers
+ * describing the board, soc or platform that this ramdisk is intended for.
+ *
+ * The vendor ramdisk section is consist of multiple ramdisk images concatenated
+ * one after another, and vendor_ramdisk_size is the size of the section, which
+ * is the total size of all the ramdisks included in the vendor boot image.
+ *
+ * The vendor ramdisk table holds the size, offset, type and hardware
+ * identifiers of each ramdisk. The type field denotes the type of its content.
+ * The hardware identifiers are specified in the board_id field in each table
+ * entry. The board_id field is consist of a vector of unsigned integer words,
+ * and the encoding scheme is defined by the hardware vendor.
+ *
+ * For the different type of ramdisks, there are:
+ *    - VENDOR_RAMDISK_TYPE_NONE indicates the value is unspecified.
+ *    - VENDOR_RAMDISK_TYPE_PLATFORM ramdisk contains platform specific bits.
+ *    - VENDOR_RAMDISK_TYPE_RECOVERY ramdisk contains recovery resources.
+ *    - VENDOR_RAMDISK_TYPE_DLKM ramdisk contains dynamic loadable kernel
+ *      modules.
+ *
+ * 0. all entities in the boot image are 4096-byte aligned in flash, all
+ *    entities in the vendor boot image are page_size (determined by the vendor
+ *    and specified in the vendor boot image header) aligned in flash
+ * 1. kernel, ramdisk, and DTB are required (size != 0)
+ * 2. load the kernel and DTB at the specified physical address (kernel_addr,
+ *    dtb_addr)
+ * 3. load the vendor ramdisks at ramdisk_addr
+ * 4. load the generic ramdisk immediately following the vendor ramdisk in
+ *    memory
+ * 5. set up registers for kernel entry as required by your architecture
+ * 6. if the platform has a second stage bootloader jump to it (must be
+ *    contained outside boot and vendor boot partitions), otherwise
+ *    jump to kernel_addr
+ */
+struct boot_img_hdr_v4 : public boot_img_hdr_v3 {
+} __attribute__((packed));
+
+struct vendor_boot_img_hdr_v4 : public vendor_boot_img_hdr_v3 {
+    uint32_t vendor_ramdisk_table_size; /* size in bytes for the vendor ramdisk table */
+    uint32_t vendor_ramdisk_table_entry_num; /* number of entries in the vendor ramdisk table */
+    uint32_t vendor_ramdisk_table_entry_size; /* size in bytes for a vendor ramdisk table entry */
+} __attribute__((packed));
+
+struct vendor_ramdisk_table_entry_v4 {
+    uint32_t ramdisk_size; /* size in bytes for the ramdisk image */
+    uint32_t ramdisk_offset; /* offset to the ramdisk image in vendor ramdisk section */
+    uint32_t ramdisk_type; /* type of the ramdisk */
+
+    // Hardware identifiers describing the board, soc or platform which this
+    // ramdisk is intended to be loaded on.
+    uint32_t board_id[VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE];
+} __attribute__((packed));