[PATCH v1] include: android_bootloader_message.h: sync with AOSP upstream

Igor Opaniuk igor.opaniuk at gmail.com
Mon Feb 19 11:15:59 CET 2024


This takes the latest changes from AOSP from [1][2] (as this
header was split on two) with minimal changes (this could lead
to warnings reported by checkpatch).

Some local changes have been applied:
1. Enable static_assert() for defined structures to be sure
that all of them have correct sizes.
2. Adjuste types in bootloader_control structure with bitfields
(uint8_t -> uint16_t). It seems that gcc just doesn't like bitfields
that cross the width of the type. Changing the type doesn't change
the layout though.
This addresses this gcc note:
In file included from boot/android_ab.c:7:
include/android_bootloader_message.h:230:1: note: offset of packed bit-field ‘merge_status’ has changed in GCC 4.4
  230 | } __attribute__((packed));

[1] https://android.googlesource.com/platform/bootable/recovery/+/main/bootloader_message/include/bootloader_message/bootloader_message.h
[2] https://android.googlesource.com/platform/hardware/interfaces/+/main/boot/1.1/default/boot_control/include/private/boot_control_definition.h

CC: Alex Deymo <deymo at google.com>
CC: Sam Protsenko <semen.protsenko at linaro.org>
CC: Eugeniu Rosca <erosca at de.adit-jv.com>
CC: Simon Glass <sjg at chromium.org>
Signed-off-by: Igor Opaniuk <igor.opaniuk at gmail.com>
---

 include/android_bootloader_message.h | 104 +++++++++++++++++++++++----
 1 file changed, 92 insertions(+), 12 deletions(-)

diff --git a/include/android_bootloader_message.h b/include/android_bootloader_message.h
index 286d7ab0f31..75198fc9dc2 100644
--- a/include/android_bootloader_message.h
+++ b/include/android_bootloader_message.h
@@ -21,17 +21,22 @@
  * stddef.h
  */
 #include <compiler.h>
+#include <linux/build_bug.h>
 #endif
 
 // Spaces used by misc partition are as below:
 // 0   - 2K     For bootloader_message
 // 2K  - 16K    Used by Vendor's bootloader (the 2K - 4K range may be optionally used
 //              as bootloader_message_ab struct)
-// 16K - 64K    Used by uncrypt and recovery to store wipe_package for A/B devices
+// 16K - 32K    Used by uncrypt and recovery to store wipe_package for A/B devices
+// 32K - 64K    System space, used for miscellanious AOSP features. See below.
 // Note that these offsets are admitted by bootloader,recovery and uncrypt, so they
 // are not configurable without changing all of them.
 static const size_t BOOTLOADER_MESSAGE_OFFSET_IN_MISC = 0;
+static const size_t VENDOR_SPACE_OFFSET_IN_MISC = 2 * 1024;
 static const size_t WIPE_PACKAGE_OFFSET_IN_MISC = 16 * 1024;
+static const size_t SYSTEM_SPACE_OFFSET_IN_MISC = 32 * 1024;
+static const size_t SYSTEM_SPACE_SIZE_IN_MISC = 32 * 1024;
 
 /* Bootloader Message (2-KiB)
  *
@@ -81,24 +86,67 @@ struct bootloader_message {
     char reserved[1184];
 };
 
+// Holds Virtual A/B merge status information. Current version is 1. New fields
+// must be added to the end.
+struct misc_virtual_ab_message {
+  uint8_t version;
+  uint32_t magic;
+  uint8_t merge_status;  // IBootControl 1.1, MergeStatus enum.
+  uint8_t source_slot;   // Slot number when merge_status was written.
+  uint8_t reserved[57];
+} __attribute__((packed));
+
+struct misc_memtag_message {
+  uint8_t version;
+  uint32_t magic; // magic string for treble compat
+  uint32_t memtag_mode;
+  uint8_t reserved[55];
+} __attribute__((packed));
+
+struct misc_kcmdline_message {
+  uint8_t version;
+  uint32_t magic;
+  uint64_t kcmdline_flags;
+  uint8_t reserved[51];
+} __attribute__((packed));
+
+#define MISC_VIRTUAL_AB_MESSAGE_VERSION 2
+#define MISC_VIRTUAL_AB_MAGIC_HEADER 0x56740AB0
+
+#define MISC_MEMTAG_MESSAGE_VERSION 1
+#define MISC_MEMTAG_MAGIC_HEADER 0x5afefe5a
+#define MISC_MEMTAG_MODE_MEMTAG 0x1
+#define MISC_MEMTAG_MODE_MEMTAG_ONCE 0x2
+#define MISC_MEMTAG_MODE_MEMTAG_KERNEL 0x4
+#define MISC_MEMTAG_MODE_MEMTAG_KERNEL_ONCE 0x8
+#define MISC_MEMTAG_MODE_MEMTAG_OFF 0x10
+// This is set when the state was overridden forcibly. This does not need to be
+// interpreted by the bootloader but is only for bookkeeping purposes so
+// userspace knows what to do when the override is undone.
+// See system/extras/mtectrl in AOSP for more information.
+#define MISC_MEMTAG_MODE_FORCED 0x20
+
+#define MISC_KCMDLINE_MESSAGE_VERSION 1
+#define MISC_KCMDLINE_MAGIC_HEADER 0x6ab5110c
+#define MISC_KCMDLINE_BINDER_RUST 0x1
 /**
  * We must be cautious when changing the bootloader_message struct size,
  * because A/B-specific fields may end up with different offsets.
  */
-#ifndef __UBOOT__
+
 #if (__STDC_VERSION__ >= 201112L) || defined(__cplusplus)
 static_assert(sizeof(struct bootloader_message) == 2048,
               "struct bootloader_message size changes, which may break A/B devices");
 #endif
-#endif /* __UBOOT__ */
 
 /**
  * The A/B-specific bootloader message structure (4-KiB).
  *
  * We separate A/B boot control metadata from the regular bootloader
  * message struct and keep it here. Everything that's A/B-specific
- * stays after struct bootloader_message, which should be managed by
- * the A/B-bootloader or boot control HAL.
+ * stays after struct bootloader_message, which belongs to the vendor
+ * space of /misc partition. Also, the A/B-specific contents should be
+ * managed by the A/B-bootloader or boot control HAL.
  *
  * The slot_suffix field is used for A/B implementations where the
  * bootloader does not set the androidboot.ro.boot.slot_suffix kernel
@@ -124,12 +172,10 @@ struct bootloader_message_ab {
  * Be cautious about the struct size change, in case we put anything post
  * bootloader_message_ab struct (b/29159185).
  */
-#ifndef __UBOOT__
 #if (__STDC_VERSION__ >= 201112L) || defined(__cplusplus)
 static_assert(sizeof(struct bootloader_message_ab) == 4096,
               "struct bootloader_message_ab size changes");
 #endif
-#endif /* __UBOOT__ */
 
 #define BOOT_CTRL_MAGIC   0x42414342 /* Bootloader Control AB */
 #define BOOT_CTRL_VERSION 1
@@ -165,11 +211,13 @@ struct bootloader_control {
     // Version of struct being used (see BOOT_CTRL_VERSION).
     uint8_t version;
     // Number of slots being managed.
-    uint8_t nb_slot : 3;
+    uint16_t nb_slot : 3;
     // Number of times left attempting to boot recovery.
-    uint8_t recovery_tries_remaining : 3;
+    uint16_t recovery_tries_remaining : 3;
+    // Status of any pending snapshot merge of dynamic partitions.
+    uint16_t merge_status : 3;
     // Ensure 4-bytes alignment for slot_info field.
-    uint8_t reserved0[2];
+    uint8_t reserved0[1];
     // Per-slot information.  Up to 4 slots.
     struct slot_metadata slot_info[4];
     // Reserved for further use.
@@ -179,25 +227,46 @@ struct bootloader_control {
     uint32_t crc32_le;
 } __attribute__((packed));
 
-#ifndef __UBOOT__
 #if (__STDC_VERSION__ >= 201112L) || defined(__cplusplus)
 static_assert(sizeof(struct bootloader_control) ==
               sizeof(((struct bootloader_message_ab *)0)->slot_suffix),
               "struct bootloader_control has wrong size");
+static_assert(sizeof(struct misc_virtual_ab_message) == 64,
+              "struct misc_virtual_ab_message has wrong size");
+static_assert(sizeof(struct misc_memtag_message) == 64,
+              "struct misc_memtag_message has wrong size");
+static_assert(sizeof(struct misc_kcmdline_message) == 64,
+              "struct misc_kcmdline_message has wrong size");
 #endif
-#endif /* __UBOOT__ */
 
 #ifndef __UBOOT__
+
+// This struct is not meant to be used directly, rather, it is to make
+// computation of offsets easier. New fields must be added to the end.
+struct misc_system_space_layout {
+  misc_virtual_ab_message virtual_ab_message;
+  misc_memtag_message memtag_message;
+  misc_kcmdline_message kcmdline_message;
+} __attribute__((packed));
+
 #ifdef __cplusplus
 
 #include <string>
 #include <vector>
 
+// Gets the block device name of /misc partition.
+std::string get_misc_blk_device(std::string* err);
+
 // Return the block device name for the bootloader message partition and waits
 // for the device for up to 10 seconds. In case of error returns the empty
 // string.
 std::string get_bootloader_message_blk_device(std::string* err);
 
+// Writes |size| bytes of data from buffer |p| to |misc_blk_device| at |offset|. If the write fails,
+// sets the error message in |err|.
+bool write_misc_partition(const void* p, size_t size, const std::string& misc_blk_device,
+                          size_t offset, std::string* err);
+
 // Read bootloader message into boot. Error message will be set in err.
 bool read_bootloader_message(bootloader_message* boot, std::string* err);
 
@@ -242,6 +311,17 @@ bool read_wipe_package(std::string* package_data, size_t size, std::string* err)
 // Write the wipe package into BCB (to offset WIPE_PACKAGE_OFFSET_IN_MISC).
 bool write_wipe_package(const std::string& package_data, std::string* err);
 
+// Read or write the Virtual A/B message from system space in /misc.
+bool ReadMiscVirtualAbMessage(misc_virtual_ab_message* message, std::string* err);
+bool WriteMiscVirtualAbMessage(const misc_virtual_ab_message& message, std::string* err);
+
+// Read or write the memtag message from system space in /misc.
+bool ReadMiscMemtagMessage(misc_memtag_message* message, std::string* err);
+bool WriteMiscMemtagMessage(const misc_memtag_message& message, std::string* err);
+
+// Read or write the kcmdline message from system space in /misc.
+bool ReadMiscKcmdlineMessage(misc_kcmdline_message* message, std::string* err);
+bool WriteMiscKcmdlineMessage(const misc_kcmdline_message& message, std::string* err);
 #else
 
 #include <stdbool.h>
-- 
2.34.1



More information about the U-Boot mailing list