]> git.sur5r.net Git - u-boot/blob - common/cmd_ximg.c
77f68c44c785408c0ecb919314abc4f81781671f
[u-boot] / common / cmd_ximg.c
1 /*
2  * (C) Copyright 2000-2004
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * (C) Copyright 2003
6  * Kai-Uwe Bloem, Auerswald GmbH & Co KG, <linux-development@auerswald.de>
7  *
8  * See file CREDITS for list of people who contributed to this
9  * project.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License as
13  * published by the Free Software Foundation; either version 2 of
14  * the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
24  * MA 02111-1307 USA
25  */
26
27 #if defined(CONFIG_CMD_XIMG)
28
29 /*
30  * Multi Image extract
31  */
32 #include <common.h>
33 #include <command.h>
34 #include <image.h>
35 #include <asm/byteorder.h>
36
37 int
38 do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
39 {
40         ulong           addr = load_addr;
41         ulong           dest = 0;
42         ulong           data, len, count;
43         int             i, verify;
44         int             part = 0;
45         char            pbuf[10];
46         char            *s;
47         image_header_t  *hdr;
48 #if defined(CONFIG_FIT)
49         const char      *uname;
50         const void*     fit_hdr;
51         int             noffset;
52         const void      *fit_data;
53         size_t          fit_len;
54 #endif
55
56         verify = getenv_verify ();
57
58         if (argc > 1) {
59                 addr = simple_strtoul(argv[1], NULL, 16);
60         }
61         if (argc > 2) {
62                 part = simple_strtoul(argv[2], NULL, 16);
63 #if defined(CONFIG_FIT)
64                 uname = argv[2];
65 #endif
66         }
67         if (argc > 3) {
68                 dest = simple_strtoul(argv[3], NULL, 16);
69         }
70
71         switch (genimg_get_format ((void *)addr)) {
72         case IMAGE_FORMAT_LEGACY:
73
74                 printf("## Copying part %d from legacy image "
75                         "at %08lx ...\n", part, addr);
76
77                 hdr = (image_header_t *)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                         printf("Wrong Image Type for %s command\n",
93                                         cmdtp->name);
94                         return 1;
95                 }
96
97                 if (image_get_comp (hdr) != IH_COMP_NONE) {
98                         printf("Wrong Compression Type for %s command\n",
99                                         cmdtp->name);
100                         return 1;
101                 }
102
103                 if (verify) {
104                         printf("   Verifying Checksum ... ");
105                         if (!image_check_dcrc (hdr)) {
106                                 printf("Bad Data CRC\n");
107                                 return 1;
108                         }
109                         printf("OK\n");
110                 }
111
112                 count = image_multi_count (hdr);
113                 if (part >= count) {
114                         printf("Bad Image Part\n");
115                         return 1;
116                 }
117
118                 image_multi_getimg (hdr, part, &data, &len);
119                 break;
120 #if defined(CONFIG_FIT)
121         case IMAGE_FORMAT_FIT:
122                 if (uname == NULL) {
123                         puts ("No FIT subimage unit name\n");
124                         return 1;
125                 }
126
127                 printf("## Copying '%s' subimage from FIT image "
128                         "at %08lx ...\n", uname, addr);
129
130                 fit_hdr = (const void *)addr;
131                 if (!fit_check_format (fit_hdr)) {
132                         puts ("Bad FIT image format\n");
133                         return 1;
134                 }
135
136                 /* get subimage node offset */
137                 noffset = fit_image_get_node (fit_hdr, fit_uname);
138                 if (noffset < 0) {
139                         printf ("Can't find '%s' FIT subimage\n", uname);
140                         return 1;
141                 }
142
143                 if (fit_image_check_comp (fit_hdr, noffset, IH_COMP_NONE)) {
144                         printf("Wrong Compression Type for %s command\n",
145                                         cmdtp->name);
146                         return 1;
147                 }
148
149                 /* verify integrity */
150                 if (verify) {
151                         if (!fit_image_check_hashes (fit_hdr, noffset)) {
152                                 puts ("Bad Data Hash\n");
153                                 return 1;
154                         }
155                 }
156
157                 /* get subimage data address and length */
158                 if (fit_image_get_data (fit_hdr, noffset, &fit_data, &fit_len)) {
159                         puts ("Could not find script subimage data\n");
160                         return 1;
161                 }
162
163                 data = (ulong *)fit_data;
164                 len = (ulong)fit_len;
165                 break;
166 #endif
167         default:
168                 puts ("Invalid image type for imxtract\n");
169                 return 1;
170         }
171
172         if (argc > 3) {
173                 memcpy((char *) dest, (char *) data, len);
174         }
175
176         sprintf(pbuf, "%8lx", data);
177         setenv("fileaddr", pbuf);
178         sprintf(pbuf, "%8lx", len);
179         setenv("filesize", pbuf);
180
181         return 0;
182 }
183
184 U_BOOT_CMD(imxtract, 4, 1, do_imgextract,
185            "imxtract- extract a part of a multi-image\n",
186            "addr part [dest]\n"
187            "    - extract <part> from legacy image at <addr> and copy to <dest>\n"
188 #if defined(CONFIG_FIT)
189            "addr uname [dest]\n"
190            "    - extract <uname> subimage from FIT image at <addr> and copy to <dest>\n"
191 #endif
192 );
193
194 #endif