[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 1/2] xen: move perform_gunzip to common
The current gunzip code to uncompress the Dom0 kernel is implemented in inflate.c which is included by bzimage.c. I am looking to doing the same on ARM64 but there is quite a bit of boilerplate definitions that I would need to import in order for inflate.c to work correctly. Instead of copying/pasting the code from x86/bzimage.c, move those definitions to a new common file, gunzip.c and integrate the gunzip uncompressing route into the decompress function. Only support the simplest calling case (which actually is the only one in use), return -EOPNOTSUPP if the fill or flush functions are passed as arguments. Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx> CC: JBeulich@xxxxxxxx CC: andrew.cooper3@xxxxxxxxxx --- xen/arch/x86/bzimage.c | 142 +----------------------------------------- xen/common/Makefile | 2 +- xen/common/decompress.c | 2 + xen/common/gunzip.c | 141 +++++++++++++++++++++++++++++++++++++++++ xen/include/xen/decompress.h | 11 +++- 5 files changed, 155 insertions(+), 143 deletions(-) create mode 100644 xen/common/gunzip.c diff --git a/xen/arch/x86/bzimage.c b/xen/arch/x86/bzimage.c index c86c39e..976225c 100644 --- a/xen/arch/x86/bzimage.c +++ b/xen/arch/x86/bzimage.c @@ -8,144 +8,6 @@ #include <xen/libelf.h> #include <asm/bzimage.h> -#define HEAPORDER 3 - -static unsigned char *__initdata window; -#define memptr long -static memptr __initdata free_mem_ptr; -static memptr __initdata free_mem_end_ptr; - -#define WSIZE 0x80000000 - -static unsigned char *__initdata inbuf; -static unsigned __initdata insize; - -/* Index of next byte to be processed in inbuf: */ -static unsigned __initdata inptr; - -/* Bytes in output buffer: */ -static unsigned __initdata outcnt; - -#define OF(args) args -#define STATIC static - -#define memzero(s, n) memset((s), 0, (n)) - -typedef unsigned char uch; -typedef unsigned short ush; -typedef unsigned long ulg; - -#define INIT __init -#define INITDATA __initdata - -#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) - -/* Diagnostic functions */ -#ifdef DEBUG -# define Assert(cond, msg) do { if (!(cond)) error(msg); } while (0) -# define Trace(x) do { fprintf x; } while (0) -# define Tracev(x) do { if (verbose) fprintf x ; } while (0) -# define Tracevv(x) do { if (verbose > 1) fprintf x ; } while (0) -# define Tracec(c, x) do { if (verbose && (c)) fprintf x ; } while (0) -# define Tracecv(c, x) do { if (verbose > 1 && (c)) fprintf x ; } while (0) -#else -# define Assert(cond, msg) -# define Trace(x) -# define Tracev(x) -# define Tracevv(x) -# define Tracec(c, x) -# define Tracecv(c, x) -#endif - -static long __initdata bytes_out; -static void flush_window(void); - -static __init void error(char *x) -{ - panic("%s", x); -} - -static __init int fill_inbuf(void) -{ - error("ran out of input data"); - return 0; -} - - -#include "../../common/inflate.c" - -static __init void flush_window(void) -{ - /* - * The window is equal to the output buffer therefore only need to - * compute the crc. - */ - unsigned long c = crc; - unsigned n; - unsigned char *in, ch; - - in = window; - for ( n = 0; n < outcnt; n++ ) - { - ch = *in++; - c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); - } - crc = c; - - bytes_out += (unsigned long)outcnt; - outcnt = 0; -} - -static __init unsigned long output_length(char *image, unsigned long image_len) -{ - return *(uint32_t *)&image[image_len - 4]; -} - -static __init int gzip_check(char *image, unsigned long image_len) -{ - unsigned char magic0, magic1; - - if ( image_len < 2 ) - return 0; - - magic0 = (unsigned char)image[0]; - magic1 = (unsigned char)image[1]; - - return (magic0 == 0x1f) && ((magic1 == 0x8b) || (magic1 == 0x9e)); -} - -static __init int perform_gunzip(char *output, char *image, unsigned long image_len) -{ - int rc; - - if ( !gzip_check(image, image_len) ) - return 1; - - window = (unsigned char *)output; - - free_mem_ptr = (unsigned long)alloc_xenheap_pages(HEAPORDER, 0); - free_mem_end_ptr = free_mem_ptr + (PAGE_SIZE << HEAPORDER); - - inbuf = (unsigned char *)image; - insize = image_len; - inptr = 0; - - makecrc(); - - if ( gunzip() < 0 ) - { - rc = -EINVAL; - } - else - { - rc = 0; - } - - free_xenheap_pages((void *)free_mem_ptr, HEAPORDER); - - return rc; -} - struct __packed setup_header { uint8_t _pad0[0x1f1]; /* skip uninteresting stuff */ uint8_t setup_sects; @@ -258,9 +120,7 @@ int __init bzimage_parse(char *image_base, char **image_start, unsigned long *im output_len = output_length(*image_start, orig_image_len); - if ( (err = perform_gunzip(image_base, *image_start, orig_image_len)) > 0 ) - err = decompress(*image_start, orig_image_len, image_base); - + err = decompress(*image_start, orig_image_len, image_base); if ( !err ) { *image_start = image_base; diff --git a/xen/common/Makefile b/xen/common/Makefile index 3fdf931..0a4d4fa 100644 --- a/xen/common/Makefile +++ b/xen/common/Makefile @@ -56,7 +56,7 @@ obj-y += vsprintf.o obj-y += wait.o obj-y += xmalloc_tlsf.o -obj-bin-$(CONFIG_X86) += $(foreach n,decompress bunzip2 unxz unlzma unlzo unlz4 earlycpio,$(n).init.o) +obj-bin-$(CONFIG_X86) += $(foreach n,decompress gunzip bunzip2 unxz unlzma unlzo unlz4 earlycpio,$(n).init.o) obj-$(perfc) += perfc.o obj-$(crash_debug) += gdbstub.o diff --git a/xen/common/decompress.c b/xen/common/decompress.c index 5f86af9..67b48ec 100644 --- a/xen/common/decompress.c +++ b/xen/common/decompress.c @@ -16,6 +16,8 @@ int __init decompress(void *inbuf, unsigned int len, void *outbuf) (!memcmp(inbuf, "\037\213", 2) || !memcmp(inbuf, "\037\236", 2)) ) return gunzip(inbuf, len, NULL, NULL, outbuf, NULL, error); #endif + if (gzip_check(inbuf, len)) + return perform_gunzip(inbuf, len, NULL, NULL, outbuf, NULL, error); if ( len >= 3 && !memcmp(inbuf, "\x42\x5a\x68", 3) ) return bunzip2(inbuf, len, NULL, NULL, outbuf, NULL, error); diff --git a/xen/common/gunzip.c b/xen/common/gunzip.c new file mode 100644 index 0000000..cb3e0c6 --- /dev/null +++ b/xen/common/gunzip.c @@ -0,0 +1,141 @@ +#include <xen/config.h> +#include <xen/errno.h> +#include <xen/init.h> +#include <xen/lib.h> +#include <xen/mm.h> + +#define HEAPORDER 3 + +static unsigned char *__initdata window; +#define memptr long +static memptr __initdata free_mem_ptr; +static memptr __initdata free_mem_end_ptr; + +#define WSIZE 0x80000000 + +static unsigned char *__initdata inbuf; +static unsigned __initdata insize; + +/* Index of next byte to be processed in inbuf: */ +static unsigned __initdata inptr; + +/* Bytes in output buffer: */ +static unsigned __initdata outcnt; + +#define OF(args) args +#define STATIC static + +#define memzero(s, n) memset((s), 0, (n)) + +typedef unsigned char uch; +typedef unsigned short ush; +typedef unsigned long ulg; + +#define INIT __init +#define INITDATA __initdata + +#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) + +/* Diagnostic functions */ +#ifdef DEBUG +# define Assert(cond, msg) do { if (!(cond)) error(msg); } while (0) +# define Trace(x) do { fprintf x; } while (0) +# define Tracev(x) do { if (verbose) fprintf x ; } while (0) +# define Tracevv(x) do { if (verbose > 1) fprintf x ; } while (0) +# define Tracec(c, x) do { if (verbose && (c)) fprintf x ; } while (0) +# define Tracecv(c, x) do { if (verbose > 1 && (c)) fprintf x ; } while (0) +#else +# define Assert(cond, msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c, x) +# define Tracecv(c, x) +#endif + +static long __initdata bytes_out; +static void flush_window(void); + +static __initdata void (*error)(const char *x); + +static __init int fill_inbuf(void) +{ + error("ran out of input data"); + return 0; +} + +#include "inflate.c" + +static INIT void flush_window(void) +{ + /* + * The window is equal to the output buffer therefore only need to + * compute the crc. + */ + unsigned long c = crc; + unsigned n; + unsigned char *in, ch; + + in = window; + for ( n = 0; n < outcnt; n++ ) + { + ch = *in++; + c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); + } + crc = c; + + bytes_out += (unsigned long)outcnt; + outcnt = 0; +} + +int INIT gzip_check(char *image, unsigned long image_len) +{ + unsigned char magic0, magic1; + + if ( image_len < 2 ) + return 0; + + magic0 = (unsigned char)image[0]; + magic1 = (unsigned char)image[1]; + + return (magic0 == 0x1f) && ((magic1 == 0x8b) || (magic1 == 0x9e)); +} + +int INIT perform_gunzip(unsigned char *image, unsigned int image_len, + int(*fill)(void*, unsigned int), + int(*flush)(void*, unsigned int), + unsigned char *output, + unsigned int *pos, + void(*error_fn)(const char *x)) +{ + int rc; + + /* currently not supported */ + if (fill != NULL || flush != NULL) + return -EOPNOTSUPP; + + error = error_fn; + window = (unsigned char *)output; + + free_mem_ptr = (unsigned long)alloc_xenheap_pages(HEAPORDER, 0); + free_mem_end_ptr = free_mem_ptr + (PAGE_SIZE << HEAPORDER); + + inbuf = (unsigned char *)image; + insize = image_len; + inptr = 0; + + makecrc(); + + if ( gunzip() < 0 ) + { + rc = -EINVAL; + } + else + { + rc = 0; + } + + free_xenheap_pages((void *)free_mem_ptr, HEAPORDER); + + return rc; +} diff --git a/xen/include/xen/decompress.h b/xen/include/xen/decompress.h index b2955fa..248f0fb 100644 --- a/xen/include/xen/decompress.h +++ b/xen/include/xen/decompress.h @@ -1,6 +1,8 @@ #ifndef __XEN_GENERIC_H #define __XEN_GENERIC_H +#include <xen/types.h> + typedef int decompress_fn(unsigned char *inbuf, unsigned int len, int (*fill)(void*, unsigned int), int (*flush)(void*, unsigned int), @@ -31,8 +33,15 @@ typedef int decompress_fn(unsigned char *inbuf, unsigned int len, * dependent). */ -decompress_fn bunzip2, unxz, unlzma, unlzo, unlz4; +decompress_fn perform_gunzip, bunzip2, unxz, unlzma, unlzo, unlz4; int decompress(void *inbuf, unsigned int len, void *outbuf); +static inline unsigned long output_length(char *image, unsigned long image_len) +{ + return *(uint32_t *)&image[image_len - 4]; +} +int gzip_check(char *image, unsigned long image_len); + + #endif -- 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 |