xref: /rk3399_rockchip-uboot/cmd/load_android.c (revision 83a51ebaaad9be5e90ca18534919101787559789)
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