common: android_ab: move the ab functions to android_ab.c

Move the ab functions to android_ab.c and add "ab_" prefix to
api function.

Signed-off-by: Jason Zhu <jason.zhu@rock-chips.com>
Change-Id: I4527a0c957aa7853a1b75d456ca3fabaf80c1c57
This commit is contained in:
Jason Zhu 2020-09-29 16:47:22 +08:00 committed by Jianhong Chen
parent cf87ffd351
commit cee2fb0e57
3 changed files with 191 additions and 183 deletions

View File

@ -7,8 +7,12 @@
#include <android_ab.h>
#include <android_bootloader_message.h>
#include <android_image.h>
#include <boot_rkimg.h>
#include <common.h>
#include <malloc.h>
#include <android_avb/avb_ops_user.h>
#include <android_avb/rk_avb_ops_user.h>
#include <u-boot/crc.h>
#include <boot_rkimg.h>
@ -332,3 +336,172 @@ int write_misc_virtual_ab_message(struct misc_virtual_ab_message *message)
return 0;
}
int ab_is_support_dynamic_partition(struct blk_desc *dev_desc)
{
disk_partition_t super_part_info;
disk_partition_t boot_part_info;
int part_num;
int is_dp = 0;
char *super_dp = NULL;
char *super_info = "androidboot.super_partition=";
memset(&super_part_info, 0x0, sizeof(super_part_info));
part_num = part_get_info_by_name(dev_desc, ANDROID_PARTITION_SUPER,
&super_part_info);
if (part_num < 0) {
memset(&boot_part_info, 0x0, sizeof(boot_part_info));
part_num = part_get_info_by_name(dev_desc, ANDROID_PARTITION_BOOT,
&boot_part_info);
if (part_num < 0) {
is_dp = 0;
} else {
andr_img_hdr hdr;
ulong hdr_blocks = sizeof(struct andr_img_hdr) /
boot_part_info.blksz;
memset(&hdr, 0x0, sizeof(hdr));
if (blk_dread(dev_desc, boot_part_info.start, hdr_blocks, &hdr) !=
hdr_blocks) {
is_dp = 0;
} else {
debug("hdr cmdline=%s\n", hdr.cmdline);
super_dp = strstr(hdr.cmdline, super_info);
if (super_dp)
is_dp = 1;
else
is_dp = 0;
}
}
} else {
debug("Find super partition, the firmware support dynamic partition\n");
is_dp = 1;
}
debug("%s is_dp=%d\n", __func__, is_dp);
return is_dp;
}
static int get_partition_unique_uuid(char *partition,
char *guid_buf,
size_t guid_buf_size)
{
struct blk_desc *dev_desc;
disk_partition_t part_info;
dev_desc = rockchip_get_bootdev();
if (!dev_desc) {
printf("%s: Could not find device\n", __func__);
return -1;
}
if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
printf("Could not find \"%s\" partition\n", partition);
return -1;
}
if (guid_buf && guid_buf_size > 0)
memcpy(guid_buf, part_info.uuid, guid_buf_size);
return 0;
}
void ab_update_root_uuid(void)
{
/*
* In android a/b & avb process, the system.img is mandory and the
* "root=" will be added in vbmeta.img.
*
* In linux a/b & avb process, the system is NOT mandory and the
* "root=" will not be added in vbmeta.img but in kernel dts bootargs.
* (Parsed and dropped late, i.e. "root=" is not available now/always).
*
* To compatible with the above two processes, test the existence of
* "root=" and create it for linux ab & avb.
*/
char root_partuuid[70] = "root=PARTUUID=";
char *boot_args = env_get("bootargs");
char guid_buf[UUID_SIZE] = {0};
struct blk_desc *dev_desc;
dev_desc = rockchip_get_bootdev();
if (!dev_desc) {
printf("%s: Could not find device\n", __func__);
return;
}
if (ab_is_support_dynamic_partition(dev_desc))
return;
if (!strstr(boot_args, "root=")) {
get_partition_unique_uuid(ANDROID_PARTITION_SYSTEM,
guid_buf, UUID_SIZE);
strcat(root_partuuid, guid_buf);
env_update("bootargs", root_partuuid);
}
}
int ab_get_slot_suffix(char *slot_suffix)
{
/* TODO: get from pre-loader or misc partition */
if (rk_avb_get_current_slot(slot_suffix)) {
printf("rk_avb_get_current_slot() failed\n");
return -1;
}
if (slot_suffix[0] != '_') {
#ifndef CONFIG_ANDROID_AVB
printf("###There is no bootable slot, bring up lastboot!###\n");
if (rk_get_lastboot() == 1)
memcpy(slot_suffix, "_b", 2);
else if (rk_get_lastboot() == 0)
memcpy(slot_suffix, "_a", 2);
else
#endif
return -1;
}
return 0;
}
int ab_decrease_tries(void)
{
AvbABData ab_data_orig;
AvbABData ab_data;
char slot_suffix[3] = {0};
AvbOps *ops;
size_t slot_index = 0;
if (ab_get_slot_suffix(slot_suffix))
return -1;
if (!strncmp(slot_suffix, "_a", 2))
slot_index = 0;
else if (!strncmp(slot_suffix, "_b", 2))
slot_index = 1;
else
slot_index = 0;
ops = avb_ops_user_new();
if (!ops) {
printf("avb_ops_user_new() failed!\n");
return -1;
}
if (load_metadata(ops->ab_ops, &ab_data, &ab_data_orig)) {
printf("Can not load metadata\n");
return -1;
}
/* ... and decrement tries remaining, if applicable. */
if (!ab_data.slots[slot_index].successful_boot &&
ab_data.slots[slot_index].tries_remaining > 0)
ab_data.slots[slot_index].tries_remaining -= 1;
if (save_metadata_if_changed(ops->ab_ops, &ab_data, &ab_data_orig)) {
printf("Can not save metadata\n");
return -1;
}
return 0;
}

View File

@ -10,6 +10,7 @@
#include <android_avb/avb_ops_user.h>
#include <android_avb/rk_avb_ops_user.h>
#include <android_image.h>
#include <android_ab.h>
#include <bootm.h>
#include <asm/arch/hotkey.h>
#include <cli.h>
@ -30,183 +31,6 @@
DECLARE_GLOBAL_DATA_PTR;
#ifdef CONFIG_ANDROID_AB
static int is_support_dynamic_partition(struct blk_desc *dev_desc)
{
disk_partition_t super_part_info;
disk_partition_t boot_part_info;
int part_num;
int is_dp = 0;
char *super_dp = NULL;
char *super_info = "androidboot.super_partition=";
memset(&super_part_info, 0x0, sizeof(super_part_info));
part_num = part_get_info_by_name(dev_desc, ANDROID_PARTITION_SUPER,
&super_part_info);
if (part_num < 0) {
memset(&boot_part_info, 0x0, sizeof(boot_part_info));
part_num = part_get_info_by_name(dev_desc, ANDROID_PARTITION_BOOT,
&boot_part_info);
if (part_num < 0) {
is_dp = 0;
} else {
andr_img_hdr hdr;
ulong hdr_blocks = sizeof(struct andr_img_hdr) /
boot_part_info.blksz;
memset(&hdr, 0x0, sizeof(hdr));
if (blk_dread(dev_desc, boot_part_info.start, hdr_blocks, &hdr) !=
hdr_blocks) {
is_dp = 0;
} else {
debug("hdr cmdline=%s\n", hdr.cmdline);
super_dp = strstr(hdr.cmdline, super_info);
if (super_dp != NULL) {
is_dp = 1;
} else {
is_dp = 0;
}
}
}
} else {
debug("Find super partition, the firmware support dynamic partition\n");
is_dp = 1;
}
debug("%s is_dp=%d\n", __func__, is_dp);
return is_dp;
}
static int get_partition_unique_uuid(char *partition,
char *guid_buf,
size_t guid_buf_size)
{
struct blk_desc *dev_desc;
disk_partition_t part_info;
dev_desc = rockchip_get_bootdev();
if (!dev_desc) {
printf("%s: Could not find device\n", __func__);
return -1;
}
if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
printf("Could not find \"%s\" partition\n", partition);
return -1;
}
if (guid_buf && guid_buf_size > 0)
memcpy(guid_buf, part_info.uuid, guid_buf_size);
return 0;
}
static void update_root_uuid_if_android_ab(void)
{
/*
* In android a/b & avb process, the system.img is mandory and the
* "root=" will be added in vbmeta.img.
*
* In linux a/b & avb process, the system is NOT mandory and the
* "root=" will not be added in vbmeta.img but in kernel dts bootargs.
* (Parsed and droped late, i.e. "root=" is not available now/always).
*
* To compatible with the above two processes, test the existence of
* "root=" and create it for linux ab & avb.
*/
char root_partuuid[70] = "root=PARTUUID=";
char *boot_args = env_get("bootargs");
char guid_buf[UUID_SIZE] = {0};
struct blk_desc *dev_desc;
dev_desc = rockchip_get_bootdev();
if (!dev_desc) {
printf("%s: Could not find device\n", __func__);
return;
}
if (is_support_dynamic_partition(dev_desc)) {
return;
}
if (!strstr(boot_args, "root=")) {
get_partition_unique_uuid(ANDROID_PARTITION_SYSTEM,
guid_buf, UUID_SIZE);
strcat(root_partuuid, guid_buf);
env_update("bootargs", root_partuuid);
}
}
static int get_slot_suffix_if_android_ab(char *slot_suffix)
{
/* TODO: get from pre-loader or misc partition */
if (rk_avb_get_current_slot(slot_suffix)) {
printf("rk_avb_get_current_slot() failed\n");
return -1;
}
if (slot_suffix[0] != '_') {
#ifndef CONFIG_ANDROID_AVB
printf("###There is no bootable slot, bring up lastboot!###\n");
if (rk_get_lastboot() == 1)
memcpy(slot_suffix, "_b", 2);
else if (rk_get_lastboot() == 0)
memcpy(slot_suffix, "_a", 2);
else
#endif
return -1;
}
return 0;
}
static int decrease_tries_if_android_ab(void)
{
AvbABData ab_data_orig;
AvbABData ab_data;
char slot_suffix[3] = {0};
AvbOps *ops;
size_t slot_index = 0;
if (get_slot_suffix_if_android_ab(slot_suffix))
return -1;
if (!strncmp(slot_suffix, "_a", 2))
slot_index = 0;
else if (!strncmp(slot_suffix, "_b", 2))
slot_index = 1;
else
slot_index = 0;
ops = avb_ops_user_new();
if (!ops) {
printf("avb_ops_user_new() failed!\n");
return -1;
}
if (load_metadata(ops->ab_ops, &ab_data, &ab_data_orig)) {
printf("Can not load metadata\n");
return -1;
}
/* ... and decrement tries remaining, if applicable. */
if (!ab_data.slots[slot_index].successful_boot &&
ab_data.slots[slot_index].tries_remaining > 0)
ab_data.slots[slot_index].tries_remaining -= 1;
if (save_metadata_if_changed(ops->ab_ops, &ab_data, &ab_data_orig)) {
printf("Can not save metadata\n");
return -1;
}
return 0;
}
#else
static inline void update_root_uuid_if_android_ab(void) {}
static int get_slot_suffix_if_android_ab(char *slot_suffix) { return 0; }
static inline int decrease_tries_if_android_ab(void) { return 0; }
#endif
#if defined(CONFIG_ANDROID_AB) && defined(CONFIG_ANDROID_AVB)
static void reset_cpu_if_android_ab(void)
{
@ -1094,11 +918,11 @@ int android_bootloader_boot_flow(struct blk_desc *dev_desc,
}
printf("ANDROID: reboot reason: \"%s\"\n", android_boot_mode_str(mode));
#ifdef CONFIG_ANDROID_AB
/* Get current slot_suffix */
if (get_slot_suffix_if_android_ab(slot_suffix))
if (ab_get_slot_suffix(slot_suffix))
return -1;
#endif
switch (mode) {
case ANDROID_BOOT_MODE_NORMAL:
/* In normal mode, we load the kernel from "boot" but append
@ -1115,7 +939,7 @@ int android_bootloader_boot_flow(struct blk_desc *dev_desc,
* and then Android's first-stage init in ramdisk
* will skip recovery and boot normal Android.
*/
if (is_support_dynamic_partition(dev_desc)) {
if (ab_is_support_dynamic_partition(dev_desc)) {
mode_cmdline = "androidboot.force_normal_boot=1";
} else {
mode_cmdline = "skip_initramfs";
@ -1193,7 +1017,10 @@ int android_bootloader_boot_flow(struct blk_desc *dev_desc,
return -1;
}
#endif
update_root_uuid_if_android_ab();
#ifdef CONFIG_ANDROID_AB
ab_update_root_uuid();
#endif
/* Set Android root variables. */
env_set_ulong("android_root_devnum", dev_desc->devnum);
@ -1230,8 +1057,10 @@ int android_bootloader_boot_flow(struct blk_desc *dev_desc,
printf("Close optee client failed!\n");
#endif
if (decrease_tries_if_android_ab())
#ifdef CONFIG_ANDROID_AB
if (ab_decrease_tries())
printf("Decrease ab tries count fail!\n");
#endif
android_bootloader_boot_kernel(load_address);

View File

@ -46,4 +46,10 @@ 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);
void ab_update_root_uuid(void);
int ab_get_slot_suffix(char *slot_suffix);
int ab_is_support_dynamic_partition(struct blk_desc *dev_desc);
int ab_decrease_tries(void);
#endif