1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24: #include "qemu-common.h"
25: #include "disas.h"
26: #include "sysemu.h"
27: #include "uboot_image.h"
28:
29:
30: int get_image_size(const char *filename)
31: {
32: int fd, size;
33: fd = open(filename, O_RDONLY | O_BINARY);
34: if (fd < 0)
35: return -1;
36: size = lseek(fd, 0, SEEK_END);
37: close(fd);
38: return size;
39: }
40:
41:
42: int load_image(const char *filename, uint8_t *addr)
43: {
44: int fd, size;
45: fd = open(filename, O_RDONLY | O_BINARY);
46: if (fd < 0)
47: return -1;
48: size = lseek(fd, 0, SEEK_END);
49: lseek(fd, 0, SEEK_SET);
50: if (read(fd, addr, size) != size) {
51: close(fd);
52: return -1;
53: }
54: close(fd);
55: return size;
56: }
57:
58:
59:
60: struct exec
61: {
62: uint32_t a_info;
63: uint32_t a_text;
64: uint32_t a_data;
65: uint32_t a_bss;
66: uint32_t a_syms;
67: uint32_t a_entry;
68: uint32_t a_trsize;
69: uint32_t a_drsize;
70: };
71:
72: #ifdef BSWAP_NEEDED
73: static void bswap_ahdr(struct exec *e)
74: {
75: bswap32s(&e->a_info);
76: bswap32s(&e->a_text);
77: bswap32s(&e->a_data);
78: bswap32s(&e->a_bss);
79: bswap32s(&e->a_syms);
80: bswap32s(&e->a_entry);
81: bswap32s(&e->a_trsize);
82: bswap32s(&e->a_drsize);
83: }
84: #else
85: #define bswap_ahdr(x) do { } while (0)
86: #endif
87:
88: #define N_MAGIC(exec) ((exec).a_info & 0xffff)
89: #define OMAGIC 0407
90: #define NMAGIC 0410
91: #define ZMAGIC 0413
92: #define QMAGIC 0314
93: #define _N_HDROFF(x) (1024 - sizeof (struct exec))
94: #define N_TXTOFF(x) \
95: (N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) : \
96: (N_MAGIC(x) == QMAGIC ? 0 : sizeof (struct exec)))
97: #define N_TXTADDR(x) (N_MAGIC(x) == QMAGIC ? TARGET_PAGE_SIZE : 0)
98: #define N_DATOFF(x) (N_TXTOFF(x) + (x).a_text)
99: #define _N_SEGMENT_ROUND(x) (((x) + TARGET_PAGE_SIZE - 1) & ~(TARGET_PAGE_SIZE - 1))
100:
101: #define _N_TXTENDADDR(x) (N_TXTADDR(x)+(x).a_text)
102:
103: #define N_DATADDR(x) \
104: (N_MAGIC(x)==OMAGIC? (_N_TXTENDADDR(x)) \
105: : (_N_SEGMENT_ROUND (_N_TXTENDADDR(x))))
106:
107:
108: int load_aout(const char *filename, uint8_t *addr)
109: {
110: int fd, size, ret;
111: struct exec e;
112: uint32_t magic;
113:
114: fd = open(filename, O_RDONLY | O_BINARY);
115: if (fd < 0)
116: return -1;
117:
118: size = read(fd, &e, sizeof(e));
119: if (size < 0)
120: goto fail;
121:
122: bswap_ahdr(&e);
123:
124: magic = N_MAGIC(e);
125: switch (magic) {
126: case ZMAGIC:
127: case QMAGIC:
128: case OMAGIC:
129: lseek(fd, N_TXTOFF(e), SEEK_SET);
130: size = read(fd, addr, e.a_text + e.a_data);
131: if (size < 0)
132: goto fail;
133: break;
134: case NMAGIC:
135: lseek(fd, N_TXTOFF(e), SEEK_SET);
136: size = read(fd, addr, e.a_text);
137: if (size < 0)
138: goto fail;
139: ret = read(fd, addr + N_DATADDR(e), e.a_data);
140: if (ret < 0)
141: goto fail;
142: size += ret;
143: break;
144: default:
145: goto fail;
146: }
147: close(fd);
148: return size;
149: fail:
150: close(fd);
151: return -1;
152: }
153:
154:
155:
156: static void *load_at(int fd, int offset, int size)
157: {
158: void *ptr;
159: if (lseek(fd, offset, SEEK_SET) < 0)
160: return NULL;
161: ptr = qemu_malloc(size);
162: if (!ptr)
163: return NULL;
164: if (read(fd, ptr, size) != size) {
165: qemu_free(ptr);
166: return NULL;
167: }
168: return ptr;
169: }
170:
171:
172: #define ELF_CLASS ELFCLASS32
173: #include "elf.h"
174:
175: #define SZ 32
176: #define elf_word uint32_t
177: #define elf_sword int32_t
178: #define bswapSZs bswap32s
179: #include "elf_ops.h"
180:
181: #undef elfhdr
182: #undef elf_phdr
183: #undef elf_shdr
184: #undef elf_sym
185: #undef elf_note
186: #undef elf_word
187: #undef elf_sword
188: #undef bswapSZs
189: #undef SZ
190: #define elfhdr elf64_hdr
191: #define elf_phdr elf64_phdr
192: #define elf_note elf64_note
193: #define elf_shdr elf64_shdr
194: #define elf_sym elf64_sym
195: #define elf_word uint64_t
196: #define elf_sword int64_t
197: #define bswapSZs bswap64s
198: #define SZ 64
199: #include "elf_ops.h"
200:
201:
202: int load_elf(const char *filename, int64_t virt_to_phys_addend,
203: uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr)
204: {
205: int fd, data_order, host_data_order, must_swab, ret;
206: uint8_t e_ident[EI_NIDENT];
207:
208: fd = open(filename, O_RDONLY | O_BINARY);
209: if (fd < 0) {
210: perror(filename);
211: return -1;
212: }
213: if (read(fd, e_ident, sizeof(e_ident)) != sizeof(e_ident))
214: goto fail;
215: if (e_ident[0] != ELFMAG0 ||
216: e_ident[1] != ELFMAG1 ||
217: e_ident[2] != ELFMAG2 ||
218: e_ident[3] != ELFMAG3)
219: goto fail;
220: #ifdef WORDS_BIGENDIAN
221: data_order = ELFDATA2MSB;
222: #else
223: data_order = ELFDATA2LSB;
224: #endif
225: must_swab = data_order != e_ident[EI_DATA];
226:
227: #ifdef TARGET_WORDS_BIGENDIAN
228: host_data_order = ELFDATA2MSB;
229: #else
230: host_data_order = ELFDATA2LSB;
231: #endif
232: if (host_data_order != e_ident[EI_DATA])
233: return -1;
234:
235: lseek(fd, 0, SEEK_SET);
236: if (e_ident[EI_CLASS] == ELFCLASS64) {
237: ret = load_elf64(fd, virt_to_phys_addend, must_swab, pentry,
238: lowaddr, highaddr);
239: } else {
240: ret = load_elf32(fd, virt_to_phys_addend, must_swab, pentry,
241: lowaddr, highaddr);
242: }
243:
244: close(fd);
245: return ret;
246:
247: fail:
248: close(fd);
249: return -1;
250: }
251:
252: static void bswap_uboot_header(uboot_image_header_t *hdr)
253: {
254: #ifndef WORDS_BIGENDIAN
255: bswap32s(&hdr->ih_magic);
256: bswap32s(&hdr->ih_hcrc);
257: bswap32s(&hdr->ih_time);
258: bswap32s(&hdr->ih_size);
259: bswap32s(&hdr->ih_load);
260: bswap32s(&hdr->ih_ep);
261: bswap32s(&hdr->ih_dcrc);
262: #endif
263: }
264:
265:
266: int load_uboot(const char *filename, target_ulong *ep, int *is_linux)
267: {
268:
269: int fd;
270: int size;
271: uboot_image_header_t h;
272: uboot_image_header_t *hdr = &h;
273: uint8_t *data = NULL;
274:
275: fd = open(filename, O_RDONLY | O_BINARY);
276: if (fd < 0)
277: return -1;
278:
279: size = read(fd, hdr, sizeof(uboot_image_header_t));
280: if (size < 0)
281: goto fail;
282:
283: bswap_uboot_header(hdr);
284:
285: if (hdr->ih_magic != IH_MAGIC)
286: goto fail;
287:
288:
289: if (hdr->ih_type == IH_TYPE_MULTI) {
290: fprintf(stderr, "Unable to load multi-file u-boot images\n");
291: goto fail;
292: }
293:
294:
295: if (hdr->ih_comp != IH_COMP_NONE) {
296: fprintf(stderr, "Unable to load compressed u-boot images\n");
297: goto fail;
298: }
299:
300:
301: if (is_linux) {
302: if (hdr->ih_type == IH_TYPE_KERNEL && hdr->ih_os == IH_OS_LINUX)
303: *is_linux = 1;
304: else
305: *is_linux = 0;
306: }
307:
308: *ep = hdr->ih_ep;
309: data = qemu_malloc(hdr->ih_size);
310: if (!data)
311: goto fail;
312:
313: if (read(fd, data, hdr->ih_size) != hdr->ih_size) {
314: fprintf(stderr, "Error reading file\n");
315: goto fail;
316: }
317:
318: cpu_physical_memory_write_rom(hdr->ih_load, data, hdr->ih_size);
319:
320: return hdr->ih_size;
321:
322: fail:
323: if (data)
324: qemu_free(data);
325: close(fd);
326: return -1;
327: }