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 int verify = env_get_yesno("verify"); 44 #endif 45 46 buf = map_sysmem(addr, 0); 47 switch (genimg_get_format(buf)) { 48 #if defined(CONFIG_IMAGE_FORMAT_LEGACY) 49 case IMAGE_FORMAT_LEGACY: 50 hdr = buf; 51 52 if (!image_check_magic (hdr)) { 53 puts ("Bad magic number\n"); 54 return 1; 55 } 56 57 if (!image_check_hcrc (hdr)) { 58 puts ("Bad header crc\n"); 59 return 1; 60 } 61 62 if (verify) { 63 if (!image_check_dcrc (hdr)) { 64 puts ("Bad data crc\n"); 65 return 1; 66 } 67 } 68 69 if (!image_check_type (hdr, IH_TYPE_SCRIPT)) { 70 puts ("Bad image type\n"); 71 return 1; 72 } 73 74 /* get length of script */ 75 data = (u32 *)image_get_data (hdr); 76 77 if ((len = uimage_to_cpu (*data)) == 0) { 78 puts ("Empty Script\n"); 79 return 1; 80 } 81 82 /* 83 * scripts are just multi-image files with one component, seek 84 * past the zero-terminated sequence of image lengths to get 85 * to the actual image data 86 */ 87 while (*data++); 88 break; 89 #endif 90 #if defined(CONFIG_FIT) 91 case IMAGE_FORMAT_FIT: 92 if (fit_uname == NULL) { 93 puts ("No FIT subimage unit name\n"); 94 return 1; 95 } 96 97 fit_hdr = buf; 98 if (!fit_check_format (fit_hdr)) { 99 puts ("Bad FIT image format\n"); 100 return 1; 101 } 102 103 /* get script component image node offset */ 104 noffset = fit_image_get_node (fit_hdr, fit_uname); 105 if (noffset < 0) { 106 printf ("Can't find '%s' FIT subimage\n", fit_uname); 107 return 1; 108 } 109 110 if (!fit_image_check_type (fit_hdr, noffset, IH_TYPE_SCRIPT)) { 111 puts ("Not a image image\n"); 112 return 1; 113 } 114 115 /* verify integrity */ 116 if (verify) { 117 if (!fit_image_verify(fit_hdr, noffset)) { 118 puts ("Bad Data Hash\n"); 119 return 1; 120 } 121 } 122 123 /* get script subimage data address and length */ 124 if (fit_image_get_data (fit_hdr, noffset, &fit_data, &fit_len)) { 125 puts ("Could not find script subimage data\n"); 126 return 1; 127 } 128 129 data = (u32 *)fit_data; 130 len = (ulong)fit_len; 131 break; 132 #endif 133 default: 134 puts ("Wrong image format for \"source\" command\n"); 135 return 1; 136 } 137 138 debug ("** Script length: %ld\n", len); 139 return run_command_list((char *)data, len, 0); 140 } 141 142 /**************************************************/ 143 #if defined(CONFIG_CMD_SOURCE) 144 static int do_source(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 145 { 146 ulong addr; 147 int rcode; 148 const char *fit_uname = NULL; 149 150 /* Find script image */ 151 if (argc < 2) { 152 addr = CONFIG_SYS_LOAD_ADDR; 153 debug ("* source: default load address = 0x%08lx\n", addr); 154 #if defined(CONFIG_FIT) 155 } else if (fit_parse_subimage (argv[1], load_addr, &addr, &fit_uname)) { 156 debug ("* source: subimage '%s' from FIT image at 0x%08lx\n", 157 fit_uname, addr); 158 #endif 159 } else { 160 addr = simple_strtoul(argv[1], NULL, 16); 161 debug ("* source: cmdline image address = 0x%08lx\n", addr); 162 } 163 164 printf ("## Executing script at %08lx\n", addr); 165 rcode = source (addr, fit_uname); 166 return rcode; 167 } 168 169 #ifdef CONFIG_SYS_LONGHELP 170 static char source_help_text[] = 171 "[addr]\n" 172 "\t- run script starting at addr\n" 173 "\t- A valid image header must be present" 174 #if defined(CONFIG_FIT) 175 "\n" 176 "For FIT format uImage addr must include subimage\n" 177 "unit name in the form of addr:<subimg_uname>" 178 #endif 179 ""; 180 #endif 181 182 U_BOOT_CMD( 183 source, 2, 0, do_source, 184 "run script from memory", source_help_text 185 ); 186 #endif 187