Commit 84aee0de authored by Soren Brinkmann's avatar Soren Brinkmann Committed by Peter Maydell
Browse files

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: default avatarSoren Brinkmann <soren.brinkmann@xilinx.com>
Reviewed-by: default avatarPeter Maydell <peter.maydell@linaro.org>
Message-id: 1373323202-17083-2-git-send-email-soren.brinkmann@xilinx.com
Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parent c8a07b35
Loading
Loading
Loading
Loading
+59 −25
Original line number Diff line number Diff line
@@ -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,15 +459,25 @@ 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;
    }

    /* 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,
@@ -474,15 +486,28 @@ int load_uimage(const char *filename, hwaddr *ep,
            goto out;
        }

        if (ep) {
            *ep = hdr->ih_ep;
        }

        /* TODO: Check CPU type.  */
        if (is_linux) {
        if (hdr->ih_os == IH_OS_LINUX)
            if (hdr->ih_os == IH_OS_LINUX) {
                *is_linux = 1;
        else
            } 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);

    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.
+13 −0
Original line number Diff line number Diff line
@@ -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,