[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 09/12] arm: load dom0 kernel from first boot module
Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx> --- xen/arch/arm/kernel.c | 74 +++++++++++++++++++++++++++++++++++++----------- xen/arch/arm/kernel.h | 10 ++++++ 2 files changed, 67 insertions(+), 17 deletions(-) diff --git a/xen/arch/arm/kernel.c b/xen/arch/arm/kernel.c index 2d56130..7fb6268 100644 --- a/xen/arch/arm/kernel.c +++ b/xen/arch/arm/kernel.c @@ -65,13 +65,13 @@ void copy_from_paddr(void *dst, paddr_t paddr, unsigned long len, int attrindx) static void kernel_zimage_load(struct kernel_info *info) { paddr_t load_addr = info->zimage.load_addr; + paddr_t paddr = info->zimage.kernel_addr; paddr_t len = info->zimage.len; - paddr_t flash = KERNEL_FLASH_ADDRESS; void *src = (void *)FIXMAP_ADDR(FIXMAP_MISC); unsigned long offs; - printk("Loading %"PRIpaddr" byte zImage from flash %"PRIpaddr" to %"PRIpaddr"-%"PRIpaddr": [", - len, flash, load_addr, load_addr + len); + printk("Loading zImage from %"PRIpaddr" to %"PRIpaddr"-%"PRIpaddr": [", + paddr, load_addr, load_addr + len); for ( offs = 0; offs < len; offs += PAGE_SIZE ) { paddr_t ma = gvirt_to_maddr(load_addr + offs); @@ -80,7 +80,7 @@ static void kernel_zimage_load(struct kernel_info *info) if ( ( offs % (1<<20) ) == 0 ) printk("."); - set_fixmap(FIXMAP_MISC, (flash+offs) >> PAGE_SHIFT, DEV_SHARED); + set_fixmap(FIXMAP_MISC, (paddr+offs) >> PAGE_SHIFT, DEV_SHARED); memcpy(dst, src, PAGE_SIZE); clear_fixmap(FIXMAP_MISC); @@ -92,30 +92,48 @@ static void kernel_zimage_load(struct kernel_info *info) /** * Check the image is a zImage and return the load address and length */ -static int kernel_try_zimage_prepare(struct kernel_info *info) +static int kernel_try_zimage_prepare(struct kernel_info *info, + paddr_t addr, paddr_t size) { uint32_t *zimage = (void *)FIXMAP_ADDR(FIXMAP_MISC); uint32_t start, end; struct minimal_dtb_header dtb_hdr; - set_fixmap(FIXMAP_MISC, KERNEL_FLASH_ADDRESS >> PAGE_SHIFT, DEV_SHARED); + set_fixmap(FIXMAP_MISC, addr >> PAGE_SHIFT, DEV_SHARED); + + zimage += addr & ~PAGE_MASK; if (zimage[ZIMAGE_MAGIC_OFFSET/4] != ZIMAGE_MAGIC) + { + clear_fixmap(FIXMAP_MISC); return -EINVAL; + } start = zimage[ZIMAGE_START_OFFSET/4]; end = zimage[ZIMAGE_END_OFFSET/4]; clear_fixmap(FIXMAP_MISC); + if ( end > addr + size ) + return -EINVAL; + /* * Check for an appended DTB. */ - copy_from_paddr(&dtb_hdr, KERNEL_FLASH_ADDRESS + end - start, sizeof(dtb_hdr), DEV_SHARED); - if (be32_to_cpu(dtb_hdr.magic) == DTB_MAGIC) { - end += be32_to_cpu(dtb_hdr.total_size); + if ( addr + end - start + sizeof(dtb_hdr) <= size ) + { + copy_from_paddr(&dtb_hdr, addr + end - start, + sizeof(dtb_hdr), DEV_SHARED); + if (be32_to_cpu(dtb_hdr.magic) == DTB_MAGIC) { + end += be32_to_cpu(dtb_hdr.total_size); + + if ( end > addr + size ) + return -EINVAL; + } } + info->zimage.kernel_addr = addr; + /* * If start is zero, the zImage is position independent -- load it * at 32k from start of RAM. @@ -142,25 +160,26 @@ static void kernel_elf_load(struct kernel_info *info) free_xenheap_pages(info->kernel_img, info->kernel_order); } -static int kernel_try_elf_prepare(struct kernel_info *info) +static int kernel_try_elf_prepare(struct kernel_info *info, + paddr_t addr, paddr_t size) { int rc; - info->kernel_order = get_order_from_bytes(KERNEL_FLASH_SIZE); + info->kernel_order = get_order_from_bytes(size); info->kernel_img = alloc_xenheap_pages(info->kernel_order, 0); if ( info->kernel_img == NULL ) panic("Cannot allocate temporary buffer for kernel.\n"); - copy_from_paddr(info->kernel_img, KERNEL_FLASH_ADDRESS, KERNEL_FLASH_SIZE, DEV_SHARED); + copy_from_paddr(info->kernel_img, addr, size, DEV_SHARED); - if ( (rc = elf_init(&info->elf.elf, info->kernel_img, KERNEL_FLASH_SIZE )) != 0 ) - return rc; + if ( (rc = elf_init(&info->elf.elf, info->kernel_img, size )) != 0 ) + goto err; #ifdef VERBOSE elf_set_verbose(&info->elf.elf); #endif elf_parse_binary(&info->elf.elf); if ( (rc = elf_xen_parse(&info->elf.elf, &info->elf.parms)) != 0 ) - return rc; + goto err; /* * TODO: can the ELF header be used to find the physical address @@ -170,15 +189,36 @@ static int kernel_try_elf_prepare(struct kernel_info *info) info->load = kernel_elf_load; return 0; +err: + free_xenheap_pages(info->kernel_img, info->kernel_order); + return rc; } int kernel_prepare(struct kernel_info *info) { int rc; - rc = kernel_try_zimage_prepare(info); + paddr_t start, size; + + if ( early_info.modules.nr_mods > 1 ) + panic("Cannot handle dom0 initrd yet\n"); + + if ( early_info.modules.nr_mods < 1 ) + { + printk("No boot modules found, trying flash\n"); + start = KERNEL_FLASH_ADDRESS; + size = KERNEL_FLASH_SIZE; + } + else + { + printk("Loading kernel from boot module 1\n"); + start = early_info.modules.module[1].start; + size = early_info.modules.module[1].size; + } + + rc = kernel_try_zimage_prepare(info, start, size); if (rc < 0) - rc = kernel_try_elf_prepare(info); + rc = kernel_try_elf_prepare(info, start, size); return rc; } diff --git a/xen/arch/arm/kernel.h b/xen/arch/arm/kernel.h index 4533568..2353e13 100644 --- a/xen/arch/arm/kernel.h +++ b/xen/arch/arm/kernel.h @@ -22,6 +22,7 @@ struct kernel_info { union { struct { + paddr_t kernel_addr; paddr_t load_addr; paddr_t len; } zimage; @@ -39,3 +40,12 @@ int kernel_prepare(struct kernel_info *info); void kernel_load(struct kernel_info *info); #endif /* #ifdef __ARCH_ARM_KERNEL_H__ */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ -- 1.7.9.1 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |