blob: 44de00fb9c974b2e7aee4b3f1490d3adfd34b731 [file] [log] [blame]
Sam Protsenko035502e2020-01-24 17:53:42 +02001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * (C) Copyright 2020
4 * Sam Protsenko <joe.skb7@gmail.com>
5 */
6
7#include <android_image.h>
Simon Glassed38aef2020-05-10 11:40:03 -06008#include <command.h>
Tom Rini22856382025-05-14 16:46:03 -06009#include <env.h>
Simon Glass2dc9c342020-05-10 11:40:01 -060010#include <image.h>
Sam Protsenko035502e2020-01-24 17:53:42 +020011#include <mapmem.h>
12
13#define abootimg_addr() \
14 (_abootimg_addr == -1 ? image_load_addr : _abootimg_addr)
15
16/* Please use abootimg_addr() macro to obtain the boot image address */
17static ulong _abootimg_addr = -1;
Roman Stratiienko826e0be2024-05-23 07:06:07 +000018static ulong _ainit_bootimg_addr = -1;
Safae Ouajih91da3632023-02-06 00:50:04 +010019static ulong _avendor_bootimg_addr = -1;
Sam Protsenko035502e2020-01-24 17:53:42 +020020
Safae Ouajih51c981b2023-02-06 00:50:17 +010021ulong get_abootimg_addr(void)
22{
23 return (_abootimg_addr == -1 ? image_load_addr : _abootimg_addr);
24}
25
Mattijs Korpershoekb47db022024-07-10 10:40:04 +020026void set_abootimg_addr(ulong addr)
27{
28 _abootimg_addr = addr;
29}
30
Roman Stratiienko826e0be2024-05-23 07:06:07 +000031ulong get_ainit_bootimg_addr(void)
32{
33 return _ainit_bootimg_addr;
34}
35
Safae Ouajih51c981b2023-02-06 00:50:17 +010036ulong get_avendor_bootimg_addr(void)
37{
38 return _avendor_bootimg_addr;
39}
40
Mattijs Korpershoekb47db022024-07-10 10:40:04 +020041void set_avendor_bootimg_addr(ulong addr)
42{
43 _avendor_bootimg_addr = addr;
44}
45
Simon Glassed38aef2020-05-10 11:40:03 -060046static int abootimg_get_ver(int argc, char *const argv[])
Sam Protsenko035502e2020-01-24 17:53:42 +020047{
Safae Ouajih8656e382023-02-06 00:50:03 +010048 const struct andr_boot_img_hdr_v0 *hdr;
Sam Protsenko035502e2020-01-24 17:53:42 +020049 int res = CMD_RET_SUCCESS;
50
51 if (argc > 1)
52 return CMD_RET_USAGE;
53
54 hdr = map_sysmem(abootimg_addr(), sizeof(*hdr));
Safae Ouajih88ad0c12023-02-06 00:50:05 +010055 if (!is_android_boot_image_header(hdr)) {
Sam Protsenko035502e2020-01-24 17:53:42 +020056 printf("Error: Boot Image header is incorrect\n");
57 res = CMD_RET_FAILURE;
58 goto exit;
59 }
60
61 if (argc == 0)
62 printf("%u\n", hdr->header_version);
63 else
64 env_set_ulong(argv[0], hdr->header_version);
65
66exit:
67 unmap_sysmem(hdr);
68 return res;
69}
70
Simon Glassed38aef2020-05-10 11:40:03 -060071static int abootimg_get_recovery_dtbo(int argc, char *const argv[])
Sam Protsenko035502e2020-01-24 17:53:42 +020072{
73 ulong addr;
74 u32 size;
75
76 if (argc > 2)
77 return CMD_RET_USAGE;
78
79 if (!android_image_get_dtbo(abootimg_addr(), &addr, &size))
80 return CMD_RET_FAILURE;
81
82 if (argc == 0) {
83 printf("%lx\n", addr);
84 } else {
85 env_set_hex(argv[0], addr);
86 if (argc == 2)
87 env_set_hex(argv[1], size);
88 }
89
90 return CMD_RET_SUCCESS;
91}
92
Simon Glassed38aef2020-05-10 11:40:03 -060093static int abootimg_get_dtb_load_addr(int argc, char *const argv[])
Sam Protsenko035502e2020-01-24 17:53:42 +020094{
Sam Protsenko035502e2020-01-24 17:53:42 +020095 if (argc > 1)
96 return CMD_RET_USAGE;
Safae Ouajihbced1042023-02-06 00:50:08 +010097 struct andr_image_data img_data = {0};
98 const struct andr_boot_img_hdr_v0 *hdr;
Safae Ouajih51c981b2023-02-06 00:50:17 +010099 const struct andr_vnd_boot_img_hdr *vhdr;
Sam Protsenko035502e2020-01-24 17:53:42 +0200100
101 hdr = map_sysmem(abootimg_addr(), sizeof(*hdr));
Safae Ouajih51c981b2023-02-06 00:50:17 +0100102 if (get_avendor_bootimg_addr() != -1)
103 vhdr = map_sysmem(get_avendor_bootimg_addr(), sizeof(*vhdr));
104
105 if (!android_image_get_data(hdr, vhdr, &img_data)) {
106 if (get_avendor_bootimg_addr() != -1)
107 unmap_sysmem(vhdr);
Safae Ouajihbced1042023-02-06 00:50:08 +0100108 unmap_sysmem(hdr);
109 return CMD_RET_FAILURE;
Sam Protsenko035502e2020-01-24 17:53:42 +0200110 }
Safae Ouajih51c981b2023-02-06 00:50:17 +0100111
112 if (get_avendor_bootimg_addr() != -1)
113 unmap_sysmem(vhdr);
Safae Ouajihbced1042023-02-06 00:50:08 +0100114 unmap_sysmem(hdr);
Sam Protsenko035502e2020-01-24 17:53:42 +0200115
Safae Ouajihbced1042023-02-06 00:50:08 +0100116 if (img_data.header_version < 2) {
Sam Protsenko035502e2020-01-24 17:53:42 +0200117 printf("Error: header_version must be >= 2 for this\n");
Safae Ouajihbced1042023-02-06 00:50:08 +0100118 return CMD_RET_FAILURE;
Sam Protsenko035502e2020-01-24 17:53:42 +0200119 }
120
Safae Ouajihbced1042023-02-06 00:50:08 +0100121 if (!img_data.dtb_load_addr) {
122 printf("Error: failed to read dtb_load_addr\n");
123 return CMD_RET_FAILURE;
124 }
125
Sam Protsenko035502e2020-01-24 17:53:42 +0200126 if (argc == 0)
Safae Ouajihbced1042023-02-06 00:50:08 +0100127 printf("%lx\n", (ulong)img_data.dtb_load_addr);
Sam Protsenko035502e2020-01-24 17:53:42 +0200128 else
Safae Ouajihbced1042023-02-06 00:50:08 +0100129 env_set_hex(argv[0], (ulong)img_data.dtb_load_addr);
Sam Protsenko035502e2020-01-24 17:53:42 +0200130
Safae Ouajihbced1042023-02-06 00:50:08 +0100131 return CMD_RET_SUCCESS;
Sam Protsenko035502e2020-01-24 17:53:42 +0200132}
133
Simon Glassed38aef2020-05-10 11:40:03 -0600134static int abootimg_get_dtb_by_index(int argc, char *const argv[])
Sam Protsenko035502e2020-01-24 17:53:42 +0200135{
136 const char *index_str;
137 u32 num;
138 char *endp;
139 ulong addr;
140 u32 size;
141
142 if (argc < 1 || argc > 3)
143 return CMD_RET_USAGE;
144
145 index_str = argv[0] + strlen("--index=");
146 if (index_str[0] == '\0') {
147 printf("Error: Wrong index num\n");
148 return CMD_RET_FAILURE;
149 }
150
151 num = simple_strtoul(index_str, &endp, 0);
152 if (*endp != '\0') {
153 printf("Error: Wrong index num\n");
154 return CMD_RET_FAILURE;
155 }
156
Safae Ouajih51c981b2023-02-06 00:50:17 +0100157 if (!android_image_get_dtb_by_index(abootimg_addr(),
158 get_avendor_bootimg_addr(), num,
Sam Protsenko035502e2020-01-24 17:53:42 +0200159 &addr, &size)) {
160 return CMD_RET_FAILURE;
161 }
162
163 if (argc == 1) {
164 printf("%lx\n", addr);
165 } else {
166 if (env_set_hex(argv[1], addr)) {
167 printf("Error: Can't set [addr_var]\n");
168 return CMD_RET_FAILURE;
169 }
170
171 if (argc == 3) {
172 if (env_set_hex(argv[2], size)) {
173 printf("Error: Can't set [size_var]\n");
174 return CMD_RET_FAILURE;
175 }
176 }
177 }
178
179 return CMD_RET_SUCCESS;
180}
181
Simon Glassed38aef2020-05-10 11:40:03 -0600182static int abootimg_get_dtb(int argc, char *const argv[])
Sam Protsenko035502e2020-01-24 17:53:42 +0200183{
184 if (argc < 1)
185 return CMD_RET_USAGE;
186
187 if (strstr(argv[0], "--index="))
188 return abootimg_get_dtb_by_index(argc, argv);
189
190 return CMD_RET_USAGE;
191}
192
Simon Glassed38aef2020-05-10 11:40:03 -0600193static int do_abootimg_addr(struct cmd_tbl *cmdtp, int flag, int argc,
194 char *const argv[])
Sam Protsenko035502e2020-01-24 17:53:42 +0200195{
196 char *endp;
197 ulong img_addr;
198
Roman Stratiienko826e0be2024-05-23 07:06:07 +0000199 if (argc < 2 || argc > 4)
Sam Protsenko035502e2020-01-24 17:53:42 +0200200 return CMD_RET_USAGE;
201
Simon Glass3ff49ec2021-07-24 09:03:29 -0600202 img_addr = hextoul(argv[1], &endp);
Sam Protsenko035502e2020-01-24 17:53:42 +0200203 if (*endp != '\0') {
204 printf("Error: Wrong image address\n");
205 return CMD_RET_FAILURE;
206 }
207
208 _abootimg_addr = img_addr;
Safae Ouajih91da3632023-02-06 00:50:04 +0100209
Roman Stratiienko826e0be2024-05-23 07:06:07 +0000210 if (argc > 2) {
Safae Ouajih91da3632023-02-06 00:50:04 +0100211 img_addr = simple_strtoul(argv[2], &endp, 16);
212 if (*endp != '\0') {
Roman Stratiienko826e0be2024-05-23 07:06:07 +0000213 printf("Error: Wrong vendor_boot image address\n");
Safae Ouajih91da3632023-02-06 00:50:04 +0100214 return CMD_RET_FAILURE;
215 }
216
217 _avendor_bootimg_addr = img_addr;
218 }
219
Roman Stratiienko826e0be2024-05-23 07:06:07 +0000220 if (argc == 4) {
221 img_addr = simple_strtoul(argv[3], &endp, 16);
222 if (*endp != '\0') {
223 printf("Error: Wrong init_boot image address\n");
224 return CMD_RET_FAILURE;
225 }
226
227 _ainit_bootimg_addr = img_addr;
228 }
229
Sam Protsenko035502e2020-01-24 17:53:42 +0200230 return CMD_RET_SUCCESS;
231}
232
Simon Glassed38aef2020-05-10 11:40:03 -0600233static int do_abootimg_get(struct cmd_tbl *cmdtp, int flag, int argc,
234 char *const argv[])
Sam Protsenko035502e2020-01-24 17:53:42 +0200235{
236 const char *param;
237
238 if (argc < 2)
239 return CMD_RET_USAGE;
240
241 param = argv[1];
242 argc -= 2;
243 argv += 2;
244 if (!strcmp(param, "ver"))
245 return abootimg_get_ver(argc, argv);
246 else if (!strcmp(param, "recovery_dtbo"))
247 return abootimg_get_recovery_dtbo(argc, argv);
248 else if (!strcmp(param, "dtb_load_addr"))
249 return abootimg_get_dtb_load_addr(argc, argv);
250 else if (!strcmp(param, "dtb"))
251 return abootimg_get_dtb(argc, argv);
252
253 return CMD_RET_USAGE;
254}
255
Simon Glassed38aef2020-05-10 11:40:03 -0600256static int do_abootimg_dump(struct cmd_tbl *cmdtp, int flag, int argc,
257 char *const argv[])
Sam Protsenko035502e2020-01-24 17:53:42 +0200258{
259 if (argc != 2)
260 return CMD_RET_USAGE;
261
262 if (!strcmp(argv[1], "dtb")) {
263 if (android_image_print_dtb_contents(abootimg_addr()))
264 return CMD_RET_FAILURE;
265 } else {
266 return CMD_RET_USAGE;
267 }
268
269 return CMD_RET_SUCCESS;
270}
271
Simon Glassed38aef2020-05-10 11:40:03 -0600272static struct cmd_tbl cmd_abootimg_sub[] = {
Roman Stratiienko826e0be2024-05-23 07:06:07 +0000273 U_BOOT_CMD_MKENT(addr, 4, 1, do_abootimg_addr, "", ""),
Sam Protsenko035502e2020-01-24 17:53:42 +0200274 U_BOOT_CMD_MKENT(dump, 2, 1, do_abootimg_dump, "", ""),
275 U_BOOT_CMD_MKENT(get, 5, 1, do_abootimg_get, "", ""),
276};
277
Simon Glassed38aef2020-05-10 11:40:03 -0600278static int do_abootimg(struct cmd_tbl *cmdtp, int flag, int argc,
279 char *const argv[])
Sam Protsenko035502e2020-01-24 17:53:42 +0200280{
Simon Glassed38aef2020-05-10 11:40:03 -0600281 struct cmd_tbl *cp;
Sam Protsenko035502e2020-01-24 17:53:42 +0200282
283 cp = find_cmd_tbl(argv[1], cmd_abootimg_sub,
284 ARRAY_SIZE(cmd_abootimg_sub));
285
286 /* Strip off leading 'abootimg' command argument */
287 argc--;
288 argv++;
289
290 if (!cp || argc > cp->maxargs)
291 return CMD_RET_USAGE;
292 if (flag == CMD_FLAG_REPEAT && !cmd_is_repeatable(cp))
293 return CMD_RET_SUCCESS;
294
295 return cp->cmd(cmdtp, flag, argc, argv);
296}
297
298U_BOOT_CMD(
299 abootimg, CONFIG_SYS_MAXARGS, 0, do_abootimg,
300 "manipulate Android Boot Image",
Roman Stratiienko826e0be2024-05-23 07:06:07 +0000301 "addr <boot_img_addr> [<vendor_boot_img_addr> [<init_boot_img_addr>]]\n"
Sam Protsenko035502e2020-01-24 17:53:42 +0200302 " - set the address in RAM where boot image is located\n"
303 " ($loadaddr is used by default)\n"
304 "abootimg dump dtb\n"
305 " - print info for all DT blobs in DTB area\n"
306 "abootimg get ver [varname]\n"
307 " - get header version\n"
308 "abootimg get recovery_dtbo [addr_var [size_var]]\n"
309 " - get address and size (hex) of recovery DTBO area in the image\n"
310 " [addr_var]: variable name to contain DTBO area address\n"
311 " [size_var]: variable name to contain DTBO area size\n"
312 "abootimg get dtb_load_addr [varname]\n"
313 " - get load address (hex) of DTB, from image header\n"
314 "abootimg get dtb --index=<num> [addr_var [size_var]]\n"
315 " - get address and size (hex) of DT blob in the image by index\n"
316 " <num>: index number of desired DT blob in DTB area\n"
317 " [addr_var]: variable name to contain DT blob address\n"
318 " [size_var]: variable name to contain DT blob size"
319);