2
0

loader.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543
  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@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. #include "qemu-common.h"
  46. #include "disas.h"
  47. #include "sysemu.h"
  48. #include "uboot_image.h"
  49. #include <zlib.h>
  50. /* return the size or -1 if error */
  51. int get_image_size(const char *filename)
  52. {
  53. int fd, size;
  54. fd = open(filename, O_RDONLY | O_BINARY);
  55. if (fd < 0)
  56. return -1;
  57. size = lseek(fd, 0, SEEK_END);
  58. close(fd);
  59. return size;
  60. }
  61. /* return the size or -1 if error */
  62. /* deprecated, because caller does not specify buffer size! */
  63. int load_image(const char *filename, uint8_t *addr)
  64. {
  65. int fd, size;
  66. fd = open(filename, O_RDONLY | O_BINARY);
  67. if (fd < 0)
  68. return -1;
  69. size = lseek(fd, 0, SEEK_END);
  70. lseek(fd, 0, SEEK_SET);
  71. if (read(fd, addr, size) != size) {
  72. close(fd);
  73. return -1;
  74. }
  75. close(fd);
  76. return size;
  77. }
  78. /* return the amount read, just like fread. 0 may mean error or eof */
  79. int fread_targphys(target_phys_addr_t dst_addr, size_t nbytes, FILE *f)
  80. {
  81. uint8_t buf[4096];
  82. target_phys_addr_t dst_begin = dst_addr;
  83. size_t want, did;
  84. while (nbytes) {
  85. want = nbytes > sizeof(buf) ? sizeof(buf) : nbytes;
  86. did = fread(buf, 1, want, f);
  87. cpu_physical_memory_write_rom(dst_addr, buf, did);
  88. dst_addr += did;
  89. nbytes -= did;
  90. if (did != want)
  91. break;
  92. }
  93. return dst_addr - dst_begin;
  94. }
  95. /* returns 0 on error, 1 if ok */
  96. int fread_targphys_ok(target_phys_addr_t dst_addr, size_t nbytes, FILE *f)
  97. {
  98. return fread_targphys(dst_addr, nbytes, f) == nbytes;
  99. }
  100. /* read()-like version */
  101. int read_targphys(int fd, target_phys_addr_t dst_addr, size_t nbytes)
  102. {
  103. uint8_t buf[4096];
  104. target_phys_addr_t dst_begin = dst_addr;
  105. size_t want, did;
  106. while (nbytes) {
  107. want = nbytes > sizeof(buf) ? sizeof(buf) : nbytes;
  108. did = read(fd, buf, want);
  109. if (did != want) break;
  110. cpu_physical_memory_write_rom(dst_addr, buf, did);
  111. dst_addr += did;
  112. nbytes -= did;
  113. }
  114. return dst_addr - dst_begin;
  115. }
  116. /* return the size or -1 if error */
  117. int load_image_targphys(const char *filename,
  118. target_phys_addr_t addr, int max_sz)
  119. {
  120. FILE *f;
  121. size_t got;
  122. f = fopen(filename, "rb");
  123. if (!f) return -1;
  124. got = fread_targphys(addr, max_sz, f);
  125. if (ferror(f)) { fclose(f); return -1; }
  126. fclose(f);
  127. return got;
  128. }
  129. void pstrcpy_targphys(target_phys_addr_t dest, int buf_size,
  130. const char *source)
  131. {
  132. static const uint8_t nul_byte = 0;
  133. const char *nulp;
  134. if (buf_size <= 0) return;
  135. nulp = memchr(source, 0, buf_size);
  136. if (nulp) {
  137. cpu_physical_memory_write_rom(dest, (uint8_t *)source,
  138. (nulp - source) + 1);
  139. } else {
  140. cpu_physical_memory_write_rom(dest, (uint8_t *)source, buf_size - 1);
  141. cpu_physical_memory_write_rom(dest, &nul_byte, 1);
  142. }
  143. }
  144. /* A.OUT loader */
  145. struct exec
  146. {
  147. uint32_t a_info; /* Use macros N_MAGIC, etc for access */
  148. uint32_t a_text; /* length of text, in bytes */
  149. uint32_t a_data; /* length of data, in bytes */
  150. uint32_t a_bss; /* length of uninitialized data area, in bytes */
  151. uint32_t a_syms; /* length of symbol table data in file, in bytes */
  152. uint32_t a_entry; /* start address */
  153. uint32_t a_trsize; /* length of relocation info for text, in bytes */
  154. uint32_t a_drsize; /* length of relocation info for data, in bytes */
  155. };
  156. #ifdef BSWAP_NEEDED
  157. static void bswap_ahdr(struct exec *e)
  158. {
  159. bswap32s(&e->a_info);
  160. bswap32s(&e->a_text);
  161. bswap32s(&e->a_data);
  162. bswap32s(&e->a_bss);
  163. bswap32s(&e->a_syms);
  164. bswap32s(&e->a_entry);
  165. bswap32s(&e->a_trsize);
  166. bswap32s(&e->a_drsize);
  167. }
  168. #else
  169. #define bswap_ahdr(x) do { } while (0)
  170. #endif
  171. #define N_MAGIC(exec) ((exec).a_info & 0xffff)
  172. #define OMAGIC 0407
  173. #define NMAGIC 0410
  174. #define ZMAGIC 0413
  175. #define QMAGIC 0314
  176. #define _N_HDROFF(x) (1024 - sizeof (struct exec))
  177. #define N_TXTOFF(x) \
  178. (N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) : \
  179. (N_MAGIC(x) == QMAGIC ? 0 : sizeof (struct exec)))
  180. #define N_TXTADDR(x) (N_MAGIC(x) == QMAGIC ? TARGET_PAGE_SIZE : 0)
  181. #define N_DATOFF(x) (N_TXTOFF(x) + (x).a_text)
  182. #define _N_SEGMENT_ROUND(x) (((x) + TARGET_PAGE_SIZE - 1) & ~(TARGET_PAGE_SIZE - 1))
  183. #define _N_TXTENDADDR(x) (N_TXTADDR(x)+(x).a_text)
  184. #define N_DATADDR(x) \
  185. (N_MAGIC(x)==OMAGIC? (_N_TXTENDADDR(x)) \
  186. : (_N_SEGMENT_ROUND (_N_TXTENDADDR(x))))
  187. int load_aout(const char *filename, target_phys_addr_t addr, int max_sz)
  188. {
  189. int fd, size, ret;
  190. struct exec e;
  191. uint32_t magic;
  192. fd = open(filename, O_RDONLY | O_BINARY);
  193. if (fd < 0)
  194. return -1;
  195. size = read(fd, &e, sizeof(e));
  196. if (size < 0)
  197. goto fail;
  198. bswap_ahdr(&e);
  199. magic = N_MAGIC(e);
  200. switch (magic) {
  201. case ZMAGIC:
  202. case QMAGIC:
  203. case OMAGIC:
  204. if (e.a_text + e.a_data > max_sz)
  205. goto fail;
  206. lseek(fd, N_TXTOFF(e), SEEK_SET);
  207. size = read_targphys(fd, addr, e.a_text + e.a_data);
  208. if (size < 0)
  209. goto fail;
  210. break;
  211. case NMAGIC:
  212. if (N_DATADDR(e) + e.a_data > max_sz)
  213. goto fail;
  214. lseek(fd, N_TXTOFF(e), SEEK_SET);
  215. size = read_targphys(fd, addr, e.a_text);
  216. if (size < 0)
  217. goto fail;
  218. ret = read_targphys(fd, addr + N_DATADDR(e), e.a_data);
  219. if (ret < 0)
  220. goto fail;
  221. size += ret;
  222. break;
  223. default:
  224. goto fail;
  225. }
  226. close(fd);
  227. return size;
  228. fail:
  229. close(fd);
  230. return -1;
  231. }
  232. /* ELF loader */
  233. static void *load_at(int fd, int offset, int size)
  234. {
  235. void *ptr;
  236. if (lseek(fd, offset, SEEK_SET) < 0)
  237. return NULL;
  238. ptr = qemu_malloc(size);
  239. if (read(fd, ptr, size) != size) {
  240. qemu_free(ptr);
  241. return NULL;
  242. }
  243. return ptr;
  244. }
  245. #define ELF_CLASS ELFCLASS32
  246. #include "elf.h"
  247. #define SZ 32
  248. #define elf_word uint32_t
  249. #define elf_sword int32_t
  250. #define bswapSZs bswap32s
  251. #include "elf_ops.h"
  252. #undef elfhdr
  253. #undef elf_phdr
  254. #undef elf_shdr
  255. #undef elf_sym
  256. #undef elf_note
  257. #undef elf_word
  258. #undef elf_sword
  259. #undef bswapSZs
  260. #undef SZ
  261. #define elfhdr elf64_hdr
  262. #define elf_phdr elf64_phdr
  263. #define elf_note elf64_note
  264. #define elf_shdr elf64_shdr
  265. #define elf_sym elf64_sym
  266. #define elf_word uint64_t
  267. #define elf_sword int64_t
  268. #define bswapSZs bswap64s
  269. #define SZ 64
  270. #include "elf_ops.h"
  271. /* return < 0 if error, otherwise the number of bytes loaded in memory */
  272. int load_elf(const char *filename, int64_t address_offset,
  273. uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr)
  274. {
  275. int fd, data_order, host_data_order, must_swab, ret;
  276. uint8_t e_ident[EI_NIDENT];
  277. fd = open(filename, O_RDONLY | O_BINARY);
  278. if (fd < 0) {
  279. perror(filename);
  280. return -1;
  281. }
  282. if (read(fd, e_ident, sizeof(e_ident)) != sizeof(e_ident))
  283. goto fail;
  284. if (e_ident[0] != ELFMAG0 ||
  285. e_ident[1] != ELFMAG1 ||
  286. e_ident[2] != ELFMAG2 ||
  287. e_ident[3] != ELFMAG3)
  288. goto fail;
  289. #ifdef WORDS_BIGENDIAN
  290. data_order = ELFDATA2MSB;
  291. #else
  292. data_order = ELFDATA2LSB;
  293. #endif
  294. must_swab = data_order != e_ident[EI_DATA];
  295. #ifdef TARGET_WORDS_BIGENDIAN
  296. host_data_order = ELFDATA2MSB;
  297. #else
  298. host_data_order = ELFDATA2LSB;
  299. #endif
  300. if (host_data_order != e_ident[EI_DATA])
  301. return -1;
  302. lseek(fd, 0, SEEK_SET);
  303. if (e_ident[EI_CLASS] == ELFCLASS64) {
  304. ret = load_elf64(fd, address_offset, must_swab, pentry,
  305. lowaddr, highaddr);
  306. } else {
  307. ret = load_elf32(fd, address_offset, must_swab, pentry,
  308. lowaddr, highaddr);
  309. }
  310. close(fd);
  311. return ret;
  312. fail:
  313. close(fd);
  314. return -1;
  315. }
  316. static void bswap_uboot_header(uboot_image_header_t *hdr)
  317. {
  318. #ifndef WORDS_BIGENDIAN
  319. bswap32s(&hdr->ih_magic);
  320. bswap32s(&hdr->ih_hcrc);
  321. bswap32s(&hdr->ih_time);
  322. bswap32s(&hdr->ih_size);
  323. bswap32s(&hdr->ih_load);
  324. bswap32s(&hdr->ih_ep);
  325. bswap32s(&hdr->ih_dcrc);
  326. #endif
  327. }
  328. #define ZALLOC_ALIGNMENT 16
  329. static void *zalloc(void *x, unsigned items, unsigned size)
  330. {
  331. void *p;
  332. size *= items;
  333. size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1);
  334. p = qemu_malloc(size);
  335. return (p);
  336. }
  337. static void zfree(void *x, void *addr)
  338. {
  339. qemu_free(addr);
  340. }
  341. #define HEAD_CRC 2
  342. #define EXTRA_FIELD 4
  343. #define ORIG_NAME 8
  344. #define COMMENT 0x10
  345. #define RESERVED 0xe0
  346. #define DEFLATED 8
  347. /* This is the maximum in uboot, so if a uImage overflows this, it would
  348. * overflow on real hardware too. */
  349. #define UBOOT_MAX_GUNZIP_BYTES 0x800000
  350. static ssize_t gunzip(void *dst, size_t dstlen, uint8_t *src,
  351. size_t srclen)
  352. {
  353. z_stream s;
  354. ssize_t dstbytes;
  355. int r, i, flags;
  356. /* skip header */
  357. i = 10;
  358. flags = src[3];
  359. if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
  360. puts ("Error: Bad gzipped data\n");
  361. return -1;
  362. }
  363. if ((flags & EXTRA_FIELD) != 0)
  364. i = 12 + src[10] + (src[11] << 8);
  365. if ((flags & ORIG_NAME) != 0)
  366. while (src[i++] != 0)
  367. ;
  368. if ((flags & COMMENT) != 0)
  369. while (src[i++] != 0)
  370. ;
  371. if ((flags & HEAD_CRC) != 0)
  372. i += 2;
  373. if (i >= srclen) {
  374. puts ("Error: gunzip out of data in header\n");
  375. return -1;
  376. }
  377. s.zalloc = zalloc;
  378. s.zfree = zfree;
  379. r = inflateInit2(&s, -MAX_WBITS);
  380. if (r != Z_OK) {
  381. printf ("Error: inflateInit2() returned %d\n", r);
  382. return (-1);
  383. }
  384. s.next_in = src + i;
  385. s.avail_in = srclen - i;
  386. s.next_out = dst;
  387. s.avail_out = dstlen;
  388. r = inflate(&s, Z_FINISH);
  389. if (r != Z_OK && r != Z_STREAM_END) {
  390. printf ("Error: inflate() returned %d\n", r);
  391. return -1;
  392. }
  393. dstbytes = s.next_out - (unsigned char *) dst;
  394. inflateEnd(&s);
  395. return dstbytes;
  396. }
  397. /* Load a U-Boot image. */
  398. int load_uimage(const char *filename, target_ulong *ep, target_ulong *loadaddr,
  399. int *is_linux)
  400. {
  401. int fd;
  402. int size;
  403. uboot_image_header_t h;
  404. uboot_image_header_t *hdr = &h;
  405. uint8_t *data = NULL;
  406. int ret = -1;
  407. fd = open(filename, O_RDONLY | O_BINARY);
  408. if (fd < 0)
  409. return -1;
  410. size = read(fd, hdr, sizeof(uboot_image_header_t));
  411. if (size < 0)
  412. goto out;
  413. bswap_uboot_header(hdr);
  414. if (hdr->ih_magic != IH_MAGIC)
  415. goto out;
  416. /* TODO: Implement other image types. */
  417. if (hdr->ih_type != IH_TYPE_KERNEL) {
  418. fprintf(stderr, "Can only load u-boot image type \"kernel\"\n");
  419. goto out;
  420. }
  421. switch (hdr->ih_comp) {
  422. case IH_COMP_NONE:
  423. case IH_COMP_GZIP:
  424. break;
  425. default:
  426. fprintf(stderr,
  427. "Unable to load u-boot images with compression type %d\n",
  428. hdr->ih_comp);
  429. goto out;
  430. }
  431. /* TODO: Check CPU type. */
  432. if (is_linux) {
  433. if (hdr->ih_os == IH_OS_LINUX)
  434. *is_linux = 1;
  435. else
  436. *is_linux = 0;
  437. }
  438. *ep = hdr->ih_ep;
  439. data = qemu_malloc(hdr->ih_size);
  440. if (read(fd, data, hdr->ih_size) != hdr->ih_size) {
  441. fprintf(stderr, "Error reading file\n");
  442. goto out;
  443. }
  444. if (hdr->ih_comp == IH_COMP_GZIP) {
  445. uint8_t *compressed_data;
  446. size_t max_bytes;
  447. ssize_t bytes;
  448. compressed_data = data;
  449. max_bytes = UBOOT_MAX_GUNZIP_BYTES;
  450. data = qemu_malloc(max_bytes);
  451. bytes = gunzip(data, max_bytes, compressed_data, hdr->ih_size);
  452. qemu_free(compressed_data);
  453. if (bytes < 0) {
  454. fprintf(stderr, "Unable to decompress gzipped image!\n");
  455. goto out;
  456. }
  457. hdr->ih_size = bytes;
  458. }
  459. cpu_physical_memory_write_rom(hdr->ih_load, data, hdr->ih_size);
  460. if (loadaddr)
  461. *loadaddr = hdr->ih_load;
  462. ret = hdr->ih_size;
  463. out:
  464. if (data)
  465. qemu_free(data);
  466. close(fd);
  467. return ret;
  468. }