uboot/tools/ublimage.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2011
   4 * Heiko Schocher, DENX Software Engineering, hs@denx.de.
   5 *
   6 * Based on:
   7 * (C) Copyright 2009
   8 * Stefano Babic, DENX Software Engineering, sbabic@denx.de.
   9 *
  10 * (C) Copyright 2008
  11 * Marvell Semiconductor <www.marvell.com>
  12 * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
  13 */
  14
  15#include "imagetool.h"
  16#include <image.h>
  17#include "ublimage.h"
  18
  19/*
  20 * Supported commands for configuration file
  21 */
  22static table_entry_t ublimage_cmds[] = {
  23        {CMD_BOOT_MODE, "MODE",         "UBL special modes", },
  24        {CMD_ENTRY,     "ENTRY",        "Entry point addr for bootloader", },
  25        {CMD_PAGE,      "PAGES",
  26                "number of pages (size of bootloader)", },
  27        {CMD_ST_BLOCK,  "START_BLOCK",
  28                "block number where bootloader is present", },
  29        {CMD_ST_PAGE,   "START_PAGE",
  30                "page number where bootloader is present", },
  31        {CMD_LD_ADDR,   "LD_ADDR",
  32                "load addr", },
  33        {-1,            "",             "", },
  34};
  35
  36/*
  37 * Supported Boot options for configuration file
  38 * this is needed to set the correct flash offset
  39 */
  40static table_entry_t ublimage_bootops[] = {
  41        {UBL_MAGIC_SAFE,        "safe", "Safe boot mode",       },
  42        {-1,                    "",     "Invalid",              },
  43};
  44
  45static struct ubl_header ublimage_header;
  46
  47static uint32_t get_cfg_value(char *token, char *name,  int linenr)
  48{
  49        char *endptr;
  50        uint32_t value;
  51
  52        errno = 0;
  53        value = strtoul(token, &endptr, 16);
  54        if (errno || (token == endptr)) {
  55                fprintf(stderr, "Error: %s[%d] - Invalid hex data(%s)\n",
  56                        name,  linenr, token);
  57                exit(EXIT_FAILURE);
  58        }
  59        return value;
  60}
  61
  62static void print_hdr(struct ubl_header *ubl_hdr)
  63{
  64        printf("Image Type : Davinci UBL Boot Image\n");
  65        printf("UBL magic  : %08x\n", ubl_hdr->magic);
  66        printf("Entry Point: %08x\n", ubl_hdr->entry);
  67        printf("nr of pages: %08x\n", ubl_hdr->pages);
  68        printf("start block: %08x\n", ubl_hdr->block);
  69        printf("start page : %08x\n", ubl_hdr->page);
  70}
  71
  72static void parse_cfg_cmd(struct ubl_header *ublhdr, int32_t cmd, char *token,
  73                                char *name, int lineno, int fld, int dcd_len)
  74{
  75        static int cmd_ver_first = ~0;
  76
  77        switch (cmd) {
  78        case CMD_BOOT_MODE:
  79                ublhdr->magic = get_table_entry_id(ublimage_bootops,
  80                                        "ublimage special boot mode", token);
  81                if (ublhdr->magic == -1) {
  82                        fprintf(stderr, "Error: %s[%d] -Invalid boot mode"
  83                                "(%s)\n", name, lineno, token);
  84                        exit(EXIT_FAILURE);
  85                }
  86                ublhdr->magic += UBL_MAGIC_BASE;
  87                if (unlikely(cmd_ver_first != 1))
  88                        cmd_ver_first = 0;
  89                break;
  90        case CMD_ENTRY:
  91                ublhdr->entry = get_cfg_value(token, name, lineno);
  92                break;
  93        case CMD_PAGE:
  94                ublhdr->pages = get_cfg_value(token, name, lineno);
  95                break;
  96        case CMD_ST_BLOCK:
  97                ublhdr->block = get_cfg_value(token, name, lineno);
  98                break;
  99        case CMD_ST_PAGE:
 100                ublhdr->page = get_cfg_value(token, name, lineno);
 101                break;
 102        case CMD_LD_ADDR:
 103                ublhdr->pll_m = get_cfg_value(token, name, lineno);
 104                break;
 105        }
 106}
 107
 108static void parse_cfg_fld(struct ubl_header *ublhdr, int32_t *cmd,
 109                char *token, char *name, int lineno, int fld, int *dcd_len)
 110{
 111
 112        switch (fld) {
 113        case CFG_COMMAND:
 114                *cmd = get_table_entry_id(ublimage_cmds,
 115                        "ublimage commands", token);
 116                if (*cmd < 0) {
 117                        fprintf(stderr, "Error: %s[%d] - Invalid command"
 118                        "(%s)\n", name, lineno, token);
 119                        exit(EXIT_FAILURE);
 120                }
 121                break;
 122        case CFG_REG_VALUE:
 123                parse_cfg_cmd(ublhdr, *cmd, token, name, lineno, fld, *dcd_len);
 124                break;
 125        default:
 126                break;
 127        }
 128}
 129static uint32_t parse_cfg_file(struct ubl_header *ublhdr, char *name)
 130{
 131        FILE *fd = NULL;
 132        char *line = NULL;
 133        char *token, *saveptr1, *saveptr2;
 134        int lineno = 0;
 135        int     i;
 136        char *ptr = (char *)ublhdr;
 137        int fld;
 138        size_t len;
 139        int dcd_len = 0;
 140        int32_t cmd;
 141        int ublhdrlen = sizeof(struct ubl_header);
 142
 143        fd = fopen(name, "r");
 144        if (fd == 0) {
 145                fprintf(stderr, "Error: %s - Can't open DCD file\n", name);
 146                exit(EXIT_FAILURE);
 147        }
 148
 149        /* Fill header with 0xff */
 150        for (i = 0; i < ublhdrlen; i++) {
 151                *ptr = 0xff;
 152                ptr++;
 153        }
 154
 155        /*
 156         * Very simple parsing, line starting with # are comments
 157         * and are dropped
 158         */
 159        while ((getline(&line, &len, fd)) > 0) {
 160                lineno++;
 161
 162                token = strtok_r(line, "\r\n", &saveptr1);
 163                if (token == NULL)
 164                        continue;
 165
 166                /* Check inside the single line */
 167                for (fld = CFG_COMMAND, cmd = CMD_INVALID,
 168                                line = token; ; line = NULL, fld++) {
 169                        token = strtok_r(line, " \t", &saveptr2);
 170                        if (token == NULL)
 171                                break;
 172
 173                        /* Drop all text starting with '#' as comments */
 174                        if (token[0] == '#')
 175                                break;
 176
 177                        parse_cfg_fld(ublhdr, &cmd, token, name,
 178                                        lineno, fld, &dcd_len);
 179                }
 180        }
 181        fclose(fd);
 182
 183        return dcd_len;
 184}
 185
 186static int ublimage_check_image_types(uint8_t type)
 187{
 188        if (type == IH_TYPE_UBLIMAGE)
 189                return EXIT_SUCCESS;
 190        else
 191                return EXIT_FAILURE;
 192}
 193
 194static int ublimage_verify_header(unsigned char *ptr, int image_size,
 195                        struct image_tool_params *params)
 196{
 197        struct ubl_header *ubl_hdr = (struct ubl_header *)ptr;
 198
 199        if ((ubl_hdr->magic & 0xFFFFFF00) != UBL_MAGIC_BASE)
 200                return -1;
 201
 202        return 0;
 203}
 204
 205static void ublimage_print_header(const void *ptr)
 206{
 207        struct ubl_header *ubl_hdr = (struct ubl_header *) ptr;
 208
 209        print_hdr(ubl_hdr);
 210}
 211
 212static void ublimage_set_header(void *ptr, struct stat *sbuf, int ifd,
 213                                struct image_tool_params *params)
 214{
 215        struct ubl_header *ublhdr = (struct ubl_header *)ptr;
 216
 217        /* Parse configuration file */
 218        parse_cfg_file(ublhdr, params->imagename);
 219}
 220
 221int ublimage_check_params(struct image_tool_params *params)
 222{
 223        if (!params)
 224                return CFG_INVALID;
 225        if (!strlen(params->imagename)) {
 226                fprintf(stderr, "Error: %s - Configuration file not"
 227                        "specified, it is needed for ublimage generation\n",
 228                        params->cmdname);
 229                return CFG_INVALID;
 230        }
 231        /*
 232         * Check parameters:
 233         * XIP is not allowed and verify that incompatible
 234         * parameters are not sent at the same time
 235         * For example, if list is required a data image must not be provided
 236         */
 237        return  (params->dflag && (params->fflag || params->lflag)) ||
 238                (params->fflag && (params->dflag || params->lflag)) ||
 239                (params->lflag && (params->dflag || params->fflag)) ||
 240                (params->xflag) || !(strlen(params->imagename));
 241}
 242
 243/*
 244 * ublimage parameters
 245 */
 246U_BOOT_IMAGE_TYPE(
 247        ublimage,
 248        "Davinci UBL boot support",
 249        sizeof(struct ubl_header),
 250        (void *)&ublimage_header,
 251        ublimage_check_params,
 252        ublimage_verify_header,
 253        ublimage_print_header,
 254        ublimage_set_header,
 255        NULL,
 256        ublimage_check_image_types,
 257        NULL,
 258        NULL
 259);
 260