]> git.sur5r.net Git - u-boot/blob - common/cmd_autoscript.c
5163d57cc4d9f3ce994f6ca6ad337791ae70fa9b
[u-boot] / common / cmd_autoscript.c
1 /*
2  * (C) Copyright 2001
3  * Kyle Harris, kharris@nexus-tech.net
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23
24 /*
25  * autoscript allows a remote host to download a command file and,
26  * optionally, binary data for automatically updating the target. For
27  * example, you create a new kernel image and want the user to be
28  * able to simply download the image and the machine does the rest.
29  * The kernel image is postprocessed with mkimage, which creates an
30  * image with a script file prepended. If enabled, autoscript will
31  * verify the script and contents of the download and execute the
32  * script portion. This would be responsible for erasing flash,
33  * copying the new image, and rebooting the machine.
34  */
35
36 /* #define DEBUG */
37
38 #include <common.h>
39 #include <command.h>
40 #include <image.h>
41 #include <malloc.h>
42 #include <asm/byteorder.h>
43 #if defined(CONFIG_8xx)
44 #include <mpc8xx.h>
45 #endif
46 #ifdef CFG_HUSH_PARSER
47 #include <hush.h>
48 #endif
49
50 #if defined(CONFIG_AUTOSCRIPT) || defined(CONFIG_CMD_AUTOSCRIPT)
51
52 int
53 autoscript (ulong addr, const char *fit_uname)
54 {
55         ulong           len;
56         image_header_t  *hdr;
57         ulong           *data;
58         char            *cmd;
59         int             rcode = 0;
60         int             verify;
61 #if defined(CONFIG_FIT)
62         const void*     fit_hdr;
63         int             noffset;
64         const void      *fit_data;
65         size_t          fit_len;
66 #endif
67
68         verify = getenv_verify ();
69
70         switch (genimg_get_format ((void *)addr)) {
71         case IMAGE_FORMAT_LEGACY:
72                 hdr = (image_header_t *)addr;
73
74                 if (!image_check_magic (hdr)) {
75                         puts ("Bad magic number\n");
76                         return 1;
77                 }
78
79                 if (!image_check_hcrc (hdr)) {
80                         puts ("Bad header crc\n");
81                         return 1;
82                 }
83
84                 if (verify) {
85                         if (!image_check_dcrc (hdr)) {
86                                 puts ("Bad data crc\n");
87                                 return 1;
88                         }
89                 }
90
91                 if (!image_check_type (hdr, IH_TYPE_SCRIPT)) {
92                         puts ("Bad image type\n");
93                         return 1;
94                 }
95
96                 /* get length of script */
97                 data = (ulong *)image_get_data (hdr);
98
99                 if ((len = uimage_to_cpu (*data)) == 0) {
100                         puts ("Empty Script\n");
101                         return 1;
102                 }
103                 break;
104 #if defined(CONFIG_FIT)
105         case IMAGE_FORMAT_FIT:
106                 if (fit_uname == NULL) {
107                         puts ("No FIT subimage unit name\n");
108                         return 1;
109                 }
110
111                 fit_hdr = (const void *)addr;
112                 if (!fit_check_format (fit_hdr)) {
113                         puts ("Bad FIT image format\n");
114                         return 1;
115                 }
116
117                 /* get script component image node offset */
118                 noffset = fit_image_get_node (fit_hdr, fit_uname);
119                 if (noffset < 0) {
120                         printf ("Can't find '%s' FIT subimage\n", fit_uname);
121                         return 1;
122                 }
123
124                 if (!fit_image_check_type (fit_hdr, noffset, IH_TYPE_SCRIPT)) {
125                         puts ("Not a image image\n");
126                         return 1;
127                 }
128
129                 /* verify integrity */
130                 if (verify) {
131                         if (!fit_image_check_hashes (fit_hdr, noffset)) {
132                                 puts ("Bad Data Hash\n");
133                                 return 1;
134                         }
135                 }
136
137                 /* get script subimage data address and length */
138                 if (fit_image_get_data (fit_hdr, noffset, &fit_data, &fit_len)) {
139                         puts ("Could not find script subimage data\n");
140                         return 1;
141                 }
142
143                 data = (ulong *)fit_data;
144                 len = (ulong)fit_len;
145                 break;
146 #endif
147         default:
148                 puts ("Wrong image format for autoscript\n");
149                 return 1;
150         }
151
152         debug ("** Script length: %ld\n", len);
153
154         if ((cmd = malloc (len + 1)) == NULL) {
155                 return 1;
156         }
157
158         while (*data++);
159
160         /* make sure cmd is null terminated */
161         memmove (cmd, (char *)data, len);
162         *(cmd + len) = 0;
163
164 #ifdef CFG_HUSH_PARSER /*?? */
165         rcode = parse_string_outer (cmd, FLAG_PARSE_SEMICOLON);
166 #else
167         {
168                 char *line = cmd;
169                 char *next = cmd;
170
171                 /*
172                  * break into individual lines,
173                  * and execute each line;
174                  * terminate on error.
175                  */
176                 while (*next) {
177                         if (*next == '\n') {
178                                 *next = '\0';
179                                 /* run only non-empty commands */
180                                 if ((next - line) > 1) {
181                                         debug ("** exec: \"%s\"\n",
182                                                 line);
183                                         if (run_command (line, 0) < 0) {
184                                                 rcode = 1;
185                                                 break;
186                                         }
187                                 }
188                                 line = next + 1;
189                         }
190                         ++next;
191                 }
192         }
193 #endif
194         free (cmd);
195         return rcode;
196 }
197
198 #endif
199
200 /**************************************************/
201 #if defined(CONFIG_CMD_AUTOSCRIPT)
202 int
203 do_autoscript (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
204 {
205         ulong addr;
206         int rcode;
207         const char *fit_uname = NULL;
208
209         /* Find script image */
210         if (argc < 2) {
211                 addr = CFG_LOAD_ADDR;
212                 debug ("*  autoscr: default load address = 0x%08lx\n", addr);
213 #if defined(CONFIG_FIT)
214         } else if (fit_parse_subimage (argv[1], load_addr, &addr, &fit_uname)) {
215                 debug ("*  autoscr: subimage '%s' from FIT image at 0x%08lx\n",
216                                 fit_uname, addr);
217 #endif
218         } else {
219                 addr = simple_strtoul(argv[1], NULL, 16);
220                 debug ("*  autoscr: cmdline image address = 0x%08lx\n", addr);
221         }
222
223         printf ("## Executing script at %08lx\n", addr);
224         rcode = autoscript (addr, fit_uname);
225         return rcode;
226 }
227
228 U_BOOT_CMD(
229         autoscr, 2, 0,  do_autoscript,
230         "autoscr - run script from memory\n",
231         "[addr] - run script starting at addr"
232         " - A valid autoscr header must be present\n"
233 #if defined(CONFIG_FIT)
234         "For FIT format uImage addr must include subimage\n"
235         "unit name in the form of addr:<subimg_uname>\n"
236 #endif
237 );
238 #endif