bootm: Reduce the unnecessary memmove
[platform/kernel/u-boot.git] / 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
28 /*
29  * Multi Image extract
30  */
31 #include <common.h>
32 #include <command.h>
33 #include <image.h>
34 #include <asm/byteorder.h>
35
36 int
37 do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
38 {
39         ulong           addr = load_addr;
40         ulong           dest = 0;
41         ulong           data, len, count;
42         int             verify;
43         int             part = 0;
44         char            pbuf[10];
45         image_header_t  *hdr;
46 #if defined(CONFIG_FIT)
47         const char      *uname = NULL;
48         const void*     fit_hdr;
49         int             noffset;
50         const void      *fit_data;
51         size_t          fit_len;
52 #endif
53
54         verify = getenv_yesno ("verify");
55
56         if (argc > 1) {
57                 addr = simple_strtoul(argv[1], NULL, 16);
58         }
59         if (argc > 2) {
60                 part = simple_strtoul(argv[2], NULL, 16);
61 #if defined(CONFIG_FIT)
62                 uname = argv[2];
63 #endif
64         }
65         if (argc > 3) {
66                 dest = simple_strtoul(argv[3], NULL, 16);
67         }
68
69         switch (genimg_get_format ((void *)addr)) {
70         case IMAGE_FORMAT_LEGACY:
71
72                 printf("## Copying part %d from legacy image "
73                         "at %08lx ...\n", part, addr);
74
75                 hdr = (image_header_t *)addr;
76                 if (!image_check_magic (hdr)) {
77                         printf("Bad Magic Number\n");
78                         return 1;
79                 }
80
81                 if (!image_check_hcrc (hdr)) {
82                         printf("Bad Header Checksum\n");
83                         return 1;
84                 }
85 #ifdef DEBUG
86                 image_print_contents (hdr);
87 #endif
88
89                 if (!image_check_type (hdr, IH_TYPE_MULTI)) {
90                         printf("Wrong Image Type for %s command\n",
91                                         cmdtp->name);
92                         return 1;
93                 }
94
95                 if (image_get_comp (hdr) != IH_COMP_NONE) {
96                         printf("Wrong Compression Type for %s command\n",
97                                         cmdtp->name);
98                         return 1;
99                 }
100
101                 if (verify) {
102                         printf("   Verifying Checksum ... ");
103                         if (!image_check_dcrc (hdr)) {
104                                 printf("Bad Data CRC\n");
105                                 return 1;
106                         }
107                         printf("OK\n");
108                 }
109
110                 count = image_multi_count (hdr);
111                 if (part >= count) {
112                         printf("Bad Image Part\n");
113                         return 1;
114                 }
115
116                 image_multi_getimg (hdr, part, &data, &len);
117                 break;
118 #if defined(CONFIG_FIT)
119         case IMAGE_FORMAT_FIT:
120                 if (uname == NULL) {
121                         puts ("No FIT subimage unit name\n");
122                         return 1;
123                 }
124
125                 printf("## Copying '%s' subimage from FIT image "
126                         "at %08lx ...\n", uname, addr);
127
128                 fit_hdr = (const void *)addr;
129                 if (!fit_check_format (fit_hdr)) {
130                         puts ("Bad FIT image format\n");
131                         return 1;
132                 }
133
134                 /* get subimage node offset */
135                 noffset = fit_image_get_node (fit_hdr, uname);
136                 if (noffset < 0) {
137                         printf ("Can't find '%s' FIT subimage\n", uname);
138                         return 1;
139                 }
140
141                 if (fit_image_check_comp (fit_hdr, noffset, IH_COMP_NONE)) {
142                         printf("Wrong Compression Type for %s command\n",
143                                         cmdtp->name);
144                         return 1;
145                 }
146
147                 /* verify integrity */
148                 if (verify) {
149                         if (!fit_image_check_hashes (fit_hdr, noffset)) {
150                                 puts ("Bad Data Hash\n");
151                                 return 1;
152                         }
153                 }
154
155                 /* get subimage data address and length */
156                 if (fit_image_get_data (fit_hdr, noffset, &fit_data, &fit_len)) {
157                         puts ("Could not find script subimage data\n");
158                         return 1;
159                 }
160
161                 data = (ulong)fit_data;
162                 len = (ulong)fit_len;
163                 break;
164 #endif
165         default:
166                 puts ("Invalid image type for imxtract\n");
167                 return 1;
168         }
169
170         if (argc > 3) {
171                 memcpy((char *) dest, (char *) data, len);
172         }
173
174         sprintf(pbuf, "%8lx", data);
175         setenv("fileaddr", pbuf);
176         sprintf(pbuf, "%8lx", len);
177         setenv("filesize", pbuf);
178
179         return 0;
180 }
181
182 U_BOOT_CMD(imxtract, 4, 1, do_imgextract,
183            "extract a part of a multi-image",
184            "addr part [dest]\n"
185            "    - extract <part> from legacy image at <addr> and copy to <dest>\n"
186 #if defined(CONFIG_FIT)
187            "addr uname [dest]\n"
188            "    - extract <uname> subimage from FIT image at <addr> and copy to <dest>\n"
189 #endif
190 );