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