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