diff options
| author | David Anderson <dvander@google.com> | 2019-11-04 14:08:11 -0800 |
|---|---|---|
| committer | David Anderson <dvander@google.com> | 2019-11-08 15:22:21 -0800 |
| commit | cf8427af89f47075953dad10d6ea9b848736527f (patch) | |
| tree | ff5b71f4a30251ad26692cfe706e19d850c339a3 /bootloader_message | |
| parent | 8243388d57dab69f41c9c2b494d7c19de775aecb (diff) | |
bootloader_message: Add helpers for handling IBootControl MergeStatus.
Move merge_status from bootloader_control_ab, which is in vendor space,
to a new generic AOSP struct in system space. This will allow more
devices to share the same HAL implementation.
This patch also changes libboot_control to compensate for merge_status
moving out of vendor space. The reference HAL library now also provides
separate helper functions for managing the merge status, so devices
using a custom boot control HAL can still take advantage of the new misc
implementation.
Bug: 139156011
Test: manual test
Change-Id: I5cd824e25f9d07aad1476301def5cdc3f506b029
Diffstat (limited to 'bootloader_message')
| -rw-r--r-- | bootloader_message/bootloader_message.cpp | 43 | ||||
| -rw-r--r-- | bootloader_message/include/bootloader_message/bootloader_message.h | 26 |
2 files changed, 69 insertions, 0 deletions
diff --git a/bootloader_message/bootloader_message.cpp b/bootloader_message/bootloader_message.cpp index f838930f..4f7085db 100644 --- a/bootloader_message/bootloader_message.cpp +++ b/bootloader_message/bootloader_message.cpp @@ -292,6 +292,49 @@ bool WriteMiscPartitionVendorSpace(const void* data, size_t size, size_t offset, err); } +static bool ValidateSystemSpaceRegion(size_t offset, size_t size, std::string* err) { + if (size <= SYSTEM_SPACE_SIZE_IN_MISC && offset <= (SYSTEM_SPACE_SIZE_IN_MISC - size)) { + return true; + } + *err = android::base::StringPrintf("Out of bound access (offset %zu size %zu)", offset, size); + return false; +} + +static bool ReadMiscPartitionSystemSpace(void* data, size_t size, size_t offset, std::string* err) { + if (!ValidateSystemSpaceRegion(offset, size, err)) { + return false; + } + auto misc_blk_device = get_misc_blk_device(err); + if (misc_blk_device.empty()) { + return false; + } + return read_misc_partition(data, size, misc_blk_device, SYSTEM_SPACE_OFFSET_IN_MISC + offset, + err); +} + +static bool WriteMiscPartitionSystemSpace(const void* data, size_t size, size_t offset, + std::string* err) { + if (!ValidateSystemSpaceRegion(offset, size, err)) { + return false; + } + auto misc_blk_device = get_misc_blk_device(err); + if (misc_blk_device.empty()) { + return false; + } + return write_misc_partition(data, size, misc_blk_device, SYSTEM_SPACE_OFFSET_IN_MISC + offset, + err); +} + +bool ReadMiscVirtualAbMessage(misc_virtual_ab_message* message, std::string* err) { + return ReadMiscPartitionSystemSpace(message, sizeof(*message), + offsetof(misc_system_space_layout, virtual_ab_message), err); +} + +bool WriteMiscVirtualAbMessage(const misc_virtual_ab_message& message, std::string* err) { + return WriteMiscPartitionSystemSpace(&message, sizeof(message), + offsetof(misc_system_space_layout, virtual_ab_message), err); +} + extern "C" bool write_reboot_bootloader(void) { std::string err; return write_reboot_bootloader(&err); diff --git a/bootloader_message/include/bootloader_message/bootloader_message.h b/bootloader_message/include/bootloader_message/bootloader_message.h index e3425fc8..3a3b862a 100644 --- a/bootloader_message/include/bootloader_message/bootloader_message.h +++ b/bootloader_message/include/bootloader_message/bootloader_message.h @@ -185,6 +185,28 @@ static_assert(sizeof(struct bootloader_control) == "struct bootloader_control has wrong size"); #endif +// 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; + uint8_t merge_status; // IBootControl 1.1, MergeStatus enum. + uint8_t source_slot; // Slot number when merge_status was written. + uint8_t reserved[61]; +} __attribute__((packed)); + +#define MISC_VIRTUAL_AB_MESSAGE_VERSION 1 + +#if (__STDC_VERSION__ >= 201112L) || defined(__cplusplus) +static_assert(sizeof(struct misc_virtual_ab_message) == 64, + "struct misc_virtual_ab_message has wrong size"); +#endif + +// 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; +} __attribute__((packed)); + #ifdef __cplusplus #include <string> @@ -247,6 +269,10 @@ bool ReadMiscPartitionVendorSpace(void* data, size_t size, size_t offset, std::s // offset is in relative to the start of the vendor space. bool WriteMiscPartitionVendorSpace(const void* data, size_t size, size_t offset, 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); + #else #include <stdbool.h> |
