12e192b24SSimon Glass /* 22e192b24SSimon Glass * (C) Copyright 2001 32e192b24SSimon Glass * Kyle Harris, kharris@nexus-tech.net 42e192b24SSimon Glass * 52e192b24SSimon Glass * SPDX-License-Identifier: GPL-2.0+ 62e192b24SSimon Glass */ 72e192b24SSimon Glass 82e192b24SSimon Glass /* 92e192b24SSimon Glass * The "source" command allows to define "script images", i. e. files 102e192b24SSimon Glass * that contain command sequences that can be executed by the command 112e192b24SSimon Glass * interpreter. It returns the exit status of the last command 122e192b24SSimon Glass * executed from the script. This is very similar to running a shell 132e192b24SSimon Glass * script in a UNIX shell, hence the name for the command. 142e192b24SSimon Glass */ 152e192b24SSimon Glass 162e192b24SSimon Glass /* #define DEBUG */ 172e192b24SSimon Glass 182e192b24SSimon Glass #include <common.h> 192e192b24SSimon Glass #include <command.h> 202e192b24SSimon Glass #include <image.h> 212e192b24SSimon Glass #include <malloc.h> 222e192b24SSimon Glass #include <mapmem.h> 232e192b24SSimon Glass #include <asm/byteorder.h> 242e192b24SSimon Glass #include <asm/io.h> 252e192b24SSimon Glass 262e192b24SSimon Glass int 272e192b24SSimon Glass source (ulong addr, const char *fit_uname) 282e192b24SSimon Glass { 292e192b24SSimon Glass ulong len; 302e192b24SSimon Glass #if defined(CONFIG_IMAGE_FORMAT_LEGACY) 312e192b24SSimon Glass const image_header_t *hdr; 322e192b24SSimon Glass #endif 332e192b24SSimon Glass u32 *data; 34408bf4b9SJoseph Chen 352e192b24SSimon Glass void *buf; 362e192b24SSimon Glass #if defined(CONFIG_FIT) 372e192b24SSimon Glass const void* fit_hdr; 382e192b24SSimon Glass int noffset; 392e192b24SSimon Glass const void *fit_data; 402e192b24SSimon Glass size_t fit_len; 412e192b24SSimon Glass #endif 42408bf4b9SJoseph Chen #if defined(CONFIG_IMAGE_FORMAT_LEGACY) || defined(CONFIG_FIT) 43408bf4b9SJoseph Chen int verify = env_get_yesno("verify"); 44408bf4b9SJoseph Chen #endif 452e192b24SSimon Glass 462e192b24SSimon Glass buf = map_sysmem(addr, 0); 472e192b24SSimon Glass switch (genimg_get_format(buf)) { 482e192b24SSimon Glass #if defined(CONFIG_IMAGE_FORMAT_LEGACY) 492e192b24SSimon Glass case IMAGE_FORMAT_LEGACY: 502e192b24SSimon Glass hdr = buf; 512e192b24SSimon Glass 522e192b24SSimon Glass if (!image_check_magic (hdr)) { 532e192b24SSimon Glass puts ("Bad magic number\n"); 542e192b24SSimon Glass return 1; 552e192b24SSimon Glass } 562e192b24SSimon Glass 572e192b24SSimon Glass if (!image_check_hcrc (hdr)) { 582e192b24SSimon Glass puts ("Bad header crc\n"); 592e192b24SSimon Glass return 1; 602e192b24SSimon Glass } 612e192b24SSimon Glass 622e192b24SSimon Glass if (verify) { 632e192b24SSimon Glass if (!image_check_dcrc (hdr)) { 642e192b24SSimon Glass puts ("Bad data crc\n"); 652e192b24SSimon Glass return 1; 662e192b24SSimon Glass } 672e192b24SSimon Glass } 682e192b24SSimon Glass 692e192b24SSimon Glass if (!image_check_type (hdr, IH_TYPE_SCRIPT)) { 702e192b24SSimon Glass puts ("Bad image type\n"); 712e192b24SSimon Glass return 1; 722e192b24SSimon Glass } 732e192b24SSimon Glass 742e192b24SSimon Glass /* get length of script */ 752e192b24SSimon Glass data = (u32 *)image_get_data (hdr); 762e192b24SSimon Glass 772e192b24SSimon Glass if ((len = uimage_to_cpu (*data)) == 0) { 782e192b24SSimon Glass puts ("Empty Script\n"); 792e192b24SSimon Glass return 1; 802e192b24SSimon Glass } 812e192b24SSimon Glass 822e192b24SSimon Glass /* 832e192b24SSimon Glass * scripts are just multi-image files with one component, seek 842e192b24SSimon Glass * past the zero-terminated sequence of image lengths to get 852e192b24SSimon Glass * to the actual image data 862e192b24SSimon Glass */ 87*11a331d2SJoseph Chen while (*data++ != IMAGE_PARAM_INVAL); 882e192b24SSimon Glass break; 892e192b24SSimon Glass #endif 902e192b24SSimon Glass #if defined(CONFIG_FIT) 912e192b24SSimon Glass case IMAGE_FORMAT_FIT: 922e192b24SSimon Glass if (fit_uname == NULL) { 932e192b24SSimon Glass puts ("No FIT subimage unit name\n"); 942e192b24SSimon Glass return 1; 952e192b24SSimon Glass } 962e192b24SSimon Glass 972e192b24SSimon Glass fit_hdr = buf; 982e192b24SSimon Glass if (!fit_check_format (fit_hdr)) { 992e192b24SSimon Glass puts ("Bad FIT image format\n"); 1002e192b24SSimon Glass return 1; 1012e192b24SSimon Glass } 1022e192b24SSimon Glass 1032e192b24SSimon Glass /* get script component image node offset */ 1042e192b24SSimon Glass noffset = fit_image_get_node (fit_hdr, fit_uname); 1052e192b24SSimon Glass if (noffset < 0) { 1062e192b24SSimon Glass printf ("Can't find '%s' FIT subimage\n", fit_uname); 1072e192b24SSimon Glass return 1; 1082e192b24SSimon Glass } 1092e192b24SSimon Glass 1102e192b24SSimon Glass if (!fit_image_check_type (fit_hdr, noffset, IH_TYPE_SCRIPT)) { 1112e192b24SSimon Glass puts ("Not a image image\n"); 1122e192b24SSimon Glass return 1; 1132e192b24SSimon Glass } 1142e192b24SSimon Glass 1152e192b24SSimon Glass /* verify integrity */ 1162e192b24SSimon Glass if (verify) { 1172e192b24SSimon Glass if (!fit_image_verify(fit_hdr, noffset)) { 1182e192b24SSimon Glass puts ("Bad Data Hash\n"); 1192e192b24SSimon Glass return 1; 1202e192b24SSimon Glass } 1212e192b24SSimon Glass } 1222e192b24SSimon Glass 1232e192b24SSimon Glass /* get script subimage data address and length */ 1242e192b24SSimon Glass if (fit_image_get_data (fit_hdr, noffset, &fit_data, &fit_len)) { 1252e192b24SSimon Glass puts ("Could not find script subimage data\n"); 1262e192b24SSimon Glass return 1; 1272e192b24SSimon Glass } 1282e192b24SSimon Glass 1292e192b24SSimon Glass data = (u32 *)fit_data; 1302e192b24SSimon Glass len = (ulong)fit_len; 1312e192b24SSimon Glass break; 1322e192b24SSimon Glass #endif 1332e192b24SSimon Glass default: 1342e192b24SSimon Glass puts ("Wrong image format for \"source\" command\n"); 1352e192b24SSimon Glass return 1; 1362e192b24SSimon Glass } 1372e192b24SSimon Glass 1382e192b24SSimon Glass debug ("** Script length: %ld\n", len); 1392e192b24SSimon Glass return run_command_list((char *)data, len, 0); 1402e192b24SSimon Glass } 1412e192b24SSimon Glass 1422e192b24SSimon Glass /**************************************************/ 1432e192b24SSimon Glass #if defined(CONFIG_CMD_SOURCE) 1442e192b24SSimon Glass static int do_source(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 1452e192b24SSimon Glass { 1462e192b24SSimon Glass ulong addr; 1472e192b24SSimon Glass int rcode; 1482e192b24SSimon Glass const char *fit_uname = NULL; 1492e192b24SSimon Glass 1502e192b24SSimon Glass /* Find script image */ 1512e192b24SSimon Glass if (argc < 2) { 1522e192b24SSimon Glass addr = CONFIG_SYS_LOAD_ADDR; 1532e192b24SSimon Glass debug ("* source: default load address = 0x%08lx\n", addr); 1542e192b24SSimon Glass #if defined(CONFIG_FIT) 1552e192b24SSimon Glass } else if (fit_parse_subimage (argv[1], load_addr, &addr, &fit_uname)) { 1562e192b24SSimon Glass debug ("* source: subimage '%s' from FIT image at 0x%08lx\n", 1572e192b24SSimon Glass fit_uname, addr); 1582e192b24SSimon Glass #endif 1592e192b24SSimon Glass } else { 1602e192b24SSimon Glass addr = simple_strtoul(argv[1], NULL, 16); 1612e192b24SSimon Glass debug ("* source: cmdline image address = 0x%08lx\n", addr); 1622e192b24SSimon Glass } 1632e192b24SSimon Glass 1642e192b24SSimon Glass printf ("## Executing script at %08lx\n", addr); 1652e192b24SSimon Glass rcode = source (addr, fit_uname); 1662e192b24SSimon Glass return rcode; 1672e192b24SSimon Glass } 1682e192b24SSimon Glass 1692e192b24SSimon Glass #ifdef CONFIG_SYS_LONGHELP 1702e192b24SSimon Glass static char source_help_text[] = 1712e192b24SSimon Glass "[addr]\n" 1722e192b24SSimon Glass "\t- run script starting at addr\n" 1732e192b24SSimon Glass "\t- A valid image header must be present" 1742e192b24SSimon Glass #if defined(CONFIG_FIT) 1752e192b24SSimon Glass "\n" 1762e192b24SSimon Glass "For FIT format uImage addr must include subimage\n" 1772e192b24SSimon Glass "unit name in the form of addr:<subimg_uname>" 1782e192b24SSimon Glass #endif 1792e192b24SSimon Glass ""; 1802e192b24SSimon Glass #endif 1812e192b24SSimon Glass 1822e192b24SSimon Glass U_BOOT_CMD( 1832e192b24SSimon Glass source, 2, 0, do_source, 1842e192b24SSimon Glass "run script from memory", source_help_text 1852e192b24SSimon Glass ); 1862e192b24SSimon Glass #endif 187