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