1*83a51ebaSAlex Deymo /* 2*83a51ebaSAlex Deymo * Copyright (C) 2008 The Android Open Source Project 3*83a51ebaSAlex Deymo * 4*83a51ebaSAlex Deymo * SPDX-License-Identifier: BSD-2-Clause 5*83a51ebaSAlex Deymo */ 6*83a51ebaSAlex Deymo 7*83a51ebaSAlex Deymo #include <common.h> 8*83a51ebaSAlex Deymo #include <command.h> 9*83a51ebaSAlex Deymo #include <mapmem.h> 10*83a51ebaSAlex Deymo 11*83a51ebaSAlex Deymo static int do_load_android(cmd_tbl_t *cmdtp, int flag, int argc, 12*83a51ebaSAlex Deymo char * const argv[]) 13*83a51ebaSAlex Deymo { 14*83a51ebaSAlex Deymo int boot_partition; 15*83a51ebaSAlex Deymo unsigned long load_address, blk_cnt, blk_read; 16*83a51ebaSAlex Deymo int ret = CMD_RET_SUCCESS; 17*83a51ebaSAlex Deymo char *addr_arg_endp, *addr_str; 18*83a51ebaSAlex Deymo void *buf; 19*83a51ebaSAlex Deymo struct blk_desc *dev_desc; 20*83a51ebaSAlex Deymo disk_partition_t part_info; 21*83a51ebaSAlex Deymo 22*83a51ebaSAlex Deymo if (argc < 2) 23*83a51ebaSAlex Deymo return CMD_RET_USAGE; 24*83a51ebaSAlex Deymo if (argc > 4) 25*83a51ebaSAlex Deymo return CMD_RET_USAGE; 26*83a51ebaSAlex Deymo 27*83a51ebaSAlex Deymo if (argc >= 4) { 28*83a51ebaSAlex Deymo load_address = simple_strtoul(argv[3], &addr_arg_endp, 16); 29*83a51ebaSAlex Deymo if (addr_arg_endp == argv[3] || *addr_arg_endp != '\0') 30*83a51ebaSAlex Deymo return CMD_RET_USAGE; 31*83a51ebaSAlex Deymo } else { 32*83a51ebaSAlex Deymo addr_str = env_get("loadaddr"); 33*83a51ebaSAlex Deymo if (addr_str != NULL) 34*83a51ebaSAlex Deymo load_address = simple_strtoul(addr_str, NULL, 16); 35*83a51ebaSAlex Deymo else 36*83a51ebaSAlex Deymo load_address = CONFIG_SYS_LOAD_ADDR; 37*83a51ebaSAlex Deymo } 38*83a51ebaSAlex Deymo 39*83a51ebaSAlex Deymo boot_partition = blk_get_device_part_str(argv[1], 40*83a51ebaSAlex Deymo (argc >= 3) ? argv[2] : NULL, 41*83a51ebaSAlex Deymo &dev_desc, &part_info, 1); 42*83a51ebaSAlex Deymo if (boot_partition < 0) 43*83a51ebaSAlex Deymo return CMD_RET_FAILURE; 44*83a51ebaSAlex Deymo 45*83a51ebaSAlex Deymo /* We don't know the size of the Android image before reading the header 46*83a51ebaSAlex Deymo * so we don't limit the size of the mapped memory. */ 47*83a51ebaSAlex Deymo buf = map_sysmem(load_address, 0 /* size */); 48*83a51ebaSAlex Deymo 49*83a51ebaSAlex Deymo /* Read the Android header first and then read the rest. */ 50*83a51ebaSAlex Deymo if (blk_dread(dev_desc, part_info.start, 1, buf) != 1) { 51*83a51ebaSAlex Deymo ret = CMD_RET_FAILURE; 52*83a51ebaSAlex Deymo } 53*83a51ebaSAlex Deymo 54*83a51ebaSAlex Deymo if (ret == CMD_RET_SUCCESS && android_image_check_header(buf) != 0) { 55*83a51ebaSAlex Deymo printf("\n** Invalid Android Image header on %s %d:%d **\n", 56*83a51ebaSAlex Deymo argv[1], dev_desc->devnum, boot_partition); 57*83a51ebaSAlex Deymo ret = CMD_RET_FAILURE; 58*83a51ebaSAlex Deymo } 59*83a51ebaSAlex Deymo if (ret == CMD_RET_SUCCESS) { 60*83a51ebaSAlex Deymo blk_cnt = (android_image_get_end(buf) - (ulong)buf + 61*83a51ebaSAlex Deymo part_info.blksz - 1) / part_info.blksz; 62*83a51ebaSAlex Deymo printf("\nLoading Android Image (%lu blocks) to 0x%lx... ", 63*83a51ebaSAlex Deymo blk_cnt, load_address); 64*83a51ebaSAlex Deymo blk_read = blk_dread(dev_desc, part_info.start, blk_cnt, buf); 65*83a51ebaSAlex Deymo } 66*83a51ebaSAlex Deymo 67*83a51ebaSAlex Deymo unmap_sysmem(buf); 68*83a51ebaSAlex Deymo if (ret != CMD_RET_SUCCESS) 69*83a51ebaSAlex Deymo return ret; 70*83a51ebaSAlex Deymo 71*83a51ebaSAlex Deymo printf("%lu blocks read: %s\n", 72*83a51ebaSAlex Deymo blk_read, (blk_read == blk_cnt) ? "OK" : "ERROR"); 73*83a51ebaSAlex Deymo return (blk_read == blk_cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE; 74*83a51ebaSAlex Deymo } 75*83a51ebaSAlex Deymo 76*83a51ebaSAlex Deymo 77*83a51ebaSAlex Deymo #if defined(CONFIG_CMD_LOAD_ANDROID) 78*83a51ebaSAlex Deymo U_BOOT_CMD( 79*83a51ebaSAlex Deymo load_android, 4, 0, do_load_android, 80*83a51ebaSAlex Deymo "load Android Boot image from storage.", 81*83a51ebaSAlex Deymo "<interface> [<dev[:part]> [<addr>]]\n" 82*83a51ebaSAlex Deymo " - Load a binary Android Boot image from the partition 'part' on\n" 83*83a51ebaSAlex Deymo " device type 'interface' instance 'dev' to address 'addr'." 84*83a51ebaSAlex Deymo ); 85*83a51ebaSAlex Deymo #endif /* CONFIG_CMD_LOAD_ANDROID */ 86