1 /* 2 * (C) Copyright 2010 3 * Linaro LTD, www.linaro.org 4 * Author: John Rigby <john.rigby@linaro.org> 5 * Based on TI's signGP.c 6 * 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 * See file CREDITS for list of people who contributed to this 15 * project. 16 * 17 * This program is free software; you can redistribute it and/or 18 * modify it under the terms of the GNU General Public License as 19 * published by the Free Software Foundation; either version 2 of 20 * the License, or (at your option) any later version. 21 * 22 * This program is distributed in the hope that it will be useful, 23 * but WITHOUT ANY WARRANTY; without even the implied warranty of 24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25 * GNU General Public License for more details. 26 * 27 * You should have received a copy of the GNU General Public License 28 * along with this program; if not, write to the Free Software 29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 30 * MA 02111-1307 USA 31 */ 32 33 /* Required to obtain the getline prototype from stdio.h */ 34 #define _GNU_SOURCE 35 36 #include "mkimage.h" 37 #include <image.h> 38 #include "omapimage.h" 39 40 /* Header size is CH header rounded up to 512 bytes plus GP header */ 41 #define OMAP_CH_HDR_SIZE 512 42 #define OMAP_GP_HDR_SIZE (sizeof(struct gp_header)) 43 #define OMAP_FILE_HDR_SIZE (OMAP_CH_HDR_SIZE+OMAP_GP_HDR_SIZE) 44 45 static uint8_t omapimage_header[OMAP_FILE_HDR_SIZE]; 46 47 static int omapimage_check_image_types(uint8_t type) 48 { 49 if (type == IH_TYPE_OMAPIMAGE) 50 return EXIT_SUCCESS; 51 else { 52 fprintf(stderr, "Unknown OMAP image type - %x", type); 53 return EXIT_FAILURE; 54 } 55 } 56 57 /* 58 * Only the simplest image type is currently supported: 59 * TOC pointing to CHSETTINGS 60 * TOC terminator 61 * CHSETTINGS 62 * 63 * padding to OMAP_CH_HDR_SIZE bytes 64 * 65 * gp header 66 * size 67 * load_addr 68 */ 69 static int valid_gph_size(uint32_t size) 70 { 71 return size; 72 } 73 74 static int valid_gph_load_addr(uint32_t load_addr) 75 { 76 return load_addr; 77 } 78 79 static int omapimage_verify_header(unsigned char *ptr, int image_size, 80 struct mkimage_params *params) 81 { 82 struct ch_toc *toc = (struct ch_toc *)ptr; 83 struct gp_header *gph = (struct gp_header *)(ptr+OMAP_CH_HDR_SIZE); 84 uint32_t offset, size; 85 86 while (toc->section_offset != 0xffffffff 87 && toc->section_size != 0xffffffff) { 88 offset = toc->section_offset; 89 size = toc->section_size; 90 if (!offset || !size) 91 return -1; 92 if (offset >= OMAP_CH_HDR_SIZE || 93 offset+size >= OMAP_CH_HDR_SIZE) 94 return -1; 95 toc++; 96 } 97 if (!valid_gph_size(gph->size)) 98 return -1; 99 if (!valid_gph_load_addr(gph->load_addr)) 100 return -1; 101 102 return 0; 103 } 104 105 static void omapimage_print_section(struct ch_settings *chs) 106 { 107 const char *section_name; 108 109 if (chs->section_key) 110 section_name = "CHSETTINGS"; 111 else 112 section_name = "UNKNOWNKEY"; 113 114 printf("%s (%x) " 115 "valid:%x " 116 "version:%x " 117 "reserved:%x " 118 "flags:%x\n", 119 section_name, 120 chs->section_key, 121 chs->valid, 122 chs->version, 123 chs->reserved, 124 chs->flags); 125 } 126 127 static void omapimage_print_header(const void *ptr) 128 { 129 const struct ch_toc *toc = (struct ch_toc *)ptr; 130 const struct gp_header *gph = 131 (struct gp_header *)(ptr+OMAP_CH_HDR_SIZE); 132 uint32_t offset, size; 133 134 while (toc->section_offset != 0xffffffff 135 && toc->section_size != 0xffffffff) { 136 offset = toc->section_offset; 137 size = toc->section_size; 138 139 if (offset >= OMAP_CH_HDR_SIZE || 140 offset+size >= OMAP_CH_HDR_SIZE) 141 exit(EXIT_FAILURE); 142 143 printf("Section %s offset %x length %x\n", 144 toc->section_name, 145 toc->section_offset, 146 toc->section_size); 147 148 omapimage_print_section((struct ch_settings *)(ptr+offset)); 149 toc++; 150 } 151 152 if (!valid_gph_size(gph->size)) { 153 fprintf(stderr, 154 "Error: invalid image size %x\n", 155 gph->size); 156 exit(EXIT_FAILURE); 157 } 158 159 if (!valid_gph_load_addr(gph->load_addr)) { 160 fprintf(stderr, 161 "Error: invalid image load address %x\n", 162 gph->size); 163 exit(EXIT_FAILURE); 164 } 165 166 printf("GP Header: Size %x LoadAddr %x\n", 167 gph->size, gph->load_addr); 168 } 169 170 static int toc_offset(void *hdr, void *member) 171 { 172 return member - hdr; 173 } 174 175 static void omapimage_set_header(void *ptr, struct stat *sbuf, int ifd, 176 struct mkimage_params *params) 177 { 178 struct ch_toc *toc = (struct ch_toc *)ptr; 179 struct ch_settings *chs = (struct ch_settings *) 180 (ptr + 2 * sizeof(*toc)); 181 struct gp_header *gph = (struct gp_header *)(ptr + OMAP_CH_HDR_SIZE); 182 183 toc->section_offset = toc_offset(ptr, chs); 184 toc->section_size = sizeof(struct ch_settings); 185 strcpy((char *)toc->section_name, "CHSETTINGS"); 186 187 chs->section_key = KEY_CHSETTINGS; 188 chs->valid = 0; 189 chs->version = 1; 190 chs->reserved = 0; 191 chs->flags = 0; 192 193 toc++; 194 memset(toc, 0xff, sizeof(*toc)); 195 196 gph->size = sbuf->st_size - OMAP_FILE_HDR_SIZE; 197 gph->load_addr = params->addr; 198 } 199 200 int omapimage_check_params(struct mkimage_params *params) 201 { 202 return (params->dflag && (params->fflag || params->lflag)) || 203 (params->fflag && (params->dflag || params->lflag)) || 204 (params->lflag && (params->dflag || params->fflag)); 205 } 206 207 /* 208 * omapimage parameters 209 */ 210 static struct image_type_params omapimage_params = { 211 .name = "TI OMAP CH/GP Boot Image support", 212 .header_size = OMAP_FILE_HDR_SIZE, 213 .hdr = (void *)&omapimage_header, 214 .check_image_type = omapimage_check_image_types, 215 .verify_header = omapimage_verify_header, 216 .print_header = omapimage_print_header, 217 .set_header = omapimage_set_header, 218 .check_params = omapimage_check_params, 219 }; 220 221 void init_omap_image_type(void) 222 { 223 mkimage_register(&omapimage_params); 224 } 225