]> Git Repo - J-u-boot.git/blob - cmd/source.c
image: Add a function to find a script in an image
[J-u-boot.git] / cmd / source.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2001
4  * Kyle Harris, [email protected]
5  */
6
7 /*
8  * The "source" command allows to define "script images", i. e. files
9  * that contain command sequences that can be executed by the command
10  * interpreter. It returns the exit status of the last command
11  * executed from the script. This is very similar to running a shell
12  * script in a UNIX shell, hence the name for the command.
13  */
14
15 /* #define DEBUG */
16
17 #include <common.h>
18 #include <command.h>
19 #include <env.h>
20 #include <image.h>
21 #include <log.h>
22 #include <malloc.h>
23 #include <mapmem.h>
24 #include <asm/byteorder.h>
25 #include <asm/io.h>
26
27 /**
28  * get_default_image() - Return default property from /images
29  *
30  * Return: Pointer to value of default property (or NULL)
31  */
32 static const char *get_default_image(const void *fit)
33 {
34         int images_noffset;
35
36         images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
37         if (images_noffset < 0)
38                 return NULL;
39
40         return fdt_getprop(fit, images_noffset, FIT_DEFAULT_PROP, NULL);
41 }
42
43 int image_locate_script(void *buf, int size, const char *fit_uname,
44                         const char *confname, char **datap, uint *lenp)
45 {
46         ulong           len;
47         const struct legacy_img_hdr *hdr;
48         u32             *data;
49         int             verify;
50         const void*     fit_hdr;
51         int             noffset;
52         const void      *fit_data;
53         size_t          fit_len;
54
55         verify = env_get_yesno("verify");
56
57         switch (genimg_get_format(buf)) {
58         case IMAGE_FORMAT_LEGACY:
59                 if (IS_ENABLED(CONFIG_LEGACY_IMAGE_FORMAT)) {
60                         hdr = buf;
61
62                         if (!image_check_magic(hdr)) {
63                                 puts("Bad magic number\n");
64                                 return 1;
65                         }
66
67                         if (!image_check_hcrc(hdr)) {
68                                 puts("Bad header crc\n");
69                                 return 1;
70                         }
71
72                         if (verify) {
73                                 if (!image_check_dcrc(hdr)) {
74                                         puts("Bad data crc\n");
75                                         return 1;
76                                 }
77                         }
78
79                         if (!image_check_type(hdr, IH_TYPE_SCRIPT)) {
80                                 puts("Bad image type\n");
81                                 return 1;
82                         }
83
84                         /* get length of script */
85                         data = (u32 *)image_get_data(hdr);
86
87                         len = uimage_to_cpu(*data);
88                         if (!len) {
89                                 puts("Empty Script\n");
90                                 return 1;
91                         }
92
93                         /*
94                          * scripts are just multi-image files with one
95                          * component, so seek past the zero-terminated sequence
96                          * of image lengths to get to the actual image data
97                          */
98                         while (*data++);
99                 }
100                 break;
101         case IMAGE_FORMAT_FIT:
102                 if (IS_ENABLED(CONFIG_FIT)) {
103                         fit_hdr = buf;
104                         if (fit_check_format(fit_hdr, IMAGE_SIZE_INVAL)) {
105                                 puts("Bad FIT image format\n");
106                                 return 1;
107                         }
108
109                         if (!fit_uname) {
110                                 /* If confname is empty, use the default */
111                                 if (confname && *confname)
112                                         noffset = fit_conf_get_node(fit_hdr, confname);
113                                 else
114                                         noffset = fit_conf_get_node(fit_hdr, NULL);
115                                 if (noffset < 0) {
116                                         if (!confname)
117                                                 goto fallback;
118                                         printf("Could not find config %s\n", confname);
119                                         return 1;
120                                 }
121
122                                 if (verify && fit_config_verify(fit_hdr, noffset))
123                                         return 1;
124
125                                 noffset = fit_conf_get_prop_node(fit_hdr,
126                                                                  noffset,
127                                                                  FIT_SCRIPT_PROP,
128                                                                  IH_PHASE_NONE);
129                                 if (noffset < 0) {
130                                         if (!confname)
131                                                 goto fallback;
132                                         printf("Could not find script in %s\n", confname);
133                                         return 1;
134                                 }
135                         } else {
136 fallback:
137                                 if (!fit_uname || !*fit_uname)
138                                         fit_uname = get_default_image(fit_hdr);
139                                 if (!fit_uname) {
140                                         puts("No FIT subimage unit name\n");
141                                         return 1;
142                                 }
143
144                                 /* get script component image node offset */
145                                 noffset = fit_image_get_node(fit_hdr, fit_uname);
146                                 if (noffset < 0) {
147                                         printf("Can't find '%s' FIT subimage\n",
148                                               fit_uname);
149                                         return 1;
150                                 }
151                         }
152
153                         if (!fit_image_check_type(fit_hdr, noffset,
154                                                   IH_TYPE_SCRIPT)) {
155                                 puts("Not a image image\n");
156                                 return 1;
157                         }
158
159                         /* verify integrity */
160                         if (verify && !fit_image_verify(fit_hdr, noffset)) {
161                                 puts("Bad Data Hash\n");
162                                 return 1;
163                         }
164
165                         /* get script subimage data address and length */
166                         if (fit_image_get_data(fit_hdr, noffset, &fit_data, &fit_len)) {
167                                 puts("Could not find script subimage data\n");
168                                 return 1;
169                         }
170
171                         data = (u32 *)fit_data;
172                         len = (ulong)fit_len;
173                 }
174                 break;
175         default:
176                 puts("Wrong image format for \"source\" command\n");
177                 return -EPERM;
178         }
179
180         *datap = (char *)data;
181         *lenp = len;
182
183         return 0;
184 }
185
186 int image_source_script(ulong addr, const char *fit_uname, const char *confname)
187 {
188         char *data;
189         void *buf;
190         uint len;
191         int ret;
192
193         buf = map_sysmem(addr, 0);
194         ret = image_locate_script(buf, 0, fit_uname, confname, &data, &len);
195         unmap_sysmem(buf);
196         if (ret)
197                 return CMD_RET_FAILURE;
198
199         debug("** Script length: %d\n", len);
200         return run_command_list(data, len, 0);
201 }
202
203 /**************************************************/
204 #if defined(CONFIG_CMD_SOURCE)
205 static int do_source(struct cmd_tbl *cmdtp, int flag, int argc,
206                      char *const argv[])
207 {
208         ulong addr;
209         int rcode;
210         const char *fit_uname = NULL, *confname = NULL;
211
212         /* Find script image */
213         if (argc < 2) {
214                 addr = CONFIG_SYS_LOAD_ADDR;
215                 debug("*  source: default load address = 0x%08lx\n", addr);
216 #if defined(CONFIG_FIT)
217         } else if (fit_parse_subimage(argv[1], image_load_addr, &addr,
218                                       &fit_uname)) {
219                 debug("*  source: subimage '%s' from FIT image at 0x%08lx\n",
220                       fit_uname, addr);
221         } else if (fit_parse_conf(argv[1], image_load_addr, &addr, &confname)) {
222                 debug("*  source: config '%s' from FIT image at 0x%08lx\n",
223                       confname, addr);
224 #endif
225         } else {
226                 addr = hextoul(argv[1], NULL);
227                 debug("*  source: cmdline image address = 0x%08lx\n", addr);
228         }
229
230         printf ("## Executing script at %08lx\n", addr);
231         rcode = image_source_script(addr, fit_uname, confname);
232         return rcode;
233 }
234
235 #ifdef CONFIG_SYS_LONGHELP
236 static char source_help_text[] =
237 #if defined(CONFIG_FIT)
238         "[<addr>][:[<image>]|#[<config>]]\n"
239         "\t- Run script starting at addr\n"
240         "\t- A FIT config name or subimage name may be specified with : or #\n"
241         "\t  (like bootm). If the image or config name is omitted, the\n"
242         "\t  default is used.";
243 #else
244         "[<addr>]\n"
245         "\t- Run script starting at addr";
246 #endif
247 #endif
248
249 U_BOOT_CMD(
250         source, 2, 0,   do_source,
251         "run script from memory", source_help_text
252 );
253 #endif
This page took 0.041546 seconds and 4 git commands to generate.