hw/loader: Support ramdisk with u-boot header

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 <soren.brinkmann@xilinx.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1373323202-17083-2-git-send-email-soren.brinkmann@xilinx.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Soren Brinkmann 2013-07-08 15:40:01 -07:00 committed by Peter Maydell
parent c8a07b355d
commit 84aee0deae
2 changed files with 72 additions and 25 deletions

View File

@ -434,15 +434,17 @@ static ssize_t gunzip(void *dst, size_t dstlen, uint8_t *src,
} }
/* Load a U-Boot image. */ /* Load a U-Boot image. */
int load_uimage(const char *filename, hwaddr *ep, static int load_uboot_image(const char *filename, hwaddr *ep, hwaddr *loadaddr,
hwaddr *loadaddr, int *is_linux) int *is_linux, uint8_t image_type)
{ {
int fd; int fd;
int size; int size;
hwaddr address;
uboot_image_header_t h; uboot_image_header_t h;
uboot_image_header_t *hdr = &h; uboot_image_header_t *hdr = &h;
uint8_t *data = NULL; uint8_t *data = NULL;
int ret = -1; int ret = -1;
int do_uncompress = 0;
fd = open(filename, O_RDONLY | O_BINARY); fd = open(filename, O_RDONLY | O_BINARY);
if (fd < 0) if (fd < 0)
@ -457,15 +459,25 @@ int load_uimage(const char *filename, hwaddr *ep,
if (hdr->ih_magic != IH_MAGIC) if (hdr->ih_magic != IH_MAGIC)
goto out; goto out;
/* TODO: Implement other image types. */ if (hdr->ih_type != image_type) {
if (hdr->ih_type != IH_TYPE_KERNEL) { fprintf(stderr, "Wrong image type %d, expected %d\n", hdr->ih_type,
fprintf(stderr, "Can only load u-boot image type \"kernel\"\n"); image_type);
goto out; goto out;
} }
/* 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) { switch (hdr->ih_comp) {
case IH_COMP_NONE: case IH_COMP_NONE:
break;
case IH_COMP_GZIP: case IH_COMP_GZIP:
do_uncompress = 1;
break; break;
default: default:
fprintf(stderr, fprintf(stderr,
@ -474,15 +486,28 @@ int load_uimage(const char *filename, hwaddr *ep,
goto out; goto out;
} }
/* TODO: Check CPU type. */ if (ep) {
if (is_linux) { *ep = hdr->ih_ep;
if (hdr->ih_os == IH_OS_LINUX) }
*is_linux = 1;
else /* TODO: Check CPU type. */
*is_linux = 0; 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, "Unsupported u-boot image type %d\n", hdr->ih_type);
goto out;
} }
*ep = hdr->ih_ep;
data = g_malloc(hdr->ih_size); data = g_malloc(hdr->ih_size);
if (read(fd, data, hdr->ih_size) != 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; goto out;
} }
if (hdr->ih_comp == IH_COMP_GZIP) { if (do_uncompress) {
uint8_t *compressed_data; uint8_t *compressed_data;
size_t max_bytes; size_t max_bytes;
ssize_t bytes; ssize_t bytes;
@ -508,10 +533,7 @@ int load_uimage(const char *filename, hwaddr *ep,
hdr->ih_size = bytes; hdr->ih_size = bytes;
} }
rom_add_blob_fixed(filename, data, hdr->ih_size, hdr->ih_load); rom_add_blob_fixed(filename, data, hdr->ih_size, address);
if (loadaddr)
*loadaddr = hdr->ih_load;
ret = hdr->ih_size; ret = hdr->ih_size;
@ -522,6 +544,18 @@ out:
return ret; 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. * Functions for reboot-persistent memory regions.
* - used for vga bios and option roms. * - used for vga bios and option roms.

View File

@ -17,6 +17,19 @@ int load_aout(const char *filename, hwaddr addr, int max_sz,
int load_uimage(const char *filename, hwaddr *ep, int load_uimage(const char *filename, hwaddr *ep,
hwaddr *loadaddr, int *is_linux); 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, ssize_t read_targphys(const char *name,
int fd, hwaddr dst_addr, size_t nbytes); int fd, hwaddr dst_addr, size_t nbytes);
void pstrcpy_targphys(const char *name, void pstrcpy_targphys(const char *name,