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 return EXIT_FAILURE; 53 } 54 } 55 56 /* 57 * Only the simplest image type is currently supported: 58 * TOC pointing to CHSETTINGS 59 * TOC terminator 60 * CHSETTINGS 61 * 62 * padding to OMAP_CH_HDR_SIZE bytes 63 * 64 * gp header 65 * size 66 * load_addr 67 */ 68 static int valid_gph_size(uint32_t size) 69 { 70 return size; 71 } 72 73 static int valid_gph_load_addr(uint32_t load_addr) 74 { 75 return load_addr; 76 } 77 78 static int omapimage_verify_header(unsigned char *ptr, int image_size, 79 struct mkimage_params *params) 80 { 81 struct ch_toc *toc = (struct ch_toc *)ptr; 82 struct gp_header *gph = (struct gp_header *)(ptr+OMAP_CH_HDR_SIZE); 83 uint32_t offset, size; 84 85 while (toc->section_offset != 0xffffffff 86 && toc->section_size != 0xffffffff) { 87 offset = toc->section_offset; 88 size = toc->section_size; 89 if (!offset || !size) 90 return -1; 91 if (offset >= OMAP_CH_HDR_SIZE || 92 offset+size >= OMAP_CH_HDR_SIZE) 93 return -1; 94 toc++; 95 } 96 if (!valid_gph_size(gph->size)) 97 return -1; 98 if (!valid_gph_load_addr(gph->load_addr)) 99 return -1; 100 101 return 0; 102 } 103 104 static void omapimage_print_section(struct ch_settings *chs) 105 { 106 const char *section_name; 107 108 if (chs->section_key) 109 section_name = "CHSETTINGS"; 110 else 111 section_name = "UNKNOWNKEY"; 112 113 printf("%s (%x) " 114 "valid:%x " 115 "version:%x " 116 "reserved:%x " 117 "flags:%x\n", 118 section_name, 119 chs->section_key, 120 chs->valid, 121 chs->version, 122 chs->reserved, 123 chs->flags); 124 } 125 126 static void omapimage_print_header(const void *ptr) 127 { 128 const struct ch_toc *toc = (struct ch_toc *)ptr; 129 const struct gp_header *gph = 130 (struct gp_header *)(ptr+OMAP_CH_HDR_SIZE); 131 uint32_t offset, size; 132 133 while (toc->section_offset != 0xffffffff 134 && toc->section_size != 0xffffffff) { 135 offset = toc->section_offset; 136 size = toc->section_size; 137 138 if (offset >= OMAP_CH_HDR_SIZE || 139 offset+size >= OMAP_CH_HDR_SIZE) 140 exit(EXIT_FAILURE); 141 142 printf("Section %s offset %x length %x\n", 143 toc->section_name, 144 toc->section_offset, 145 toc->section_size); 146 147 omapimage_print_section((struct ch_settings *)(ptr+offset)); 148 toc++; 149 } 150 151 if (!valid_gph_size(gph->size)) { 152 fprintf(stderr, 153 "Error: invalid image size %x\n", 154 gph->size); 155 exit(EXIT_FAILURE); 156 } 157 158 if (!valid_gph_load_addr(gph->load_addr)) { 159 fprintf(stderr, 160 "Error: invalid image load address %x\n", 161 gph->size); 162 exit(EXIT_FAILURE); 163 } 164 165 printf("GP Header: Size %x LoadAddr %x\n", 166 gph->size, gph->load_addr); 167 } 168 169 static int toc_offset(void *hdr, void *member) 170 { 171 return member - hdr; 172 } 173 174 static void omapimage_set_header(void *ptr, struct stat *sbuf, int ifd, 175 struct mkimage_params *params) 176 { 177 struct ch_toc *toc = (struct ch_toc *)ptr; 178 struct ch_settings *chs = (struct ch_settings *) 179 (ptr + 2 * sizeof(*toc)); 180 struct gp_header *gph = (struct gp_header *)(ptr + OMAP_CH_HDR_SIZE); 181 182 toc->section_offset = toc_offset(ptr, chs); 183 toc->section_size = sizeof(struct ch_settings); 184 strcpy((char *)toc->section_name, "CHSETTINGS"); 185 186 chs->section_key = KEY_CHSETTINGS; 187 chs->valid = 0; 188 chs->version = 1; 189 chs->reserved = 0; 190 chs->flags = 0; 191 192 toc++; 193 memset(toc, 0xff, sizeof(*toc)); 194 195 gph->size = sbuf->st_size - OMAP_FILE_HDR_SIZE; 196 gph->load_addr = params->addr; 197 } 198 199 int omapimage_check_params(struct mkimage_params *params) 200 { 201 return (params->dflag && (params->fflag || params->lflag)) || 202 (params->fflag && (params->dflag || params->lflag)) || 203 (params->lflag && (params->dflag || params->fflag)); 204 } 205 206 /* 207 * omapimage parameters 208 */ 209 static struct image_type_params omapimage_params = { 210 .name = "TI OMAP CH/GP Boot Image support", 211 .header_size = OMAP_FILE_HDR_SIZE, 212 .hdr = (void *)&omapimage_header, 213 .check_image_type = omapimage_check_image_types, 214 .verify_header = omapimage_verify_header, 215 .print_header = omapimage_print_header, 216 .set_header = omapimage_set_header, 217 .check_params = omapimage_check_params, 218 }; 219 220 void init_omap_image_type(void) 221 { 222 mkimage_register(&omapimage_params); 223 } 224