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