diff options
author | Julien Masson <jmasson@baylibre.com> | 2024-11-21 11:59:55 +0100 |
---|---|---|
committer | Mattijs Korpershoek <mkorpershoek@baylibre.com> | 2024-11-26 10:04:40 +0100 |
commit | abadcda24b100b8eb0f138085cca6595518cec85 (patch) | |
tree | 5222694a184a6da712456401fba1c3913f18ae4e /boot/bootmeth_android.c | |
parent | 126254ab97691a93902d8fe02fdff0a783921c39 (diff) |
bootstd: android: don't read whole partition sizes
The current implementation is reading the whole partition for boot and
vendor_boot image which can be long following the size of the
partition or the time to read blocks (driver/SoC specific).
For example with mediatek mt8365 EVK board, we have a 64MiB boot
partition and the boot image flashed in this partition is only 42MiB.
It takes ~8-9 secs to read the boot partition.
Instead we can retrieved the boot image and vendor boot image size
with these new functions:
- android_image_get_bootimg_size
- android_image_get_vendor_bootimg_size
Use these information and read only the necessary.
By doing this with mt8365 EVK board, we read boot image in ~5 secs.
Signed-off-by: Julien Masson <jmasson@baylibre.com>
Reviewed-by: Mattijs Korpershoek <mkorpershoek@baylibre.com>
Link: https://lore.kernel.org/r/20241121-bootmeth-android-part-sizes-v1-1-25760bbd0f08@baylibre.com
Signed-off-by: Mattijs Korpershoek <mkorpershoek@baylibre.com>
Diffstat (limited to 'boot/bootmeth_android.c')
-rw-r--r-- | boot/bootmeth_android.c | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/boot/bootmeth_android.c b/boot/bootmeth_android.c index 2aac32331d3..3a5144aaa3b 100644 --- a/boot/bootmeth_android.c +++ b/boot/bootmeth_android.c @@ -45,6 +45,8 @@ struct android_priv { enum android_boot_mode boot_mode; char *slot; u32 header_version; + u32 boot_img_size; + u32 vendor_boot_img_size; }; static int android_check(struct udevice *dev, struct bootflow_iter *iter) @@ -98,7 +100,13 @@ static int scan_boot_part(struct udevice *blk, struct android_priv *priv) return log_msg_ret("header", -ENOENT); } + if (!android_image_get_bootimg_size(buf, &priv->boot_img_size)) { + free(buf); + return log_msg_ret("get bootimg size", -EINVAL); + } + priv->header_version = ((struct andr_boot_img_hdr_v0 *)buf)->header_version; + free(buf); return 0; @@ -138,6 +146,12 @@ static int scan_vendor_boot_part(struct udevice *blk, struct android_priv *priv) free(buf); return log_msg_ret("header", -ENOENT); } + + if (!android_image_get_vendor_bootimg_size(buf, &priv->vendor_boot_img_size)) { + free(buf); + return log_msg_ret("get vendor bootimg size", -EINVAL); + } + free(buf); return 0; @@ -330,15 +344,17 @@ static int android_read_file(struct udevice *dev, struct bootflow *bflow, * @blk: Block device to read * @name: Partition name to read * @slot: Nul-terminated slot suffixed to partition name ("a\0" or "b\0") + * @image_size: Image size in bytes used when reading the partition * @addr: Address where the partition content is loaded into * Return: 0 if OK, negative errno on failure. */ static int read_slotted_partition(struct blk_desc *desc, const char *const name, - const char slot[2], ulong addr) + const char slot[2], ulong image_size, ulong addr) { struct disk_partition partition; char partname[PART_NAME_LEN]; size_t partname_len; + ulong num_blks = DIV_ROUND_UP(image_size, desc->blksz); int ret; u32 n; @@ -364,8 +380,8 @@ static int read_slotted_partition(struct blk_desc *desc, const char *const name, if (ret < 0) return log_msg_ret("part", ret); - n = blk_dread(desc, partition.start, partition.size, map_sysmem(addr, 0)); - if (n < partition.size) + n = blk_dread(desc, partition.start, num_blks, map_sysmem(addr, 0)); + if (n < num_blks) return log_msg_ret("part read", -EIO); return 0; @@ -498,12 +514,14 @@ static int boot_android_normal(struct bootflow *bflow) if (ret < 0) return log_msg_ret("read slot", ret); - ret = read_slotted_partition(desc, "boot", priv->slot, loadaddr); + ret = read_slotted_partition(desc, "boot", priv->slot, priv->boot_img_size, + loadaddr); if (ret < 0) return log_msg_ret("read boot", ret); if (priv->header_version >= 3) { - ret = read_slotted_partition(desc, "vendor_boot", priv->slot, vloadaddr); + ret = read_slotted_partition(desc, "vendor_boot", priv->slot, + priv->vendor_boot_img_size, vloadaddr); if (ret < 0) return log_msg_ret("read vendor_boot", ret); set_avendor_bootimg_addr(vloadaddr); |