From 83a51ebaaad9be5e90ca18534919101787559789 Mon Sep 17 00:00:00 2001 From: Alex Deymo Date: Mon, 3 Oct 2016 17:38:26 -0700 Subject: [PATCH] Add 'load_android' command to load Android images. Android kernel images include a header that specifies addresses and kernel size. This patch adds a command to load these images from storage without specifying the size or address of them, and parsing them from the header instead. Bug: 31636643 Change-Id: I84a9cf82cff78ce2299b1981c4f6f9a5720e4d0d --- cmd/Kconfig | 9 +++++ cmd/Makefile | 1 + cmd/load_android.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+) create mode 100644 cmd/load_android.c diff --git a/cmd/Kconfig b/cmd/Kconfig index 87b56e2c92..833d98d8c6 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -743,6 +743,15 @@ config CMD_LOADS help Load an S-Record file over serial line +config CMD_LOAD_ANDROID + bool "load_android" + default n + depends on ANDROID_BOOT_IMAGE + help + Load an Android Boot image from storage. The Android Boot images + define the size and kernel address on the header, which are used by + this command. + config CMD_MMC bool "mmc" help diff --git a/cmd/Makefile b/cmd/Makefile index 868113eab2..f1c412160d 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -76,6 +76,7 @@ obj-$(CONFIG_LED_STATUS_CMD) += legacy_led.o obj-$(CONFIG_CMD_LED) += led.o obj-$(CONFIG_CMD_LICENSE) += license.o obj-y += load.o +obj-$(CONFIG_CMD_LOAD_ANDROID) += load_android.o obj-$(CONFIG_LOGBUFFER) += log.o obj-$(CONFIG_ID_EEPROM) += mac.o obj-$(CONFIG_CMD_MD5SUM) += md5sum.o diff --git a/cmd/load_android.c b/cmd/load_android.c new file mode 100644 index 0000000000..e6c5930837 --- /dev/null +++ b/cmd/load_android.c @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2008 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; + char *addr_arg_endp, *addr_str; + void *buf; + struct blk_desc *dev_desc; + disk_partition_t part_info; + + if (argc < 2) + return CMD_RET_USAGE; + if (argc > 4) + return CMD_RET_USAGE; + + if (argc >= 4) { + load_address = simple_strtoul(argv[3], &addr_arg_endp, 16); + if (addr_arg_endp == argv[3] || *addr_arg_endp != '\0') + return CMD_RET_USAGE; + } else { + addr_str = env_get("loadaddr"); + if (addr_str != NULL) + load_address = simple_strtoul(addr_str, NULL, 16); + else + load_address = CONFIG_SYS_LOAD_ADDR; + } + + boot_partition = blk_get_device_part_str(argv[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 (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; +} + + +#if defined(CONFIG_CMD_LOAD_ANDROID) +U_BOOT_CMD( + load_android, 4, 0, do_load_android, + "load Android Boot image from storage.", + " [ []]\n" + " - 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 */