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:
parent
cf87ffd351
commit
cee2fb0e57
|
|
@ -7,8 +7,12 @@
|
||||||
#include <android_ab.h>
|
#include <android_ab.h>
|
||||||
|
|
||||||
#include <android_bootloader_message.h>
|
#include <android_bootloader_message.h>
|
||||||
|
#include <android_image.h>
|
||||||
|
#include <boot_rkimg.h>
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <malloc.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 <u-boot/crc.h>
|
||||||
#include <boot_rkimg.h>
|
#include <boot_rkimg.h>
|
||||||
|
|
||||||
|
|
@ -332,3 +336,172 @@ int write_misc_virtual_ab_message(struct misc_virtual_ab_message *message)
|
||||||
|
|
||||||
return 0;
|
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;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
#include <android_avb/avb_ops_user.h>
|
#include <android_avb/avb_ops_user.h>
|
||||||
#include <android_avb/rk_avb_ops_user.h>
|
#include <android_avb/rk_avb_ops_user.h>
|
||||||
#include <android_image.h>
|
#include <android_image.h>
|
||||||
|
#include <android_ab.h>
|
||||||
#include <bootm.h>
|
#include <bootm.h>
|
||||||
#include <asm/arch/hotkey.h>
|
#include <asm/arch/hotkey.h>
|
||||||
#include <cli.h>
|
#include <cli.h>
|
||||||
|
|
@ -30,183 +31,6 @@
|
||||||
|
|
||||||
DECLARE_GLOBAL_DATA_PTR;
|
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)
|
#if defined(CONFIG_ANDROID_AB) && defined(CONFIG_ANDROID_AVB)
|
||||||
static void reset_cpu_if_android_ab(void)
|
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));
|
printf("ANDROID: reboot reason: \"%s\"\n", android_boot_mode_str(mode));
|
||||||
|
#ifdef CONFIG_ANDROID_AB
|
||||||
/* Get current slot_suffix */
|
/* Get current slot_suffix */
|
||||||
if (get_slot_suffix_if_android_ab(slot_suffix))
|
if (ab_get_slot_suffix(slot_suffix))
|
||||||
return -1;
|
return -1;
|
||||||
|
#endif
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case ANDROID_BOOT_MODE_NORMAL:
|
case ANDROID_BOOT_MODE_NORMAL:
|
||||||
/* In normal mode, we load the kernel from "boot" but append
|
/* 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
|
* and then Android's first-stage init in ramdisk
|
||||||
* will skip recovery and boot normal Android.
|
* 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";
|
mode_cmdline = "androidboot.force_normal_boot=1";
|
||||||
} else {
|
} else {
|
||||||
mode_cmdline = "skip_initramfs";
|
mode_cmdline = "skip_initramfs";
|
||||||
|
|
@ -1193,7 +1017,10 @@ int android_bootloader_boot_flow(struct blk_desc *dev_desc,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
update_root_uuid_if_android_ab();
|
|
||||||
|
#ifdef CONFIG_ANDROID_AB
|
||||||
|
ab_update_root_uuid();
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Set Android root variables. */
|
/* Set Android root variables. */
|
||||||
env_set_ulong("android_root_devnum", dev_desc->devnum);
|
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");
|
printf("Close optee client failed!\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (decrease_tries_if_android_ab())
|
#ifdef CONFIG_ANDROID_AB
|
||||||
|
if (ab_decrease_tries())
|
||||||
printf("Decrease ab tries count fail!\n");
|
printf("Decrease ab tries count fail!\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
android_bootloader_boot_kernel(load_address);
|
android_bootloader_boot_kernel(load_address);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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.*/
|
/* 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 read_misc_virtual_ab_message(struct misc_virtual_ab_message *message);
|
||||||
int write_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
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue