From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54437) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V1EhF-0005GU-5K for qemu-devel@nongnu.org; Mon, 22 Jul 2013 07:54:41 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1V1Eh4-0001DG-EQ for qemu-devel@nongnu.org; Mon, 22 Jul 2013 07:54:33 -0400 Received: from 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.d.1.0.0.b.8.0.1.0.0.2.ip6.arpa ([2001:8b0:1d0::1]:58897 helo=mnementh.archaic.org.uk) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V1Eh4-0001CZ-5l for qemu-devel@nongnu.org; Mon, 22 Jul 2013 07:54:22 -0400 From: Peter Maydell Date: Mon, 22 Jul 2013 12:43:46 +0100 Message-Id: <1374493427-3254-10-git-send-email-peter.maydell@linaro.org> In-Reply-To: <1374493427-3254-1-git-send-email-peter.maydell@linaro.org> References: <1374493427-3254-1-git-send-email-peter.maydell@linaro.org> Subject: [Qemu-devel] [PULL 09/10] hw/loader: Support ramdisk with u-boot header List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Anthony Liguori Cc: qemu-devel@nongnu.org, Paul Brook From: Soren Brinkmann Introduce 'load_ramdisk()' which can load "normal" ramdisks and ramdisks with a u-boot header. To enable this and leverage synergies 'load_uimage()' is refactored to accomodate this additional use case. Signed-off-by: Soren Brinkmann Reviewed-by: Peter Maydell Message-id: 1373323202-17083-2-git-send-email-soren.brinkmann@xilinx.com Signed-off-by: Peter Maydell --- hw/core/loader.c | 84 ++++++++++++++++++++++++++++++++++++--------------- include/hw/loader.h | 13 ++++++++ 2 files changed, 72 insertions(+), 25 deletions(-) diff --git a/hw/core/loader.c b/hw/core/loader.c index 44311ff..c3c28cf 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -434,15 +434,17 @@ static ssize_t gunzip(void *dst, size_t dstlen, uint8_t *src, } /* Load a U-Boot image. */ -int load_uimage(const char *filename, hwaddr *ep, - hwaddr *loadaddr, int *is_linux) +static int load_uboot_image(const char *filename, hwaddr *ep, hwaddr *loadaddr, + int *is_linux, uint8_t image_type) { int fd; int size; + hwaddr address; uboot_image_header_t h; uboot_image_header_t *hdr = &h; uint8_t *data = NULL; int ret = -1; + int do_uncompress = 0; fd = open(filename, O_RDONLY | O_BINARY); if (fd < 0) @@ -457,32 +459,55 @@ int load_uimage(const char *filename, hwaddr *ep, if (hdr->ih_magic != IH_MAGIC) goto out; - /* TODO: Implement other image types. */ - if (hdr->ih_type != IH_TYPE_KERNEL) { - fprintf(stderr, "Can only load u-boot image type \"kernel\"\n"); + if (hdr->ih_type != image_type) { + fprintf(stderr, "Wrong image type %d, expected %d\n", hdr->ih_type, + image_type); goto out; } - switch (hdr->ih_comp) { - case IH_COMP_NONE: - case IH_COMP_GZIP: + /* TODO: Implement other image types. */ + switch (hdr->ih_type) { + case IH_TYPE_KERNEL: + address = hdr->ih_load; + if (loadaddr) { + *loadaddr = hdr->ih_load; + } + + switch (hdr->ih_comp) { + case IH_COMP_NONE: + break; + case IH_COMP_GZIP: + do_uncompress = 1; + break; + default: + fprintf(stderr, + "Unable to load u-boot images with compression type %d\n", + hdr->ih_comp); + goto out; + } + + if (ep) { + *ep = hdr->ih_ep; + } + + /* TODO: Check CPU type. */ + if (is_linux) { + if (hdr->ih_os == IH_OS_LINUX) { + *is_linux = 1; + } else { + *is_linux = 0; + } + } + + break; + case IH_TYPE_RAMDISK: + address = *loadaddr; break; default: - fprintf(stderr, - "Unable to load u-boot images with compression type %d\n", - hdr->ih_comp); + fprintf(stderr, "Unsupported u-boot image type %d\n", hdr->ih_type); goto out; } - /* TODO: Check CPU type. */ - if (is_linux) { - if (hdr->ih_os == IH_OS_LINUX) - *is_linux = 1; - else - *is_linux = 0; - } - - *ep = hdr->ih_ep; data = g_malloc(hdr->ih_size); if (read(fd, data, hdr->ih_size) != hdr->ih_size) { @@ -490,7 +515,7 @@ int load_uimage(const char *filename, hwaddr *ep, goto out; } - if (hdr->ih_comp == IH_COMP_GZIP) { + if (do_uncompress) { uint8_t *compressed_data; size_t max_bytes; ssize_t bytes; @@ -508,10 +533,7 @@ int load_uimage(const char *filename, hwaddr *ep, hdr->ih_size = bytes; } - rom_add_blob_fixed(filename, data, hdr->ih_size, hdr->ih_load); - - if (loadaddr) - *loadaddr = hdr->ih_load; + rom_add_blob_fixed(filename, data, hdr->ih_size, address); ret = hdr->ih_size; @@ -522,6 +544,18 @@ out: return ret; } +int load_uimage(const char *filename, hwaddr *ep, hwaddr *loadaddr, + int *is_linux) +{ + return load_uboot_image(filename, ep, loadaddr, is_linux, IH_TYPE_KERNEL); +} + +/* Load a ramdisk. */ +int load_ramdisk(const char *filename, hwaddr addr, uint64_t max_sz) +{ + return load_uboot_image(filename, NULL, &addr, NULL, IH_TYPE_RAMDISK); +} + /* * Functions for reboot-persistent memory regions. * - used for vga bios and option roms. diff --git a/include/hw/loader.h b/include/hw/loader.h index 15d4cc9..eb9c9a3 100644 --- a/include/hw/loader.h +++ b/include/hw/loader.h @@ -17,6 +17,19 @@ int load_aout(const char *filename, hwaddr addr, int max_sz, int load_uimage(const char *filename, hwaddr *ep, hwaddr *loadaddr, int *is_linux); +/** + * load_ramdisk: + * @filename: Path to the ramdisk image + * @addr: Memory address to load the ramdisk to + * @max_sz: Maximum allowed ramdisk size (for non-u-boot ramdisks) + * + * Load a ramdisk image with U-Boot header to the specified memory + * address. + * + * Returns the size of the loaded image on success, -1 otherwise. + */ +int load_ramdisk(const char *filename, hwaddr addr, uint64_t max_sz); + ssize_t read_targphys(const char *name, int fd, hwaddr dst_addr, size_t nbytes); void pstrcpy_targphys(const char *name, -- 1.7.9.5