diff --git a/common/android_ab.c b/common/android_ab.c index cfbf5301a5..6ff1e32d54 100644 --- a/common/android_ab.c +++ b/common/android_ab.c @@ -10,6 +10,7 @@ #include #include #include +#include /** android_boot_control_compute_crc - Compute the CRC-32 of the bootloader * control struct. Only the bytes up to the crc32_le field are considered for @@ -264,3 +265,70 @@ int android_ab_select(struct blk_desc *dev_desc, disk_partition_t *part_info) return -1; return slot; } + +int read_misc_virtual_ab_message(struct misc_virtual_ab_message *message) +{ + struct blk_desc *dev_desc; + disk_partition_t part_info; + u32 bcb_offset = (ANDROID_VIRTUAL_AB_METADATA_OFFSET_IN_MISC >> 9); + int cnt, ret; + + if (!message) { + debug("%s: message is NULL!\n", __func__); + return -1; + } + + dev_desc = rockchip_get_bootdev(); + if (!dev_desc) { + debug("%s: dev_desc is NULL!\n", __func__); + return -1; + } + + ret = part_get_info_by_name(dev_desc, PART_MISC, &part_info); + if (ret < 0) { + debug("%s: Could not found misc partition\n", + __func__); + return -1; + } + + cnt = DIV_ROUND_UP(sizeof(struct misc_virtual_ab_message), dev_desc->blksz); + if (blk_dread(dev_desc, part_info.start + bcb_offset, cnt, message) != cnt) { + debug("%s: could not read from misc partition\n", __func__); + return -1; + } + + return 0; +} + +int write_misc_virtual_ab_message(struct misc_virtual_ab_message *message) +{ + struct blk_desc *dev_desc; + disk_partition_t part_info; + u32 bcb_offset = (ANDROID_VIRTUAL_AB_METADATA_OFFSET_IN_MISC >> 9); + int cnt, ret; + + if (!message) { + debug("%s: message is NULL!\n", __func__); + return -1; + } + + dev_desc = rockchip_get_bootdev(); + if (!dev_desc) { + debug("%s: dev_desc is NULL!\n", __func__); + return -1; + } + + ret = part_get_info_by_name(dev_desc, PART_MISC, &part_info); + if (ret < 0) { + debug("%s: Could not found misc partition\n", + __func__); + return -1; + } + + cnt = DIV_ROUND_UP(sizeof(struct misc_virtual_ab_message), dev_desc->blksz); + ret = blk_dwrite(dev_desc, part_info.start + bcb_offset, cnt, message); + if (ret != cnt) + debug("%s: blk_dwrite write failed, ret=%d\n", __func__, ret); + + return 0; +} diff --git a/include/android_ab.h b/include/android_ab.h index c264e9b948..47e88b041c 100644 --- a/include/android_ab.h +++ b/include/android_ab.h @@ -12,6 +12,22 @@ /* Android standard boot slot names are 'a', 'b', 'c', ... */ #define ANDROID_BOOT_SLOT_NAME(slot_num) ('a' + (slot_num)) +#define ENUM_MERGE_STATUS_NONE (0) +#define ENUM_MERGE_STATUS_UNKNOWN (1) +#define ENUM_MERGE_STATUS_SNAPSHOTTED (2) +#define ENUM_MERGE_STATUS_MERGING (3) +#define ENUM_MERGE_STATUS_CANCELLED (4) +#define MISC_VIRTUAL_AB_MAGIC_HEADER (0x56740AB0) + +struct misc_virtual_ab_message { + u8 version; + u32 magic; + u8 merge_status; + u8 source_slot; + u8 reserved[57]; + u8 reserved2[448]; +} __packed; + /** android_ab_select - Select the slot where to boot from. * On Android devices with more than one boot slot (multiple copies of the * kernel and system images) selects which slot should be used to boot from and @@ -27,4 +43,7 @@ */ int android_ab_select(struct blk_desc *dev_desc, disk_partition_t *part_info); +/* Read or write the Virtual A/B message from 32KB offset in /misc.*/ +int read_misc_virtual_ab_message(struct misc_virtual_ab_message *message); +int write_misc_virtual_ab_message(struct misc_virtual_ab_message *message); #endif diff --git a/include/android_bootloader_message.h b/include/android_bootloader_message.h index 2c2142dc6f..9fa8cf0d2e 100644 --- a/include/android_bootloader_message.h +++ b/include/android_bootloader_message.h @@ -21,12 +21,14 @@ * 0 - 2K 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 miscellaneous AOSP features (virtual A/B metadata). * 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 ANDROID_BOOTLOADER_MESSAGE_OFFSET_IN_MISC = 0; static const size_t ANDROID_WIPE_PACKAGE_OFFSET_IN_MISC = 16 * 1024; +static const size_t ANDROID_VIRTUAL_AB_METADATA_OFFSET_IN_MISC = 32 * 1024; /* Bootloader Message (2-KiB) * diff --git a/include/boot_rkimg.h b/include/boot_rkimg.h index 8807aede9a..18b1309127 100644 --- a/include/boot_rkimg.h +++ b/include/boot_rkimg.h @@ -59,6 +59,8 @@ struct rockchip_image { #define PART_DTBO "dtbo" #define PART_LOGO "logo" #define PART_SYSTEM "system" +#define PART_METADATA "metadata" +#define PART_USERDATA "userdata" struct blk_desc *rockchip_get_bootdev(void); void rockchip_set_bootdev(struct blk_desc *desc);