[PATCH] avb: Extend support to non-eMMC interfaces
Alistair Delva
adelva at google.com
Tue Sep 27 00:02:11 CEST 2022
From: Jiyong Park <jiyong at google.com>
Previously Android AVB supported block devices only on eMMC. This change
eliminates the restriction by using the generic block driver model.
The `avb init' command is modified to accept another parameter which
specifies the interface type. e.g., `avb init virtio 0' initializes
avb for the first (0) disk that is accessible via the virtio interface.
[adelva: The "avb init" command is updated directly, as this is
considered a "debug command" that can't be usefully used in u-boot
scripts.]
Signed-off-by: Alistair Delva <adelva at google.com>
Cc: Igor Opaniuk <igor.opaniuk at gmail.com>
Cc: Ram Muthiah <rammuthiah at google.com>
Cc: Jiyong Park <jiyong at google.com>
Cc: Simon Glass <sjg at chromium.org>
---
cmd/avb.c | 16 ++++---
common/Kconfig | 1 -
common/avb_verify.c | 105 +++++++++++++++++++++----------------------
include/avb_verify.h | 31 ++++---------
4 files changed, 69 insertions(+), 84 deletions(-)
diff --git a/cmd/avb.c b/cmd/avb.c
index 783f51b816..8bffe49011 100644
--- a/cmd/avb.c
+++ b/cmd/avb.c
@@ -10,24 +10,25 @@
#include <env.h>
#include <image.h>
#include <malloc.h>
-#include <mmc.h>
#define AVB_BOOTARGS "avb_bootargs"
static struct AvbOps *avb_ops;
int do_avb_init(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
- unsigned long mmc_dev;
+ const char *iface;
+ const char *devnum;
- if (argc != 2)
+ if (argc != 3)
return CMD_RET_USAGE;
- mmc_dev = hextoul(argv[1], NULL);
+ iface = argv[1];
+ devnum = argv[2];
if (avb_ops)
avb_ops_free(avb_ops);
- avb_ops = avb_ops_alloc(mmc_dev);
+ avb_ops = avb_ops_alloc(iface, devnum);
if (avb_ops)
return CMD_RET_SUCCESS;
@@ -419,7 +420,7 @@ int do_avb_write_pvalue(struct cmd_tbl *cmdtp, int flag, int argc,
}
static struct cmd_tbl cmd_avb[] = {
- U_BOOT_CMD_MKENT(init, 2, 0, do_avb_init, "", ""),
+ U_BOOT_CMD_MKENT(init, 3, 0, do_avb_init, "", ""),
U_BOOT_CMD_MKENT(read_rb, 2, 0, do_avb_read_rb, "", ""),
U_BOOT_CMD_MKENT(write_rb, 3, 0, do_avb_write_rb, "", ""),
U_BOOT_CMD_MKENT(is_unlocked, 1, 0, do_avb_is_unlocked, "", ""),
@@ -455,7 +456,8 @@ static int do_avb(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
U_BOOT_CMD(
avb, 29, 0, do_avb,
"Provides commands for testing Android Verified Boot 2.0 functionality",
- "init <dev> - initialize avb2 for <dev>\n"
+ "init <interface> <devnum> - initialize avb2 for the disk <devnum> which\n"
+ " is on the interface <interface>\n"
"avb read_rb <num> - read rollback index at location <num>\n"
"avb write_rb <num> <rb> - write rollback index <rb> to <num>\n"
"avb is_unlocked - returns unlock status of the device\n"
diff --git a/common/Kconfig b/common/Kconfig
index ebee856e56..a66060767c 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -703,7 +703,6 @@ config HASH
config AVB_VERIFY
bool "Build Android Verified Boot operations"
depends on LIBAVB
- depends on MMC
depends on PARTITION_UUIDS
help
This option enables compilation of bootloader-dependent operations,
diff --git a/common/avb_verify.c b/common/avb_verify.c
index 0520a71455..d30bbb5726 100644
--- a/common/avb_verify.c
+++ b/common/avb_verify.c
@@ -253,10 +253,10 @@ char *avb_set_enforce_verity(const char *cmdline)
/**
* ============================================================================
- * IO(mmc) auxiliary functions
+ * IO auxiliary functions
* ============================================================================
*/
-static unsigned long mmc_read_and_flush(struct mmc_part *part,
+static unsigned long blk_read_and_flush(struct avb_part *part,
lbaint_t start,
lbaint_t sectors,
void *buffer)
@@ -291,7 +291,7 @@ static unsigned long mmc_read_and_flush(struct mmc_part *part,
tmp_buf = buffer;
}
- blks = blk_dread(part->mmc_blk,
+ blks = blk_dread(part->blk,
start, sectors, tmp_buf);
/* flush cache after read */
flush_cache((ulong)tmp_buf, sectors * part->info.blksz);
@@ -302,7 +302,7 @@ static unsigned long mmc_read_and_flush(struct mmc_part *part,
return blks;
}
-static unsigned long mmc_write(struct mmc_part *part, lbaint_t start,
+static unsigned long blk_write(struct avb_part *part, lbaint_t start,
lbaint_t sectors, void *buffer)
{
void *tmp_buf;
@@ -330,69 +330,59 @@ static unsigned long mmc_write(struct mmc_part *part, lbaint_t start,
tmp_buf = buffer;
}
- return blk_dwrite(part->mmc_blk,
+ return blk_dwrite(part->blk,
start, sectors, tmp_buf);
}
-static struct mmc_part *get_partition(AvbOps *ops, const char *partition)
+static struct avb_part *get_partition(AvbOps *ops, const char *partition)
{
- int ret;
- u8 dev_num;
- int part_num = 0;
- struct mmc_part *part;
- struct blk_desc *mmc_blk;
+ struct avb_part *part;
+ struct AvbOpsData *data;
+ size_t dev_part_str_len;
+ char *dev_part_str;
- part = malloc(sizeof(struct mmc_part));
+ part = malloc(sizeof(struct avb_part));
if (!part)
return NULL;
- dev_num = get_boot_device(ops);
- part->mmc = find_mmc_device(dev_num);
- if (!part->mmc) {
- printf("No MMC device at slot %x\n", dev_num);
- goto err;
- }
-
- if (mmc_init(part->mmc)) {
- printf("MMC initialization failed\n");
- goto err;
- }
+ if (!ops)
+ return NULL;
- ret = mmc_switch_part(part->mmc, part_num);
- if (ret)
- goto err;
+ data = ops->user_data;
+ if (!data)
+ return NULL;
- mmc_blk = mmc_get_blk_desc(part->mmc);
- if (!mmc_blk) {
- printf("Error - failed to obtain block descriptor\n");
- goto err;
+ // format is "<devnum>#<partition>\0"
+ dev_part_str_len = strlen(data->devnum) + 1 + strlen(partition) + 1;
+ dev_part_str = (char *)malloc(dev_part_str_len);
+ if (!dev_part_str) {
+ free(part);
+ return NULL;
}
- ret = part_get_info_by_name(mmc_blk, partition, &part->info);
- if (ret < 0) {
- printf("Can't find partition '%s'\n", partition);
- goto err;
+ snprintf(dev_part_str, dev_part_str_len, "%s#%s", data->devnum,
+ partition);
+ if (part_get_info_by_dev_and_name_or_num(data->iface, dev_part_str,
+ &part->blk, &part->info,
+ false) < 0) {
+ free(part);
+ part = NULL;
}
- part->dev_num = dev_num;
- part->mmc_blk = mmc_blk;
-
+ free(dev_part_str);
return part;
-err:
- free(part);
- return NULL;
}
-static AvbIOResult mmc_byte_io(AvbOps *ops,
+static AvbIOResult blk_byte_io(AvbOps *ops,
const char *partition,
s64 offset,
size_t num_bytes,
void *buffer,
size_t *out_num_read,
- enum mmc_io_type io_type)
+ enum io_type io_type)
{
ulong ret;
- struct mmc_part *part;
+ struct avb_part *part;
u64 start_offset, start_sector, sectors, residue;
u8 *tmp_buf;
size_t io_cnt = 0;
@@ -425,7 +415,7 @@ static AvbIOResult mmc_byte_io(AvbOps *ops,
}
if (io_type == IO_READ) {
- ret = mmc_read_and_flush(part,
+ ret = blk_read_and_flush(part,
part->info.start +
start_sector,
1, tmp_buf);
@@ -442,7 +432,7 @@ static AvbIOResult mmc_byte_io(AvbOps *ops,
tmp_buf += (start_offset % part->info.blksz);
memcpy(buffer, (void *)tmp_buf, residue);
} else {
- ret = mmc_read_and_flush(part,
+ ret = blk_read_and_flush(part,
part->info.start +
start_sector,
1, tmp_buf);
@@ -456,7 +446,7 @@ static AvbIOResult mmc_byte_io(AvbOps *ops,
start_offset % part->info.blksz,
buffer, residue);
- ret = mmc_write(part, part->info.start +
+ ret = blk_write(part, part->info.start +
start_sector, 1, tmp_buf);
if (ret != 1) {
printf("%s: write error (%ld, %lld)\n",
@@ -474,12 +464,12 @@ static AvbIOResult mmc_byte_io(AvbOps *ops,
if (sectors) {
if (io_type == IO_READ) {
- ret = mmc_read_and_flush(part,
+ ret = blk_read_and_flush(part,
part->info.start +
start_sector,
sectors, buffer);
} else {
- ret = mmc_write(part,
+ ret = blk_write(part,
part->info.start +
start_sector,
sectors, buffer);
@@ -535,7 +525,7 @@ static AvbIOResult read_from_partition(AvbOps *ops,
void *buffer,
size_t *out_num_read)
{
- return mmc_byte_io(ops, partition_name, offset_from_partition,
+ return blk_byte_io(ops, partition_name, offset_from_partition,
num_bytes, buffer, out_num_read, IO_READ);
}
@@ -562,7 +552,7 @@ static AvbIOResult write_to_partition(AvbOps *ops,
size_t num_bytes,
const void *buffer)
{
- return mmc_byte_io(ops, partition_name, offset_from_partition,
+ return blk_byte_io(ops, partition_name, offset_from_partition,
num_bytes, (void *)buffer, NULL, IO_WRITE);
}
@@ -803,7 +793,7 @@ static AvbIOResult get_unique_guid_for_partition(AvbOps *ops,
char *guid_buf,
size_t guid_buf_size)
{
- struct mmc_part *part;
+ struct avb_part *part;
size_t uuid_size;
part = get_partition(ops, partition);
@@ -837,7 +827,7 @@ static AvbIOResult get_size_of_partition(AvbOps *ops,
const char *partition,
u64 *out_size_num_bytes)
{
- struct mmc_part *part;
+ struct avb_part *part;
if (!out_size_num_bytes)
return AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE;
@@ -976,7 +966,7 @@ free_name:
* AVB2.0 AvbOps alloc/initialisation/free
* ============================================================================
*/
-AvbOps *avb_ops_alloc(int boot_device)
+AvbOps *avb_ops_alloc(const char *iface, const char *devnum)
{
struct AvbOpsData *ops_data;
@@ -999,7 +989,8 @@ AvbOps *avb_ops_alloc(int boot_device)
ops_data->ops.read_persistent_value = read_persistent_value;
#endif
ops_data->ops.get_size_of_partition = get_size_of_partition;
- ops_data->mmc_dev = boot_device;
+ ops_data->iface = avb_strdup(iface);
+ ops_data->devnum = avb_strdup(devnum);
return &ops_data->ops;
}
@@ -1018,6 +1009,12 @@ void avb_ops_free(AvbOps *ops)
if (ops_data->tee)
tee_close_session(ops_data->tee, ops_data->session);
#endif
+ if (ops_data->iface)
+ avb_free((void*)ops_data->iface);
+
+ if (ops_data->devnum)
+ avb_free((void*)ops_data->devnum);
+
avb_free(ops_data);
}
}
diff --git a/include/avb_verify.h b/include/avb_verify.h
index 1e787ba666..732839f74b 100644
--- a/include/avb_verify.h
+++ b/include/avb_verify.h
@@ -9,8 +9,9 @@
#define _AVB_VERIFY_H
#include <../lib/libavb/libavb.h>
+#include <blk.h>
#include <mapmem.h>
-#include <mmc.h>
+#include <part.h>
#define AVB_MAX_ARGS 1024
#define VERITY_TABLE_OPT_RESTART "restart_on_corruption"
@@ -26,7 +27,8 @@ enum avb_boot_state {
struct AvbOpsData {
struct AvbOps ops;
- int mmc_dev;
+ const char *iface;
+ const char *devnum;
enum avb_boot_state boot_state;
#ifdef CONFIG_OPTEE_TA_AVB
struct udevice *tee;
@@ -34,19 +36,17 @@ struct AvbOpsData {
#endif
};
-struct mmc_part {
- int dev_num;
- struct mmc *mmc;
- struct blk_desc *mmc_blk;
+struct avb_part {
+ struct blk_desc *blk;
struct disk_partition info;
};
-enum mmc_io_type {
+enum io_type {
IO_READ,
IO_WRITE
};
-AvbOps *avb_ops_alloc(int boot_device);
+AvbOps *avb_ops_alloc(const char *iface, const char *devnum);
void avb_ops_free(AvbOps *ops);
char *avb_set_state(AvbOps *ops, enum avb_boot_state boot_state);
@@ -60,7 +60,7 @@ char *append_cmd_line(char *cmdline_orig, char *cmdline_new);
* I/O helper inline functions
* ============================================================================
*/
-static inline uint64_t calc_offset(struct mmc_part *part, int64_t offset)
+static inline uint64_t calc_offset(struct avb_part *part, int64_t offset)
{
u64 part_size = part->info.size * part->info.blksz;
@@ -85,17 +85,4 @@ static inline bool is_buf_unaligned(void *buffer)
return (bool)((uintptr_t)buffer % ALLOWED_BUF_ALIGN);
}
-static inline int get_boot_device(AvbOps *ops)
-{
- struct AvbOpsData *data;
-
- if (ops) {
- data = ops->user_data;
- if (data)
- return data->mmc_dev;
- }
-
- return -1;
-}
-
#endif /* _AVB_VERIFY_H */
--
2.30.2
More information about the U-Boot
mailing list