int load_uimage(const char *filename, target_ulong *ep, target_ulong *loadaddr, int *is_linux) { int fd; int size; uboot_image_header_t h; uboot_image_header_t *hdr = &h; uint8_t *data = NULL; int ret = -1; fd = open(filename, O_RDONLY | O_BINARY); if (fd < 0) return -1; size = read(fd, hdr, sizeof(uboot_image_header_t)); if (size < 0) goto out; bswap_uboot_header(hdr); if (hdr->ih_magic != IH_MAGIC) goto out; /* TODO: Implement Multi-File images. */ if (hdr->ih_type == IH_TYPE_MULTI) { fprintf(stderr, "Unable to load multi-file u-boot images\n"); goto out; } switch (hdr->ih_comp) { case IH_COMP_NONE: case IH_COMP_GZIP: break; default: fprintf(stderr, "Unable to load u-boot images with compression type %d\n", hdr->ih_comp); goto out; } /* TODO: Check CPU type. */ if (is_linux) { if (hdr->ih_type == IH_TYPE_KERNEL && hdr->ih_os == IH_OS_LINUX) *is_linux = 1; else *is_linux = 0; } *ep = hdr->ih_ep; data = qemu_malloc(hdr->ih_size); if (!data) goto out; if (read(fd, data, hdr->ih_size) != hdr->ih_size) { fprintf(stderr, "Error reading file\n"); goto out; } if (hdr->ih_comp == IH_COMP_GZIP) { uint8_t *compressed_data; size_t max_bytes; ssize_t bytes; compressed_data = data; max_bytes = UBOOT_MAX_GUNZIP_BYTES; data = qemu_malloc(max_bytes); bytes = gunzip(data, max_bytes, compressed_data, hdr->ih_size); qemu_free(compressed_data); if (bytes < 0) { fprintf(stderr, "Unable to decompress gzipped image!\n"); goto out; } hdr->ih_size = bytes; } cpu_physical_memory_write_rom(hdr->ih_load, data, hdr->ih_size); if (loadaddr) *loadaddr = hdr->ih_load; ret = hdr->ih_size; out: if (data) qemu_free(data); close(fd); return ret; }