|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v2 2/2] xen/arm: support gzip compressed kernels
Free the memory used for the compressed kernel and update the relative
mod->start and mod->size parameters with the uncompressed ones.
Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
CC: julien.grall@xxxxxxxxxx
CC: ian.campbell@xxxxxxxxxx
---
Changes in v2:
- use gzip_check
- avoid useless casts
- free original kernel image and update the mod with the new address and
size
- remove changes to common Makefile
- remove CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
---
xen/arch/arm/kernel.c | 48 +++++++++++++++++++++++++++++++++++++++++++
xen/arch/arm/setup.c | 2 +-
xen/include/asm-arm/setup.h | 2 ++
3 files changed, 51 insertions(+), 1 deletion(-)
diff --git a/xen/arch/arm/kernel.c b/xen/arch/arm/kernel.c
index f641b12..e7fbb24 100644
--- a/xen/arch/arm/kernel.c
+++ b/xen/arch/arm/kernel.c
@@ -13,6 +13,8 @@
#include <asm/byteorder.h>
#include <asm/setup.h>
#include <xen/libfdt/libfdt.h>
+#include <xen/gunzip.h>
+#include <xen/vmap.h>
#include "kernel.h"
@@ -257,6 +259,43 @@ static int kernel_uimage_probe(struct kernel_info *info,
return 0;
}
+static __init unsigned long output_length(char *image, unsigned long image_len)
+{
+ return *(uint32_t *)&image[image_len - 4];
+}
+
+static int kernel_decompress(struct kernel_info *info,
+ paddr_t *addr, paddr_t *size)
+{
+ char *output, *input;
+ char magic[2];
+ int rc;
+ unsigned kernel_order_in;
+ unsigned kernel_order_out;
+ paddr_t output_size;
+
+ copy_from_paddr(magic, *addr, sizeof(magic));
+
+ /* only gzip is supported */
+ if (!gzip_check(magic, *size))
+ return 0;
+
+ kernel_order_in = get_order_from_bytes(*size);
+ input = ioremap_cache(*addr, *size);
+
+ output_size = output_length(input, *size);
+ kernel_order_out = get_order_from_bytes(output_size);
+ output = alloc_xenheap_pages(kernel_order_out, 0);
+
+ rc = perform_gunzip(output, input, *size);
+ clean_dcache_va_range(output, output_size);
+ iounmap(input);
+
+ *addr = virt_to_maddr(output);
+ *size = output_size;
+ return 1;
+}
+
#ifdef CONFIG_ARM_64
/*
* Check if the image is a 64-bit Image.
@@ -463,6 +502,15 @@ int kernel_probe(struct kernel_info *info)
printk("Loading ramdisk from boot module @ %"PRIpaddr"\n",
info->initrd_bootmodule->start);
+ if (kernel_decompress(info, &start, &size) > 0)
+ {
+ /* Free the original kernel, update the pointers to the
+ * decompressed kernel */
+ dt_unreserved_regions(mod->start, mod->start + mod->size,
+ init_domheap_pages, 0);
+ mod->start = start;
+ mod->size = size;
+ }
#ifdef CONFIG_ARM_64
rc = kernel_zimage64_probe(info, start, size);
if (rc < 0)
diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
index 6626eba..109c71c 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -165,7 +165,7 @@ static void __init processor_id(void)
processor_setup();
}
-static void dt_unreserved_regions(paddr_t s, paddr_t e,
+void dt_unreserved_regions(paddr_t s, paddr_t e,
void (*cb)(paddr_t, paddr_t), int first)
{
int i, nr = fdt_num_mem_rsv(device_tree_flattened);
diff --git a/xen/include/asm-arm/setup.h b/xen/include/asm-arm/setup.h
index 81bb3da..30ac53b 100644
--- a/xen/include/asm-arm/setup.h
+++ b/xen/include/asm-arm/setup.h
@@ -54,6 +54,8 @@ void copy_from_paddr(void *dst, paddr_t paddr, unsigned long
len);
int construct_dom0(struct domain *d);
void discard_initial_modules(void);
+void dt_unreserved_regions(paddr_t s, paddr_t e,
+ void (*cb)(paddr_t, paddr_t), int first);
size_t __init boot_fdt_info(const void *fdt, paddr_t paddr);
const char __init *boot_fdt_cmdline(const void *fdt);
--
1.7.10.4
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |