rockchip: rkimg: Add R/W interfaces for virtual A/B metadata

According to the AOSP default definition, the virtual A/B
metadata is located at the offset 32KB of the misc partition.

Signed-off-by: Dayao Ji <jdy@rock-chips.com>
Change-Id: Ib60379f25e4c72be9f5ed03934ab7dc928cdd585
This commit is contained in:
Dayao Ji 2020-09-22 11:52:43 +08:00
parent ab2b3191ab
commit 132e9ecacf
4 changed files with 92 additions and 1 deletions

View File

@ -10,6 +10,7 @@
#include <common.h> #include <common.h>
#include <malloc.h> #include <malloc.h>
#include <u-boot/crc.h> #include <u-boot/crc.h>
#include <boot_rkimg.h>
/** android_boot_control_compute_crc - Compute the CRC-32 of the bootloader /** 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 * 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 -1;
return slot; 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;
}

View File

@ -12,6 +12,22 @@
/* Android standard boot slot names are 'a', 'b', 'c', ... */ /* Android standard boot slot names are 'a', 'b', 'c', ... */
#define ANDROID_BOOT_SLOT_NAME(slot_num) ('a' + (slot_num)) #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. /** android_ab_select - Select the slot where to boot from.
* On Android devices with more than one boot slot (multiple copies of the * 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 * 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); 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 #endif

View File

@ -21,12 +21,14 @@
* 0 - 2K Bootloader Message * 0 - 2K Bootloader Message
* 2K - 16K Used by Vendor's bootloader (the 2K - 4K range may be optionally used * 2K - 16K Used by Vendor's bootloader (the 2K - 4K range may be optionally used
* as bootloader_message_ab struct) * 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 * Note that these offsets are admitted by bootloader,recovery and uncrypt, so they
* are not configurable without changing all of them. * are not configurable without changing all of them.
*/ */
static const size_t ANDROID_BOOTLOADER_MESSAGE_OFFSET_IN_MISC = 0; 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_WIPE_PACKAGE_OFFSET_IN_MISC = 16 * 1024;
static const size_t ANDROID_VIRTUAL_AB_METADATA_OFFSET_IN_MISC = 32 * 1024;
/* Bootloader Message (2-KiB) /* Bootloader Message (2-KiB)
* *

View File

@ -59,6 +59,8 @@ struct rockchip_image {
#define PART_DTBO "dtbo" #define PART_DTBO "dtbo"
#define PART_LOGO "logo" #define PART_LOGO "logo"
#define PART_SYSTEM "system" #define PART_SYSTEM "system"
#define PART_METADATA "metadata"
#define PART_USERDATA "userdata"
struct blk_desc *rockchip_get_bootdev(void); struct blk_desc *rockchip_get_bootdev(void);
void rockchip_set_bootdev(struct blk_desc *desc); void rockchip_set_bootdev(struct blk_desc *desc);