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