image: Rename load_addr, save_addr, save_size
[oweals/u-boot.git] / cmd / ximg.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2000-2004
4  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5  *
6  * (C) Copyright 2003
7  * Kai-Uwe Bloem, Auerswald GmbH & Co KG, <linux-development@auerswald.de>
8  */
9
10
11 /*
12  * Multi Image extract
13  */
14 #include <common.h>
15 #include <command.h>
16 #include <cpu_func.h>
17 #include <env.h>
18 #include <gzip.h>
19 #include <image.h>
20 #include <mapmem.h>
21 #include <watchdog.h>
22 #if defined(CONFIG_BZIP2)
23 #include <bzlib.h>
24 #endif
25 #include <asm/byteorder.h>
26 #include <asm/io.h>
27
28 #ifndef CONFIG_SYS_XIMG_LEN
29 /* use 8MByte as default max gunzip size */
30 #define CONFIG_SYS_XIMG_LEN     0x800000
31 #endif
32
33 static int
34 do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
35 {
36         ulong           addr = image_load_addr;
37         ulong           dest = 0;
38         ulong           data, len;
39         int             verify;
40         int             part = 0;
41 #if defined(CONFIG_LEGACY_IMAGE_FORMAT)
42         ulong           count;
43         image_header_t  *hdr = NULL;
44 #endif
45 #if defined(CONFIG_FIT)
46         const char      *uname = NULL;
47         const void*     fit_hdr;
48         int             noffset;
49         const void      *fit_data;
50         size_t          fit_len;
51 #endif
52 #ifdef CONFIG_GZIP
53         uint            unc_len = CONFIG_SYS_XIMG_LEN;
54 #endif
55         uint8_t         comp;
56
57         verify = env_get_yesno("verify");
58
59         if (argc > 1) {
60                 addr = simple_strtoul(argv[1], NULL, 16);
61         }
62         if (argc > 2) {
63                 part = simple_strtoul(argv[2], NULL, 16);
64 #if defined(CONFIG_FIT)
65                 uname = argv[2];
66 #endif
67         }
68         if (argc > 3) {
69                 dest = simple_strtoul(argv[3], NULL, 16);
70         }
71
72         switch (genimg_get_format((void *)addr)) {
73 #if defined(CONFIG_LEGACY_IMAGE_FORMAT)
74         case IMAGE_FORMAT_LEGACY:
75
76                 printf("## Copying part %d from legacy image "
77                         "at %08lx ...\n", part, addr);
78
79                 hdr = (image_header_t *)addr;
80                 if (!image_check_magic(hdr)) {
81                         printf("Bad Magic Number\n");
82                         return 1;
83                 }
84
85                 if (!image_check_hcrc(hdr)) {
86                         printf("Bad Header Checksum\n");
87                         return 1;
88                 }
89 #ifdef DEBUG
90                 image_print_contents(hdr);
91 #endif
92
93                 if (!image_check_type(hdr, IH_TYPE_MULTI) &&
94                     !image_check_type(hdr, IH_TYPE_SCRIPT)) {
95                         printf("Wrong Image Type for %s command\n",
96                                         cmdtp->name);
97                         return 1;
98                 }
99
100                 comp = image_get_comp(hdr);
101                 if ((comp != IH_COMP_NONE) && (argc < 4)) {
102                         printf("Must specify load address for %s command "
103                                         "with compressed image\n",
104                                         cmdtp->name);
105                         return 1;
106                 }
107
108                 if (verify) {
109                         printf("   Verifying Checksum ... ");
110                         if (!image_check_dcrc(hdr)) {
111                                 printf("Bad Data CRC\n");
112                                 return 1;
113                         }
114                         printf("OK\n");
115                 }
116
117                 count = image_multi_count(hdr);
118                 if (part >= count) {
119                         printf("Bad Image Part\n");
120                         return 1;
121                 }
122
123                 image_multi_getimg(hdr, part, &data, &len);
124                 break;
125 #endif
126 #if defined(CONFIG_FIT)
127         case IMAGE_FORMAT_FIT:
128                 if (uname == NULL) {
129                         puts("No FIT subimage unit name\n");
130                         return 1;
131                 }
132
133                 printf("## Copying '%s' subimage from FIT image "
134                         "at %08lx ...\n", uname, addr);
135
136                 fit_hdr = (const void *)addr;
137                 if (!fit_check_format(fit_hdr)) {
138                         puts("Bad FIT image format\n");
139                         return 1;
140                 }
141
142                 /* get subimage node offset */
143                 noffset = fit_image_get_node(fit_hdr, uname);
144                 if (noffset < 0) {
145                         printf("Can't find '%s' FIT subimage\n", uname);
146                         return 1;
147                 }
148
149                 if (!fit_image_check_comp(fit_hdr, noffset, IH_COMP_NONE)
150                     && (argc < 4)) {
151                         printf("Must specify load address for %s command "
152                                 "with compressed image\n",
153                                 cmdtp->name);
154                         return 1;
155                 }
156
157                 /* verify integrity */
158                 if (verify) {
159                         if (!fit_image_verify(fit_hdr, noffset)) {
160                                 puts("Bad Data Hash\n");
161                                 return 1;
162                         }
163                 }
164
165                 /* get subimage/external data address and length */
166                 if (fit_image_get_data_and_size(fit_hdr, noffset,
167                                                &fit_data, &fit_len)) {
168                         puts("Could not find script subimage data\n");
169                         return 1;
170                 }
171
172                 if (fit_image_get_comp(fit_hdr, noffset, &comp)) {
173                         puts("Could not find script subimage "
174                                 "compression type\n");
175                         return 1;
176                 }
177
178                 data = (ulong)fit_data;
179                 len = (ulong)fit_len;
180                 break;
181 #endif
182         default:
183                 puts("Invalid image type for imxtract\n");
184                 return 1;
185         }
186
187         if (argc > 3) {
188                 switch (comp) {
189                 case IH_COMP_NONE:
190 #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
191                         {
192                                 size_t l = len;
193                                 size_t tail;
194                                 void *to = (void *) dest;
195                                 void *from = (void *)data;
196
197                                 printf("   Loading part %d ... ", part);
198
199                                 while (l > 0) {
200                                         tail = (l > CHUNKSZ) ? CHUNKSZ : l;
201                                         WATCHDOG_RESET();
202                                         memmove(to, from, tail);
203                                         to += tail;
204                                         from += tail;
205                                         l -= tail;
206                                 }
207                         }
208 #else   /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */
209                         printf("   Loading part %d ... ", part);
210                         memmove((char *) dest, (char *)data, len);
211 #endif  /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */
212                         break;
213 #ifdef CONFIG_GZIP
214                 case IH_COMP_GZIP:
215                         printf("   Uncompressing part %d ... ", part);
216                         if (gunzip((void *) dest, unc_len,
217                                    (uchar *) data, &len) != 0) {
218                                 puts("GUNZIP ERROR - image not loaded\n");
219                                 return 1;
220                         }
221                         break;
222 #endif
223 #if defined(CONFIG_BZIP2) && defined(CONFIG_LEGACY_IMAGE_FORMAT)
224                 case IH_COMP_BZIP2:
225                         {
226                                 int i;
227
228                                 printf("   Uncompressing part %d ... ", part);
229                                 /*
230                                  * If we've got less than 4 MB of malloc()
231                                  * space, use slower decompression algorithm
232                                  * which requires at most 2300 KB of memory.
233                                  */
234                                 i = BZ2_bzBuffToBuffDecompress(
235                                         map_sysmem(ntohl(hdr->ih_load), 0),
236                                         &unc_len, (char *)data, len,
237                                         CONFIG_SYS_MALLOC_LEN < (4096 * 1024),
238                                         0);
239                                 if (i != BZ_OK) {
240                                         printf("BUNZIP2 ERROR %d - "
241                                                 "image not loaded\n", i);
242                                         return 1;
243                                 }
244                         }
245                         break;
246 #endif /* CONFIG_BZIP2 */
247                 default:
248                         printf("Unimplemented compression type %d\n", comp);
249                         return 1;
250                 }
251                 puts("OK\n");
252         }
253
254         flush_cache(dest, ALIGN(len, ARCH_DMA_MINALIGN));
255
256         env_set_hex("fileaddr", data);
257         env_set_hex("filesize", len);
258
259         return 0;
260 }
261
262 #ifdef CONFIG_SYS_LONGHELP
263 static char imgextract_help_text[] =
264         "addr part [dest]\n"
265         "    - extract <part> from legacy image at <addr> and copy to <dest>"
266 #if defined(CONFIG_FIT)
267         "\n"
268         "addr uname [dest]\n"
269         "    - extract <uname> subimage from FIT image at <addr> and copy to <dest>"
270 #endif
271         "";
272 #endif
273
274 U_BOOT_CMD(
275         imxtract, 4, 1, do_imgextract,
276         "extract a part of a multi-image", imgextract_help_text
277 );