1 /* 2 * (C) Copyright 2001 3 * Kyle Harris, kharris@nexus-tech.net 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 /* 9 * The "source" command allows to define "script images", i. e. files 10 * that contain command sequences that can be executed by the command 11 * interpreter. It returns the exit status of the last command 12 * executed from the script. This is very similar to running a shell 13 * script in a UNIX shell, hence the name for the command. 14 */ 15 16 /* #define DEBUG */ 17 18 #include <common.h> 19 #include <command.h> 20 #include <image.h> 21 #include <malloc.h> 22 #include <mapmem.h> 23 #include <asm/byteorder.h> 24 #include <asm/io.h> 25 26 int 27 source (ulong addr, const char *fit_uname) 28 { 29 ulong len; 30 #if defined(CONFIG_IMAGE_FORMAT_LEGACY) 31 const image_header_t *hdr; 32 #endif 33 u32 *data; 34 35 void *buf; 36 #if defined(CONFIG_FIT) 37 const void* fit_hdr; 38 int noffset; 39 const void *fit_data; 40 size_t fit_len; 41 #endif 42 #if defined(CONFIG_IMAGE_FORMAT_LEGACY) || defined(CONFIG_FIT) 43 #ifdef CONFIG_FIT_SIGNATURE 44 int verify = 1; 45 #else 46 int verify = env_get_yesno("verify"); 47 #endif 48 #endif 49 buf = map_sysmem(addr, 0); 50 switch (genimg_get_format(buf)) { 51 #if defined(CONFIG_IMAGE_FORMAT_LEGACY) 52 case IMAGE_FORMAT_LEGACY: 53 hdr = buf; 54 55 if (!image_check_magic (hdr)) { 56 puts ("Bad magic number\n"); 57 return 1; 58 } 59 60 if (!image_check_hcrc (hdr)) { 61 puts ("Bad header crc\n"); 62 return 1; 63 } 64 65 if (verify) { 66 if (!image_check_dcrc (hdr)) { 67 puts ("Bad data crc\n"); 68 return 1; 69 } 70 } 71 72 if (!image_check_type (hdr, IH_TYPE_SCRIPT)) { 73 puts ("Bad image type\n"); 74 return 1; 75 } 76 77 /* get length of script */ 78 data = (u32 *)image_get_data (hdr); 79 80 if ((len = uimage_to_cpu (*data)) == 0) { 81 puts ("Empty Script\n"); 82 return 1; 83 } 84 85 /* 86 * scripts are just multi-image files with one component, seek 87 * past the zero-terminated sequence of image lengths to get 88 * to the actual image data 89 */ 90 while (*data++ != IMAGE_PARAM_INVAL); 91 break; 92 #endif 93 #if defined(CONFIG_FIT) 94 case IMAGE_FORMAT_FIT: 95 if (fit_uname == NULL) { 96 puts ("No FIT subimage unit name\n"); 97 return 1; 98 } 99 100 fit_hdr = buf; 101 if (!fit_check_format (fit_hdr)) { 102 puts ("Bad FIT image format\n"); 103 return 1; 104 } 105 106 /* get script component image node offset */ 107 noffset = fit_image_get_node (fit_hdr, fit_uname); 108 if (noffset < 0) { 109 printf ("Can't find '%s' FIT subimage\n", fit_uname); 110 return 1; 111 } 112 113 if (!fit_image_check_type (fit_hdr, noffset, IH_TYPE_SCRIPT)) { 114 puts ("Not a image image\n"); 115 return 1; 116 } 117 118 /* verify integrity */ 119 if (verify) { 120 #ifdef CONFIG_FIT_SIGNATURE 121 int conf_noffset; 122 123 /* NULL for default conf */ 124 conf_noffset = fit_conf_get_node(fit_hdr, NULL); 125 if (conf_noffset < 0) 126 return conf_noffset; 127 128 if (fit_config_verify(fit_hdr, conf_noffset)) { 129 puts ("Bad Data Hash\n"); 130 return 1; 131 } 132 #endif 133 if (!fit_image_verify(fit_hdr, noffset)) { 134 puts ("Bad Data Hash\n"); 135 return 1; 136 } 137 } 138 139 /* get script subimage data address and length */ 140 if (fit_image_get_data (fit_hdr, noffset, &fit_data, &fit_len)) { 141 puts ("Could not find script subimage data\n"); 142 return 1; 143 } 144 145 data = (u32 *)fit_data; 146 len = (ulong)fit_len; 147 break; 148 #endif 149 default: 150 puts ("Wrong image format for \"source\" command\n"); 151 return 1; 152 } 153 154 debug ("** Script length: %ld\n", len); 155 return run_command_list((char *)data, len, 0); 156 } 157 158 /**************************************************/ 159 #if defined(CONFIG_CMD_SOURCE) 160 static int do_source(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 161 { 162 ulong addr; 163 int rcode; 164 const char *fit_uname = NULL; 165 166 /* Find script image */ 167 if (argc < 2) { 168 addr = CONFIG_SYS_LOAD_ADDR; 169 debug ("* source: default load address = 0x%08lx\n", addr); 170 #if defined(CONFIG_FIT) 171 } else if (fit_parse_subimage (argv[1], load_addr, &addr, &fit_uname)) { 172 debug ("* source: subimage '%s' from FIT image at 0x%08lx\n", 173 fit_uname, addr); 174 #endif 175 } else { 176 addr = simple_strtoul(argv[1], NULL, 16); 177 debug ("* source: cmdline image address = 0x%08lx\n", addr); 178 } 179 180 printf ("## Executing script at %08lx\n", addr); 181 rcode = source (addr, fit_uname); 182 return rcode; 183 } 184 185 #ifdef CONFIG_SYS_LONGHELP 186 static char source_help_text[] = 187 "[addr]\n" 188 "\t- run script starting at addr\n" 189 "\t- A valid image header must be present" 190 #if defined(CONFIG_FIT) 191 "\n" 192 "For FIT format uImage addr must include subimage\n" 193 "unit name in the form of addr:<subimg_uname>" 194 #endif 195 ""; 196 #endif 197 198 U_BOOT_CMD( 199 source, 2, 0, do_source, 200 "run script from memory", source_help_text 201 ); 202 #endif 203