1 /* 2 * QEMU Executable loader 3 * 4 * Copyright (c) 2006 Fabrice Bellard 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 * THE SOFTWARE. 23 * 24 * Gunzip functionality in this file is derived from u-boot: 25 * 26 * (C) Copyright 2008 Semihalf 27 * 28 * (C) Copyright 2000-2005 29 * Wolfgang Denk, DENX Software Engineering, wd (at) denx.de. 30 * 31 * This program is free software; you can redistribute it and/or 32 * modify it under the terms of the GNU General Public License as 33 * published by the Free Software Foundation; either version 2 of 34 * the License, or (at your option) any later version. 35 * 36 * This program is distributed in the hope that it will be useful, 37 * but WITHOUT ANY WARRANTY; without even the implied warranty of 38 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 39 * GNU General Public License for more details. 40 * 41 * You should have received a copy of the GNU General Public License along 42 * with this program; if not, write to the Free Software Foundation, Inc., 43 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 44 */ 45 46 #include "qemu-common.h" 47 #include "disas/disas.h" 48 #include "sysemu/sysemu.h" 49 #include "uboot_image.h" 50 51 #include <zlib.h> 52 53 /* return the size or -1 if error */ 54 int get_image_size(const char *filename) 55 { 56 int fd, size; 57 fd = open(filename, O_RDONLY | O_BINARY); 58 if (fd < 0) 59 return -1; 60 size = lseek(fd, 0, SEEK_END); 61 close(fd); 62 return size; 63 } 64 65 /* return the size or -1 if error */ 66 /* deprecated, because caller does not specify buffer size! */ 67 int load_image(const char *filename, uint8_t *addr) 68 { 69 int fd, size; 70 fd = open(filename, O_RDONLY | O_BINARY); 71 if (fd < 0) 72 return -1; 73 size = lseek(fd, 0, SEEK_END); 74 lseek(fd, 0, SEEK_SET); 75 if (read(fd, addr, size) != size) { 76 close(fd); 77 return -1; 78 } 79 close(fd); 80 return size; 81 } 82 83 /* return the amount read, just like fread. 0 may mean error or eof */ 84 int fread_targphys(hwaddr dst_addr, size_t nbytes, FILE *f) 85 { 86 uint8_t buf[4096]; 87 hwaddr dst_begin = dst_addr; 88 size_t want, did; 89 90 while (nbytes) { 91 want = nbytes > sizeof(buf) ? sizeof(buf) : nbytes; 92 did = fread(buf, 1, want, f); 93 94 cpu_physical_memory_write_rom(dst_addr, buf, did); 95 dst_addr += did; 96 nbytes -= did; 97 if (did != want) 98 break; 99 } 100 return dst_addr - dst_begin; 101 } 102 103 /* returns 0 on error, 1 if ok */ 104 int fread_targphys_ok(hwaddr dst_addr, size_t nbytes, FILE *f) 105 { 106 return fread_targphys(dst_addr, nbytes, f) == nbytes; 107 } 108 109 /* read()-like version */ 110 int read_targphys(int fd, hwaddr dst_addr, size_t nbytes) 111 { 112 uint8_t buf[4096]; 113 hwaddr dst_begin = dst_addr; 114 size_t want, did; 115 116 while (nbytes) { 117 want = nbytes > sizeof(buf) ? sizeof(buf) : nbytes; 118 did = read(fd, buf, want); 119 if (did != want) break; 120 121 cpu_physical_memory_write_rom(dst_addr, buf, did); 122 dst_addr += did; 123 nbytes -= did; 124 } 125 return dst_addr - dst_begin; 126 } 127 128 /* return the size or -1 if error */ 129 int load_image_targphys(const char *filename, 130 hwaddr addr, int max_sz) 131 { 132 FILE *f; 133 size_t got; 134 135 f = fopen(filename, "rb"); 136 if (!f) return -1; 137 138 got = fread_targphys(addr, max_sz, f); 139 if (ferror(f)) { fclose(f); return -1; } 140 fclose(f); 141 142 return got; 143 } 144 145 void pstrcpy_targphys(const char* name, 146 hwaddr dest, int buf_size, 147 const char *source) 148 { 149 static const uint8_t nul_byte = 0; 150 const char *nulp; 151 152 if (buf_size <= 0) return; 153 nulp = memchr(source, 0, buf_size); 154 if (nulp) { 155 cpu_physical_memory_write_rom(dest, (uint8_t *)source, 156 (nulp - source) + 1); 157 } else { 158 cpu_physical_memory_write_rom(dest, (uint8_t *)source, buf_size - 1); 159 cpu_physical_memory_write_rom(dest, &nul_byte, 1); 160 } 161 } 162 163 /* A.OUT loader */ 164 165 struct exec 166 { 167 uint32_t a_info; /* Use macros N_MAGIC, etc for access */ 168 uint32_t a_text; /* length of text, in bytes */ 169 uint32_t a_data; /* length of data, in bytes */ 170 uint32_t a_bss; /* length of uninitialized data area, in bytes */ 171 uint32_t a_syms; /* length of symbol table data in file, in bytes */ 172 uint32_t a_entry; /* start address */ 173 uint32_t a_trsize; /* length of relocation info for text, in bytes */ 174 uint32_t a_drsize; /* length of relocation info for data, in bytes */ 175 }; 176 177 #ifdef BSWAP_NEEDED 178 static void bswap_ahdr(struct exec *e) 179 { 180 bswap32s(&e->a_info); 181 bswap32s(&e->a_text); 182 bswap32s(&e->a_data); 183 bswap32s(&e->a_bss); 184 bswap32s(&e->a_syms); 185 bswap32s(&e->a_entry); 186 bswap32s(&e->a_trsize); 187 bswap32s(&e->a_drsize); 188 } 189 #else 190 #define bswap_ahdr(x) do { } while (0) 191 #endif 192 193 #define N_MAGIC(exec) ((exec).a_info & 0xffff) 194 #define OMAGIC 0407 195 #define NMAGIC 0410 196 #define ZMAGIC 0413 197 #define QMAGIC 0314 198 #define _N_HDROFF(x) (1024 - sizeof (struct exec)) 199 #define N_TXTOFF(x) \ 200 (N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) : \ 201 (N_MAGIC(x) == QMAGIC ? 0 : sizeof (struct exec))) 202 #define N_TXTADDR(x) (N_MAGIC(x) == QMAGIC ? TARGET_PAGE_SIZE : 0) 203 #define _N_SEGMENT_ROUND(x) (((x) + TARGET_PAGE_SIZE - 1) & ~(TARGET_PAGE_SIZE - 1)) 204 205 #define _N_TXTENDADDR(x) (N_TXTADDR(x)+(x).a_text) 206 207 #define N_DATADDR(x) \ 208 (N_MAGIC(x)==OMAGIC? (_N_TXTENDADDR(x)) \ 209 : (_N_SEGMENT_ROUND (_N_TXTENDADDR(x)))) 210 211 212 int load_aout(const char *filename, hwaddr addr, int max_sz) 213 { 214 int fd, size, ret; 215 struct exec e; 216 uint32_t magic; 217 218 fd = open(filename, O_RDONLY | O_BINARY); 219 if (fd < 0) 220 return -1; 221 222 size = read(fd, &e, sizeof(e)); 223 if (size < 0) 224 goto fail; 225 226 bswap_ahdr(&e); 227 228 magic = N_MAGIC(e); 229 switch (magic) { 230 case ZMAGIC: 231 case QMAGIC: 232 case OMAGIC: 233 if (e.a_text + e.a_data > max_sz) 234 goto fail; 235 lseek(fd, N_TXTOFF(e), SEEK_SET); 236 size = read_targphys(fd, addr, e.a_text + e.a_data); 237 if (size < 0) 238 goto fail; 239 break; 240 case NMAGIC: 241 if (N_DATADDR(e) + e.a_data > max_sz) 242 goto fail; 243 lseek(fd, N_TXTOFF(e), SEEK_SET); 244 size = read_targphys(fd, addr, e.a_text); 245 if (size < 0) 246 goto fail; 247 ret = read_targphys(fd, addr + N_DATADDR(e), e.a_data); 248 if (ret < 0) 249 goto fail; 250 size += ret; 251 break; 252 default: 253 goto fail; 254 } 255 close(fd); 256 return size; 257 fail: 258 close(fd); 259 return -1; 260 } 261 262 /* ELF loader */ 263 264 static void *load_at(int fd, int offset, int size) 265 { 266 void *ptr; 267 if (lseek(fd, offset, SEEK_SET) < 0) 268 return NULL; 269 ptr = g_malloc(size); 270 if (read(fd, ptr, size) != size) { 271 g_free(ptr); 272 return NULL; 273 } 274 return ptr; 275 } 276 277 278 #define ELF_CLASS ELFCLASS32 279 #include "elf.h" 280 281 #define SZ 32 282 #define elf_word uint32_t 283 #define elf_sword int32_t 284 #define bswapSZs bswap32s 285 #include "hw/elf_ops.h" 286 287 #undef elfhdr 288 #undef elf_phdr 289 #undef elf_shdr 290 #undef elf_sym 291 #undef elf_note 292 #undef elf_word 293 #undef elf_sword 294 #undef bswapSZs 295 #undef SZ 296 #define elfhdr elf64_hdr 297 #define elf_phdr elf64_phdr 298 #define elf_note elf64_note 299 #define elf_shdr elf64_shdr 300 #define elf_sym elf64_sym 301 #define elf_word uint64_t 302 #define elf_sword int64_t 303 #define bswapSZs bswap64s 304 #define SZ 64 305 #include "hw/elf_ops.h" 306 307 /* return < 0 if error, otherwise the number of bytes loaded in memory */ 308 int load_elf(const char *filename, int64_t address_offset, 309 uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr) 310 { 311 int fd, data_order, host_data_order, must_swab, ret; 312 uint8_t e_ident[EI_NIDENT]; 313 314 fd = open(filename, O_RDONLY | O_BINARY); 315 if (fd < 0) { 316 perror(filename); 317 return -1; 318 } 319 if (read(fd, e_ident, sizeof(e_ident)) != sizeof(e_ident)) 320 goto fail; 321 if (e_ident[0] != ELFMAG0 || 322 e_ident[1] != ELFMAG1 || 323 e_ident[2] != ELFMAG2 || 324 e_ident[3] != ELFMAG3) 325 goto fail; 326 #ifdef HOST_WORDS_BIGENDIAN 327 data_order = ELFDATA2MSB; 328 #else 329 data_order = ELFDATA2LSB; 330 #endif 331 must_swab = data_order != e_ident[EI_DATA]; 332 333 #ifdef TARGET_WORDS_BIGENDIAN 334 host_data_order = ELFDATA2MSB; 335 #else 336 host_data_order = ELFDATA2LSB; 337 #endif 338 if (host_data_order != e_ident[EI_DATA]) 339 return -1; 340 341 lseek(fd, 0, SEEK_SET); 342 if (e_ident[EI_CLASS] == ELFCLASS64) { 343 ret = load_elf64(fd, address_offset, must_swab, pentry, 344 lowaddr, highaddr); 345 } else { 346 ret = load_elf32(fd, address_offset, must_swab, pentry, 347 lowaddr, highaddr); 348 } 349 350 close(fd); 351 return ret; 352 353 fail: 354 close(fd); 355 return -1; 356 } 357 358 static void bswap_uboot_header(uboot_image_header_t *hdr) 359 { 360 #ifndef HOST_WORDS_BIGENDIAN 361 bswap32s(&hdr->ih_magic); 362 bswap32s(&hdr->ih_hcrc); 363 bswap32s(&hdr->ih_time); 364 bswap32s(&hdr->ih_size); 365 bswap32s(&hdr->ih_load); 366 bswap32s(&hdr->ih_ep); 367 bswap32s(&hdr->ih_dcrc); 368 #endif 369 } 370 371 372 #define ZALLOC_ALIGNMENT 16 373 374 static void *zalloc(void *x, unsigned items, unsigned size) 375 { 376 void *p; 377 378 size *= items; 379 size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1); 380 381 p = g_malloc(size); 382 383 return (p); 384 } 385 386 static void zfree(void *x, void *addr) 387 { 388 g_free(addr); 389 } 390 391 392 #define HEAD_CRC 2 393 #define EXTRA_FIELD 4 394 #define ORIG_NAME 8 395 #define COMMENT 0x10 396 #define RESERVED 0xe0 397 398 #define DEFLATED 8 399 400 /* This is the maximum in uboot, so if a uImage overflows this, it would 401 * overflow on real hardware too. */ 402 #define UBOOT_MAX_GUNZIP_BYTES 0x800000 403 404 static ssize_t gunzip(void *dst, size_t dstlen, uint8_t *src, 405 size_t srclen) 406 { 407 z_stream s; 408 ssize_t dstbytes; 409 int r, i, flags; 410 411 /* skip header */ 412 i = 10; 413 flags = src[3]; 414 if (src[2] != DEFLATED || (flags & RESERVED) != 0) { 415 puts ("Error: Bad gzipped data\n"); 416 return -1; 417 } 418 if ((flags & EXTRA_FIELD) != 0) 419 i = 12 + src[10] + (src[11] << 8); 420 if ((flags & ORIG_NAME) != 0) 421 while (src[i++] != 0) 422 ; 423 if ((flags & COMMENT) != 0) 424 while (src[i++] != 0) 425 ; 426 if ((flags & HEAD_CRC) != 0) 427 i += 2; 428 if (i >= srclen) { 429 puts ("Error: gunzip out of data in header\n"); 430 return -1; 431 } 432 433 s.zalloc = zalloc; 434 s.zfree = zfree; 435 436 r = inflateInit2(&s, -MAX_WBITS); 437 if (r != Z_OK) { 438 printf ("Error: inflateInit2() returned %d\n", r); 439 return (-1); 440 } 441 s.next_in = src + i; 442 s.avail_in = srclen - i; 443 s.next_out = dst; 444 s.avail_out = dstlen; 445 r = inflate(&s, Z_FINISH); 446 if (r != Z_OK && r != Z_STREAM_END) { 447 printf ("Error: inflate() returned %d\n", r); 448 return -1; 449 } 450 dstbytes = s.next_out - (unsigned char *) dst; 451 inflateEnd(&s); 452 453 return dstbytes; 454 } 455 456 /* Load a U-Boot image. */ 457 int load_uimage(const char *filename, target_ulong *ep, target_ulong *loadaddr, 458 int *is_linux) 459 { 460 int fd; 461 int size; 462 uboot_image_header_t h; 463 uboot_image_header_t *hdr = &h; 464 uint8_t *data = NULL; 465 int ret = -1; 466 467 fd = open(filename, O_RDONLY | O_BINARY); 468 if (fd < 0) 469 return -1; 470 471 size = read(fd, hdr, sizeof(uboot_image_header_t)); 472 if (size < 0) 473 goto out; 474 475 bswap_uboot_header(hdr); 476 477 if (hdr->ih_magic != IH_MAGIC) 478 goto out; 479 480 /* TODO: Implement other image types. */ 481 if (hdr->ih_type != IH_TYPE_KERNEL) { 482 fprintf(stderr, "Can only load u-boot image type \"kernel\"\n"); 483 goto out; 484 } 485 486 switch (hdr->ih_comp) { 487 case IH_COMP_NONE: 488 case IH_COMP_GZIP: 489 break; 490 default: 491 fprintf(stderr, 492 "Unable to load u-boot images with compression type %d\n", 493 hdr->ih_comp); 494 goto out; 495 } 496 497 /* TODO: Check CPU type. */ 498 if (is_linux) { 499 if (hdr->ih_os == IH_OS_LINUX) 500 *is_linux = 1; 501 else 502 *is_linux = 0; 503 } 504 505 *ep = hdr->ih_ep; 506 data = g_malloc(hdr->ih_size); 507 508 if (read(fd, data, hdr->ih_size) != hdr->ih_size) { 509 fprintf(stderr, "Error reading file\n"); 510 goto out; 511 } 512 513 if (hdr->ih_comp == IH_COMP_GZIP) { 514 uint8_t *compressed_data; 515 size_t max_bytes; 516 ssize_t bytes; 517 518 compressed_data = data; 519 max_bytes = UBOOT_MAX_GUNZIP_BYTES; 520 data = g_malloc(max_bytes); 521 522 bytes = gunzip(data, max_bytes, compressed_data, hdr->ih_size); 523 g_free(compressed_data); 524 if (bytes < 0) { 525 fprintf(stderr, "Unable to decompress gzipped image!\n"); 526 goto out; 527 } 528 hdr->ih_size = bytes; 529 } 530 531 cpu_physical_memory_write_rom(hdr->ih_load, data, hdr->ih_size); 532 533 if (loadaddr) 534 *loadaddr = hdr->ih_load; 535 536 ret = hdr->ih_size; 537 538 out: 539 if (data) 540 g_free(data); 541 close(fd); 542 return ret; 543 } 544