From 76e2a5a6c67043440fb0ea4942cde9b08e260a9d Mon Sep 17 00:00:00 2001 From: Alex Deymo Date: Mon, 9 Jan 2017 20:36:34 -0800 Subject: [PATCH] Move Android Image loading logic to image-android.c This patch moves the Android Image loading logic from the load_android command to a new android_load_image() function in image-android.c so it can be re-used from other commands. Bug: 32707546 Test: Booted the rpi3 with this patch. Signed-off-by: Alex Deymo Change-Id: I12d206141ead1b94ebbcc90ee05512a276c7595a --- cmd/load_android.c | 47 ++++++++------------------------------ common/image-android.c | 51 ++++++++++++++++++++++++++++++++++++++++++ include/image.h | 19 ++++++++++++++++ 3 files changed, 79 insertions(+), 38 deletions(-) diff --git a/cmd/load_android.c b/cmd/load_android.c index e6c5930837..e2ca4fe6ca 100644 --- a/cmd/load_android.c +++ b/cmd/load_android.c @@ -1,21 +1,18 @@ /* - * Copyright (C) 2008 The Android Open Source Project + * Copyright (C) 2016 The Android Open Source Project * * SPDX-License-Identifier: BSD-2-Clause */ #include #include -#include static int do_load_android(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int boot_partition; - unsigned long load_address, blk_cnt, blk_read; - int ret = CMD_RET_SUCCESS; + unsigned long load_address; char *addr_arg_endp, *addr_str; - void *buf; struct blk_desc *dev_desc; disk_partition_t part_info; @@ -37,44 +34,19 @@ static int do_load_android(cmd_tbl_t *cmdtp, int flag, int argc, } boot_partition = blk_get_device_part_str(argv[1], - (argc >= 3) ? argv[2] : NULL, - &dev_desc, &part_info, 1); + (argc >= 3) ? argv[2] : NULL, + &dev_desc, &part_info, 1); if (boot_partition < 0) return CMD_RET_FAILURE; - /* We don't know the size of the Android image before reading the header - * so we don't limit the size of the mapped memory. */ - buf = map_sysmem(load_address, 0 /* size */); - - /* Read the Android header first and then read the rest. */ - if (blk_dread(dev_desc, part_info.start, 1, buf) != 1) { - ret = CMD_RET_FAILURE; + if (android_image_load(dev_desc, &part_info, load_address, -1UL) < 0) { + printf("Error loading Android Image from %s %d:%d to 0x%lx.\n", + argv[1], dev_desc->devnum, boot_partition, load_address); + return CMD_RET_FAILURE; } - - if (ret == CMD_RET_SUCCESS && android_image_check_header(buf) != 0) { - printf("\n** Invalid Android Image header on %s %d:%d **\n", - argv[1], dev_desc->devnum, boot_partition); - ret = CMD_RET_FAILURE; - } - if (ret == CMD_RET_SUCCESS) { - blk_cnt = (android_image_get_end(buf) - (ulong)buf + - part_info.blksz - 1) / part_info.blksz; - printf("\nLoading Android Image (%lu blocks) to 0x%lx... ", - blk_cnt, load_address); - blk_read = blk_dread(dev_desc, part_info.start, blk_cnt, buf); - } - - unmap_sysmem(buf); - if (ret != CMD_RET_SUCCESS) - return ret; - - printf("%lu blocks read: %s\n", - blk_read, (blk_read == blk_cnt) ? "OK" : "ERROR"); - return (blk_read == blk_cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE; + return CMD_RET_SUCCESS; } - -#if defined(CONFIG_CMD_LOAD_ANDROID) U_BOOT_CMD( load_android, 4, 0, do_load_android, "load Android Boot image from storage.", @@ -82,4 +54,3 @@ U_BOOT_CMD( " - Load a binary Android Boot image from the partition 'part' on\n" " device type 'interface' instance 'dev' to address 'addr'." ); -#endif /* CONFIG_CMD_LOAD_ANDROID */ diff --git a/common/image-android.c b/common/image-android.c index e74d0aafca..e6976d0e63 100644 --- a/common/image-android.c +++ b/common/image-android.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #define ANDROID_IMAGE_DEFAULT_KERNEL_ADDR 0x10008000 @@ -146,6 +147,56 @@ int android_image_get_ramdisk(const struct andr_img_hdr *hdr, return 0; } +long android_image_load(struct blk_desc *dev_desc, + const disk_partition_t *part_info, + unsigned long load_address, + unsigned long max_size) { + void *buf; + long blk_cnt, blk_read = 0; + + if (max_size < part_info->blksz) + return -1; + + /* We don't know the size of the Android image before reading the header + * so we don't limit the size of the mapped memory. + */ + buf = map_sysmem(load_address, 0 /* size */); + + /* Read the Android header first and then read the rest. */ + if (blk_dread(dev_desc, part_info->start, 1, buf) != 1) + blk_read = -1; + + if (!blk_read && android_image_check_header(buf) != 0) { + printf("** Invalid Android Image header **\n"); + blk_read = -1; + } + if (!blk_read) { + blk_cnt = (android_image_get_end(buf) - (ulong)buf + + part_info->blksz - 1) / part_info->blksz; + if (blk_cnt * part_info->blksz > max_size) { + debug("Android Image too big (%lu bytes, max %lu)\n", + android_image_get_end(buf) - (ulong)buf, + max_size); + blk_read = -1; + } else { + debug("Loading Android Image (%lu blocks) to 0x%lx... ", + blk_cnt, load_address); + blk_read = blk_dread(dev_desc, part_info->start, + blk_cnt, buf); + } + } + + unmap_sysmem(buf); + if (blk_read < 0) + return blk_read; + + debug("%lu blocks read: %s\n", + blk_read, (blk_read == blk_cnt) ? "OK" : "ERROR"); + if (blk_read != blk_cnt) + return -1; + return blk_read; +} + #if !defined(CONFIG_SPL_BUILD) /** * android_print_contents - prints out the contents of the Android format image diff --git a/include/image.h b/include/image.h index 10ff094709..300a72a4b5 100644 --- a/include/image.h +++ b/include/image.h @@ -1238,6 +1238,25 @@ ulong android_image_get_end(const struct andr_img_hdr *hdr); ulong android_image_get_kload(const struct andr_img_hdr *hdr); void android_print_contents(const struct andr_img_hdr *hdr); +/** android_image_load - Load an Android Image from storage. + * + * Load an Android Image based on the header size in the storage. Return the + * number of bytes read from storage, which could be bigger than the actual + * Android Image as described in the header size. In case of error reading the + * image or if the image size needed to be read from disk is bigger than the + * the passed |max_size| a negative number is returned. + * + * @dev_desc: The device where to read the image from + * @part_info: The partition in |dev_desc| where to read the image from + * @load_address: The address where the image will be loaded + * @max_size: The maximum loaded size, in bytes + * @return the number of bytes read or a negative number in case of error. + */ +long android_image_load(struct blk_desc *dev_desc, + const disk_partition_t *part_info, + unsigned long load_address, + unsigned long max_size); + #endif /* CONFIG_ANDROID_BOOT_IMAGE */ /**