[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v4] xen/tools: Introduce QNX IFS loader
On Wed, Sep 24, 2014 at 6:43 PM, Oleksandr Tyshchenko <oleksandr.tyshchenko@xxxxxxxxxxxxxxx> wrote: > This patch was developed according to instruction: > http://www.qnx.com/developers/docs/6.4.1/neutrino/building/load_process.html > > Add ability to load QNX IFS image. The loader probe function > based on "Writing an IPL Program" howto from qnx.com > and performs image validation and startup entry point location. > Because of the fact that the image is already in place some > customizations have been done. Also in case of multiple images > (very seldom case) only the first image will be loaded. > > There are some restrictions: > 1. The base address of the image (image attribute) and the location > of RAM in system must be synchronized with RAM base address in Xen. > 2. The QNX IFS image must be created as a simple binary image. > > Signed-off-by: Oleksandr Tyshchenko <oleksandr.tyshchenko@xxxxxxxxxxxxxxx> Acked-by: Andrii Tseglytskyi <andrii.tseglytskyi@xxxxxxxxxxxxxxx> > Cc: Ian Campbell <ian.campbell@xxxxxxxxxx> > Cc: Julien Grall <julien.grall@xxxxxxxxxx> > --- > tools/libxc/Makefile | 1 + > tools/libxc/xc_dom_qnxifsloader.c | 228 > ++++++++++++++++++++++++++++++++++++++ > 2 files changed, 229 insertions(+) > create mode 100644 tools/libxc/xc_dom_qnxifsloader.c > > diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile > index 2cca2b2..1462f53 100644 > --- a/tools/libxc/Makefile > +++ b/tools/libxc/Makefile > @@ -66,6 +66,7 @@ GUEST_SRCS-y += xc_dom_elfloader.c > GUEST_SRCS-$(CONFIG_X86) += xc_dom_bzimageloader.c > GUEST_SRCS-$(CONFIG_X86) += xc_dom_decompress_lz4.c > GUEST_SRCS-$(CONFIG_ARM) += xc_dom_armzimageloader.c > +GUEST_SRCS-$(CONFIG_ARM) += xc_dom_qnxifsloader.c > GUEST_SRCS-y += xc_dom_binloader.c > GUEST_SRCS-y += xc_dom_compat_linux.c > > diff --git a/tools/libxc/xc_dom_qnxifsloader.c > b/tools/libxc/xc_dom_qnxifsloader.c > new file mode 100644 > index 0000000..8b03885 > --- /dev/null > +++ b/tools/libxc/xc_dom_qnxifsloader.c > @@ -0,0 +1,228 @@ > +/* > + * Xen domain builder -- QNX IFS bits > + * > + * Parse and load QNX IFS image. > + * > + * Copyright (C) 2014, Globallogic. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 > USA > + * > + */ > + > +#include <stdio.h> > +#include <stdlib.h> > +#include <inttypes.h> > + > +#include "xg_private.h" > +#include "xc_dom.h" > + > +struct startup_header { > + uint32_t signature; /* Header sig */ > + uint16_t version; /* Header vers */ > + uint8_t flags1; /* Misc flags */ > + uint8_t flags2; /* No flags defined yet */ > + uint16_t header_size; /* sizeof(struct startup_header) */ > + uint16_t machine; /* Machine type */ > + uint32_t startup_vaddr; /* Virtual Address to transfer */ > + /* to after IPL is done */ > + uint32_t paddr_bias; /* Value to add to physical address */ > + /* to get a value to put into a */ > + /* pointer and indirected through */ > + uint32_t image_paddr; /* Physical address of image */ > + uint32_t ram_paddr; /* Physical address of RAM to copy */ > + /* image to (startup_size bytes copied) */ > + uint32_t ram_size; /* Amount of RAM used by the startup */ > + /* program and executables contained */ > + /* in the file system */ > + uint32_t startup_size; /* Size of startup (never compressed) */ > + uint32_t stored_size; /* Size of entire image */ > + uint32_t imagefs_paddr; /* Set by IPL to where the imagefs is */ > + /* when startup runs */ > + uint32_t imagefs_size; /* Size of uncompressed imagefs */ > + uint16_t preboot_size; /* Size of loaded before header */ > + uint16_t zero0; /* Zeros */ > + uint32_t zero[3]; /* Zeros */ > + uint32_t info[48]; /* Array of startup_info* structures */ > +}; > + > +#define STARTUP_HDR_SIGNATURE 0x00ff7eeb > + > +static int calc_checksum(uint32_t *ptr, uint32_t size) > +{ > + int sum = 0; > + > + while ( size > 0 ) > + { > + sum += *ptr++; > + size -= 4; > + } > + > + return sum; > +} > + > +static int xc_dom_probe_qnx_ifs(struct xc_dom_image *dom) > +{ > + struct startup_header *startup_hdr; > + > + if ( dom->kernel_blob == NULL ) > + { > + xc_dom_panic(dom->xch, XC_INTERNAL_ERROR, > + "%s: no QNX IFS loaded", __FUNCTION__); > + return -EINVAL; > + } > + > + /* Performs a preliminary checks for a valid image size */ > + if ( dom->kernel_size < sizeof(struct startup_header) ) > + { > + xc_dom_printf(dom->xch, "%s: QNX IFS is too small", __FUNCTION__); > + return -EINVAL; > + } > + > + /* > + * Performs a check for a valid OS signature. We assume that nothing > + * preceded by startup header because we expect a simple binary image. > + */ > + startup_hdr = (struct startup_header *)dom->kernel_blob; > + if ( (startup_hdr->signature != STARTUP_HDR_SIGNATURE) || > + (startup_hdr->preboot_size != 0) ) > + { > + xc_dom_printf(dom->xch, "%s: image is not a QNX IFS", __FUNCTION__); > + return -EINVAL; > + } > + > + /* Performs a check for a valid startup header size */ > + if ( startup_hdr->header_size != sizeof(struct startup_header) ) > + { > + xc_dom_printf(dom->xch, "%s: QNX IFS has wrong startup header size", > __FUNCTION__); > + return -EINVAL; > + } > + > + /* Performs a check for a valid stored size */ > + if ( startup_hdr->stored_size != dom->kernel_size ) > + { > + xc_dom_printf(dom->xch, "%s: QNX IFS has wrong stored size", > __FUNCTION__); > + return -EINVAL; > + } > + > + /* Performs a check for a valid startup size */ > + if ( startup_hdr->startup_size >= startup_hdr->stored_size ) > + { > + xc_dom_printf(dom->xch, "%s: QNX IFS has wrong startup size", > __FUNCTION__); > + return -EINVAL; > + } > + > + /* Performs a checksums on the startup and the OS image filesystem */ > + if ( (calc_checksum((uint32_t *)startup_hdr, startup_hdr->startup_size) > != 0) || > + (calc_checksum((uint32_t *)startup_hdr + > startup_hdr->startup_size/4, > + startup_hdr->stored_size - startup_hdr->startup_size) != 0) ) > + { > + xc_dom_printf(dom->xch, "%s: QNX IFS has wrong checksum", > __FUNCTION__); > + return -EINVAL; > + } > + > + return 0; > +} > + > +static int xc_dom_parse_qnx_ifs(struct xc_dom_image *dom) > +{ > + struct startup_header *startup_hdr; > + uint64_t v_start, v_end; > + uint64_t rambase = dom->rambase_pfn << XC_PAGE_SHIFT; > + > + DOMPRINTF_CALLED(dom->xch); > + > + /* Do not load kernel at the very first RAM address */ > + v_start = rambase + 0x8000; > + > + if ( dom->kernel_size > UINT64_MAX - v_start ) > + { > + xc_dom_printf(dom->xch, "%s: QNX IFS is too big", __FUNCTION__); > + return -EINVAL; > + } > + > + v_end = v_start + dom->kernel_size; > + > + /* find kernel segment */ > + dom->kernel_seg.vstart = v_start; > + dom->kernel_seg.vend = v_end; > + > + startup_hdr = (struct startup_header *)dom->kernel_blob; > + > + /* Performs a sanity check for a valid startup entry point */ > + if ( (startup_hdr->startup_vaddr < v_start) || > + (startup_hdr->startup_vaddr > v_end) ) > + { > + xc_dom_printf(dom->xch, "%s: QNX IFS has wrong startup entry point", > __FUNCTION__); > + return -EINVAL; > + } > + > + dom->parms.virt_entry = startup_hdr->startup_vaddr; > + dom->parms.virt_base = rambase; > + > + dom->guest_type = "xen-3.0-armv7l"; > + DOMPRINTF("%s: %s: RAM starts at %"PRI_xen_pfn, > + __FUNCTION__, dom->guest_type, dom->rambase_pfn); > + DOMPRINTF("%s: %s: 0x%" PRIx64 " -> 0x%" PRIx64 "", > + __FUNCTION__, dom->guest_type, > + dom->kernel_seg.vstart, dom->kernel_seg.vend); > + > + return 0; > +} > + > +static int xc_dom_load_qnx_ifs(struct xc_dom_image *dom) > +{ > + void *dst; > + > + DOMPRINTF_CALLED(dom->xch); > + > + dst = xc_dom_seg_to_ptr(dom, &dom->kernel_seg); > + if ( dst == NULL ) > + { > + DOMPRINTF("%s: xc_dom_seg_to_ptr(dom, &dom->kernel_seg) => NULL", > + __func__); > + return -1; > + } > + > + DOMPRINTF("%s: kernel seg %#"PRIx64"-%#"PRIx64, > + __func__, dom->kernel_seg.vstart, dom->kernel_seg.vend); > + DOMPRINTF("%s: copy %zd bytes from blob %p to dst %p", > + __func__, dom->kernel_size, dom->kernel_blob, dst); > + > + memcpy(dst, dom->kernel_blob, dom->kernel_size); > + > + return 0; > +} > + > +static struct xc_dom_loader qnx_ifs_loader = { > + .name = "QNX IFS", > + .probe = xc_dom_probe_qnx_ifs, > + .parser = xc_dom_parse_qnx_ifs, > + .loader = xc_dom_load_qnx_ifs, > +}; > + > +static void __init register_loader(void) > +{ > + xc_dom_register_loader(&qnx_ifs_loader); > +} > + > +/* > + * Local variables: > + * mode: C > + * c-file-style: "BSD" > + * c-basic-offset: 4 > + * tab-width: 4 > + * indent-tabs-mode: nil > + * End: > + */ > -- > 1.9.1 > > > _______________________________________________ > Xen-devel mailing list > Xen-devel@xxxxxxxxxxxxx > http://lists.xen.org/xen-devel -- Andrii Tseglytskyi | Embedded Dev GlobalLogic www.globallogic.com _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |