lkml.org 
[lkml]   [2005]   [Oct]   [31]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH 12/20] inflate: internalize (arch) most of the output window handling
    inflate: internalize most of the output window handling

    This moves the inflate window definition and handling into
    lib/inflate.c and rather than calling a global flush_window function,
    now calls a flush callback. The callback in most callers is also
    greatly simplified.

    Signed-off-by: Matt Mackall <mpm@selenic.com>

    Index: 2.6.14/lib/inflate.c
    ===================================================================
    --- 2.6.14.orig/lib/inflate.c 2005-10-28 21:10:35.000000000 -0700
    +++ 2.6.14/lib/inflate.c 2005-10-28 21:13:20.000000000 -0700
    @@ -144,7 +144,10 @@ static void free(void *where)
    if (!malloc_count)
    malloc_ptr = free_mem_ptr;
    }
    +
    +static u8 window[0x8000]; /* use a statically allocated window */
    #else
    +static u8 *window; /* dynamically allocate */
    #define malloc(a) kmalloc(a, GFP_KERNEL)
    #define free(a) kfree(a)
    #endif
    @@ -170,8 +173,9 @@ struct huft {

    struct iostate {
    u8 *window, *ibuf;
    - int ipos, isize, itotal, opos, osize, bits;
    + int ipos, isize, itotal, opos, osize, ototal, bits;
    void (*fill)(u8 *ibuf, int len);
    + void (*flush)(const u8 *obuf, int len);
    u32 buf, crc;
    };

    @@ -191,10 +195,6 @@ static int INIT inflate(struct iostate *
    stream to find repeated byte strings. This is implemented here as a
    circular buffer. The index is updated simply by incrementing and then
    ANDing with 0x7fff (32K-1). */
    -/* It is left to other modules to supply the 32 K area. It is assumed
    - to be usable as if it were declared "u8 window[32768];" or as just
    - "u8 *window;" and then malloc'ed in the latter case. The definition
    - must be in unzip.h, included above. */

    static void flush_output(struct iostate *io)
    {
    @@ -204,8 +204,8 @@ static void flush_output(struct iostate
    io->crc = crc_32_tab[(io->window[i] ^ (int)io->crc) & 0xff]
    ^ (io->crc >> 8);

    - outcnt = io->opos;
    - flush_window();
    + io->flush(io->window, io->opos);
    + io->ototal += io->opos;
    io->opos = 0;
    }

    @@ -991,8 +991,10 @@ static void INIT makecrc(void)
    * @ibuf: input character pool
    * @isize: size of pool
    * @fill: function to fill the input pool
    + * @flush: function to flush the output pool
    */
    -static int INIT gunzip(u8 *ibuf, int isize, void (*fill)(u8 *buf, int size))
    +static int INIT gunzip(u8 *ibuf, int isize, void (*fill)(u8 *buf, int size),
    + void (*flush)(const u8 *buf, int size))
    {
    u8 flags;
    unsigned char magic[2]; /* magic header */
    @@ -1002,13 +1004,13 @@ static int INIT gunzip(u8 *ibuf, int isi
    int res;
    struct iostate io;

    - io.window = window;
    - io.osize = WSIZE;
    - io.opos = io.bits = io.buf = io.ipos = io.itotal = 0;
    + io.osize = 0x8000; /* 32k for inflate */
    + io.opos = io.bits = io.buf = io.ipos = io.itotal = io.ototal = 0;
    io.crc = 0xffffffffUL;
    io.isize = isize;
    io.ibuf = ibuf;
    io.fill = fill;
    + io.flush = flush;

    makecrc(); /* initialize the CRC table */

    @@ -1066,7 +1068,16 @@ static int INIT gunzip(u8 *ibuf, int isi
    ;

    /* Decompress */
    - if ((res = inflate(&io))) {
    + io.window = window ? window : malloc(io.osize);
    + if (!io.window) {
    + error("couldn't allocate gunzip window\n");
    + return -1;
    + }
    + res = inflate(&io);
    + if (!window)
    + free(io.window);
    +
    + if (res) {
    switch (res) {
    case 0:
    break;
    @@ -1106,7 +1117,7 @@ static int INIT gunzip(u8 *ibuf, int isi
    error("crc error");
    return -1;
    }
    - if (orig_len != bytes_out) {
    + if (orig_len != io.ototal) {
    error("length error");
    return -1;
    }
    Index: 2.6.14/arch/alpha/boot/misc.c
    ===================================================================
    --- 2.6.14.orig/arch/alpha/boot/misc.c 2005-10-28 21:09:20.000000000 -0700
    +++ 2.6.14/arch/alpha/boot/misc.c 2005-10-28 21:13:20.000000000 -0700
    @@ -32,21 +32,12 @@ typedef unsigned char uch;
    typedef unsigned short ush;
    typedef unsigned long ulg;

    -#define WSIZE 0x8000 /* Window size must be at least 32k, */
    - /* and a power of two */
    -
    -static uch *window; /* Sliding window buffer */
    -static unsigned outcnt; /* bytes in output buffer */
    -
    -static void flush_window(void);
    static void error(char *m);

    static char *input_data;
    static int input_data_size;

    static uch *output_data;
    -static ulg output_ptr;
    -static ulg bytes_out;

    extern int end;
    static ulg free_mem_ptr;
    @@ -56,24 +47,11 @@ static ulg free_mem_ptr_end;

    #include "../../../lib/inflate.c"

    -/* ===========================================================================
    - * Write the output window window[0..outcnt-1] and update bytes_out.
    - * (Used for the decompressed data only.)
    - */
    -void flush_window(void)
    +/* flush gunzip output window */
    +static void flush_window(const u8 *buf, int len)
    {
    - unsigned n;
    - uch *in, *out, ch;
    -
    - in = window;
    - out = &output_data[output_ptr];
    - for (n = 0; n < outcnt; n++)
    - ch = *out++ = *in++;
    -
    - bytes_out += (ulg)outcnt;
    - output_ptr += (ulg)outcnt;
    - outcnt = 0;
    -/* puts("."); */
    + while(len--)
    + *output_data++ = *buf++;
    }

    static void error(char *x)
    @@ -91,6 +69,7 @@ decompress_kernel(void *output_start,
    size_t ksize,
    size_t kzsize)
    {
    + int count;
    output_data = (uch *)output_start;
    input_data = (uch *)input_start;
    input_data_size = kzsize; /* use compressed size */
    @@ -100,11 +79,8 @@ decompress_kernel(void *output_start,
    free_mem_ptr_end = (ulg)output_start + ksize + 0x200000;
    /* FIXME FIXME FIXME */

    - /* put in temp area to reduce initial footprint */
    - window = malloc(WSIZE);
    -
    /* puts("Uncompressing Linux..."); */
    - gunzip(input_data, input_data_size, NULL);
    + count = gunzip(input_data, input_data_size, NULL, flush_window);
    /* puts(" done, booting the kernel.\n"); */
    - return output_ptr;
    + return count;
    }
    Index: 2.6.14/arch/arm/boot/compressed/misc.c
    ===================================================================
    --- 2.6.14.orig/arch/arm/boot/compressed/misc.c 2005-10-28 21:09:20.000000000 -0700
    +++ 2.6.14/arch/arm/boot/compressed/misc.c 2005-10-28 21:13:20.000000000 -0700
    @@ -50,21 +50,12 @@ typedef unsigned char uch;
    typedef unsigned short ush;
    typedef unsigned long ulg;

    -#define WSIZE 0x8000 /* Window size must be at least 32k, */
    - /* and a power of two */
    -
    -static uch window[WSIZE]; /* Sliding window buffer */
    -static unsigned outcnt; /* bytes in output buffer */
    -
    -static void flush_window(void);
    static void error(char *m);

    extern char input_data[];
    extern char input_data_end[];

    static uch *output_data;
    -static ulg output_ptr;
    -static ulg bytes_out;

    static void putstr(const char *);

    @@ -80,23 +71,11 @@ static ulg free_mem_ptr_end;
    #define NO_INFLATE_MALLOC
    #endif

    -/* ===========================================================================
    - * Write the output window window[0..outcnt-1] and update bytes_out.
    - * (Used for the decompressed data only.)
    - */
    -void flush_window(void)
    +/* flush gunzip output window */
    +static void flush_window(const u8 *buf, int len)
    {
    - unsigned n;
    - uch *in, *out, ch;
    -
    - in = window;
    - out = &output_data[output_ptr];
    - for (n = 0; n < outcnt; n++)
    - ch = *out++ = *in++;
    -
    - bytes_out += (ulg)outcnt;
    - output_ptr += (ulg)outcnt;
    - outcnt = 0;
    + while(len--)
    + *output_data++ = *buf++;
    putstr(".");
    }

    @@ -123,7 +102,7 @@ decompress_kernel(ulg output_start, ulg
    arch_decomp_setup();

    putstr("Uncompressing Linux...");
    - gunzip(input_data, input_data_end - input_data, NULL);
    + gunzip(input_data, input_data_end - input_data, NULL, flush_window);
    putstr(" done, booting the kernel.\n");
    return output_ptr;
    }
    @@ -136,7 +115,7 @@ int main()
    output_data = output_buffer;

    putstr("Uncompressing Linux...");
    - gunzip(input_data, input_data_end - input_data, NULL);
    + gunzip(input_data, input_data_end - input_data, NULL, flush_window);
    putstr("done.\n");
    return 0;
    }
    Index: 2.6.14/arch/arm26/boot/compressed/misc.c
    ===================================================================
    --- 2.6.14.orig/arch/arm26/boot/compressed/misc.c 2005-10-28 21:09:20.000000000 -0700
    +++ 2.6.14/arch/arm26/boot/compressed/misc.c 2005-10-28 21:13:20.000000000 -0700
    @@ -35,21 +35,11 @@ typedef unsigned char uch;
    typedef unsigned short ush;
    typedef unsigned long ulg;

    -#define WSIZE 0x8000 /* Window size must be at least 32k, */
    - /* and a power of two */
    -
    -static uch window[WSIZE]; /* Sliding window buffer */
    -static unsigned outcnt; /* bytes in output buffer */
    -
    -static void flush_window(void);
    static void error(char *m);

    extern char input_data[];
    extern char input_data_end[];
    -
    static uch *output_data;
    -static ulg output_ptr;
    -static ulg bytes_out;

    static void puts(const char *);

    @@ -65,23 +55,11 @@ static ulg free_mem_ptr_end;
    #define NO_INFLATE_MALLOC
    #endif

    -/* ===========================================================================
    - * Write the output window window[0..outcnt-1] and update bytes_out.
    - * (Used for the decompressed data only.)
    - */
    -void flush_window(void)
    +/* flush the gunzip output window */
    +static void flush_window(const u8 *buf, int len)
    {
    - unsigned n;
    - uch *in, *out, ch;
    -
    - in = window;
    - out = &output_data[output_ptr];
    - for (n = 0; n < outcnt; n++)
    - ch = *out++ = *in++;
    -
    - bytes_out += (ulg)outcnt;
    - output_ptr += (ulg)outcnt;
    - outcnt = 0;
    + while (len--)
    + *output_data++ = *buf++;
    puts(".");
    }

    @@ -110,7 +88,7 @@ decompress_kernel(ulg output_start, ulg
    arch_decomp_setup();

    puts("Uncompressing Linux...");
    - gunzip(input_data, input_data_end - input_data, NULL);
    + gunzip(input_data, input_data_end - input_data, NULL, flush_window);
    puts(" done, booting the kernel.\n");
    return output_ptr;
    }
    @@ -123,7 +101,7 @@ int main()
    output_data = output_buffer;

    puts("Uncompressing Linux...");
    - gunzip(input_data, input_data_end - input_data, NULL);
    + gunzip(input_data, input_data_end - input_data, NULL, flush_window);
    puts("done.\n");
    return 0;
    }
    Index: 2.6.14/arch/cris/arch-v10/boot/compressed/misc.c
    ===================================================================
    --- 2.6.14.orig/arch/cris/arch-v10/boot/compressed/misc.c 2005-10-28 21:09:20.000000000 -0700
    +++ 2.6.14/arch/cris/arch-v10/boot/compressed/misc.c 2005-10-28 21:13:20.000000000 -0700
    @@ -32,21 +32,12 @@ typedef unsigned char uch;
    typedef unsigned short ush;
    typedef unsigned long ulg;

    -#define WSIZE 0x8000 /* Window size must be at least 32k, */
    - /* and a power of two */
    -
    -static uch window[WSIZE]; /* Sliding window buffer */
    unsigned compsize; /* compressed size, used by head.S */
    -static unsigned outcnt = 0; /* bytes in output buffer */

    -static void flush_window(void);
    static void error(char *m);

    extern char *input_data; /* lives in head.S */
    -
    -static long bytes_out = 0;
    static uch *output_data;
    -static unsigned long output_ptr = 0;

    static void puts(const char *);

    @@ -85,25 +76,11 @@ puts(const char *s)
    #endif
    }

    -/* ===========================================================================
    - * Write the output window window[0..outcnt-1] and update bytes_out.
    - * (Used for the decompressed data only.)
    - */
    -
    -static void
    -flush_window()
    +/* flush the gunzip output window */
    +static void flush_window(const u8 *buf, int len)
    {
    - unsigned n;
    - uch *in, *out, ch;
    -
    - in = window;
    - out = &output_data[output_ptr];
    - for (n = 0; n < outcnt; n++)
    - ch = *out++ = *in++;
    -
    - bytes_out += (ulg)outcnt;
    - output_ptr += (ulg)outcnt;
    - outcnt = 0;
    + while (len--)
    + *output_data++ = *buf++;
    }

    static void
    @@ -163,6 +140,6 @@ decompress_kernel()
    }

    puts("Uncompressing Linux...\n");
    - compsize = gunzip(input_data, 0x7fffffff, NULL);
    + compsize = gunzip(input_data, 0x7fffffff, NULL, flush_window);
    puts("Done. Now booting the kernel.\n");
    }
    Index: 2.6.14/arch/cris/arch-v32/boot/compressed/misc.c
    ===================================================================
    --- 2.6.14.orig/arch/cris/arch-v32/boot/compressed/misc.c 2005-10-28 21:09:20.000000000 -0700
    +++ 2.6.14/arch/cris/arch-v32/boot/compressed/misc.c 2005-10-28 21:13:20.000000000 -0700
    @@ -34,20 +34,10 @@ typedef unsigned char uch;
    typedef unsigned short ush;
    typedef unsigned long ulg;

    -#define WSIZE 0x8000 /* Window size must be at least 32k, */
    - /* and a power of two */
    -
    -static uch window[WSIZE]; /* Sliding window buffer */
    -static unsigned outcnt = 0; /* bytes in output buffer */
    -
    -static void flush_window(void);
    static void error(char *m);

    extern char *input_data; /* lives in head.S */
    -
    -static long bytes_out = 0;
    static uch *output_data;
    -static unsigned long output_ptr = 0;

    static void puts(const char *);

    @@ -98,25 +88,11 @@ puts(const char *s)
    #endif
    }

    -/* ===========================================================================
    - * Write the output window window[0..outcnt-1] and update bytes_out.
    - * (Used for the decompressed data only.)
    - */
    -
    -static void
    -flush_window()
    +/* flush the gunzip output window */
    +static void flush_window(const u8 *buf, int len)
    {
    - unsigned n;
    - uch *in, *out, ch;
    -
    - in = window;
    - out = &output_data[output_ptr];
    - for (n = 0; n < outcnt; n++)
    - ch = *out++ = *in++;
    -
    - bytes_out += (ulg)outcnt;
    - output_ptr += (ulg)outcnt;
    - outcnt = 0;
    + while (len--)
    + *output_data++ = *buf++;
    }

    static void
    @@ -207,6 +183,6 @@ decompress_kernel()
    }

    puts("Uncompressing Linux...\n");
    - gunzip(input_data, 0x7fffffff, NULL);
    + gunzip(input_data, 0x7fffffff, NULL, flush_window);
    puts("Done. Now booting the kernel.\n");
    }
    Index: 2.6.14/arch/i386/boot/compressed/misc.c
    ===================================================================
    --- 2.6.14.orig/arch/i386/boot/compressed/misc.c 2005-10-28 21:09:20.000000000 -0700
    +++ 2.6.14/arch/i386/boot/compressed/misc.c 2005-10-28 21:13:20.000000000 -0700
    @@ -27,13 +27,6 @@ typedef unsigned char uch;
    typedef unsigned short ush;
    typedef unsigned long ulg;

    -#define WSIZE 0x8000 /* Window size must be at least 32k, */
    - /* and a power of two */
    -
    -static uch window[WSIZE]; /* Sliding window buffer */
    -static unsigned outcnt = 0; /* bytes in output buffer */
    -
    -static void flush_window(void);
    static void error(char *m);

    /*
    @@ -49,10 +42,8 @@ static unsigned char *real_mode; /* Poin

    extern char input_data[];
    extern int input_len;
    -
    -static long bytes_out = 0;
    +static long bytes_out;
    static uch *output_data;
    -static unsigned long output_ptr = 0;

    static void putstr(const char *);

    @@ -126,43 +117,15 @@ static void putstr(const char *s)
    outb_p(0xff & (pos >> 1), vidport+1);
    }

    -/* ===========================================================================
    - * Write the output window window[0..outcnt-1] and update bytes_out.
    - * (Used for the decompressed data only.)
    - */
    -static void flush_window_low(void)
    -{
    - unsigned n;
    - uch *in, *out, ch;
    -
    - in = window;
    - out = &output_data[output_ptr];
    - for (n = 0; n < outcnt; n++)
    - ch = *out++ = *in++;
    -
    - bytes_out += (ulg)outcnt;
    - output_ptr += (ulg)outcnt;
    - outcnt = 0;
    -}
    -
    -static void flush_window_high(void)
    +/* flush the gunzip output buffer */
    +static void flush_window(const u8 *buf, int len)
    {
    - unsigned n;
    - uch *in, ch;
    - in = window;
    - for (n = 0; n < outcnt; n++) {
    - ch = *output_data++ = *in++;
    - if ((ulg)output_data == low_buffer_end) output_data=high_buffer_start;
    - }
    -
    - bytes_out += (ulg)outcnt;
    - outcnt = 0;
    -}
    -
    -static void flush_window(void)
    -{
    - if (high_loaded) flush_window_high();
    - else flush_window_low();
    + bytes_out += len;
    + while (len--) {
    + *output_data++ = *buf++;
    + if (high_loaded && (u32)output_data == low_buffer_end)
    + output_data = high_buffer_start;
    + }
    }

    static void error(char *x)
    @@ -254,7 +217,7 @@ asmlinkage int decompress_kernel(struct
    else setup_output_buffer_if_we_run_high(mv);

    putstr("Uncompressing Linux... ");
    - gunzip(input_data, input_len, NULL);
    + gunzip(input_data, input_len, NULL, flush_window);
    putstr("Ok, booting the kernel.\n");
    if (high_loaded) close_output_buffer_if_we_run_high(mv);
    return high_loaded;
    Index: 2.6.14/arch/m32r/boot/compressed/misc.c
    ===================================================================
    --- 2.6.14.orig/arch/m32r/boot/compressed/misc.c 2005-10-28 21:09:20.000000000 -0700
    +++ 2.6.14/arch/m32r/boot/compressed/misc.c 2005-10-28 21:13:20.000000000 -0700
    @@ -21,21 +21,11 @@ typedef unsigned char uch;
    typedef unsigned short ush;
    typedef unsigned long ulg;

    -#define WSIZE 0x8000 /* Window size must be at least 32k, */
    - /* and a power of two */
    -
    -static uch window[WSIZE]; /* Sliding window buffer */
    -static unsigned outcnt = 0; /* bytes in output buffer */
    -
    -static void flush_window(void);
    static void error(char *m);

    static unsigned char *input_data;
    static int input_len;
    -
    -static long bytes_out = 0;
    static uch *output_data;
    -static unsigned long output_ptr = 0;

    #include "m32r_sio.c"

    @@ -46,23 +36,11 @@ static unsigned long free_mem_end_ptr;

    #include "../../../../lib/inflate.c"

    -/* ===========================================================================
    - * Write the output window window[0..outcnt-1] and update bytes_out.
    - * (Used for the decompressed data only.)
    - */
    -static void flush_window(void)
    +/* flush the gunzip output buffer */
    +static void flush_window(const u8 *buf, int len)
    {
    - unsigned n;
    - uch *in, *out, ch;
    -
    - in = window;
    - out = &output_data[output_ptr];
    - for (n = 0; n < outcnt; n++)
    - ch = *out++ = *in++;
    -
    - bytes_out += (ulg)outcnt;
    - output_ptr += (ulg)outcnt;
    - outcnt = 0;
    + while (len--)
    + *output_data++ = *buf++;
    }

    static void error(char *x)
    @@ -87,6 +65,6 @@ decompress_kernel(int mmu_on, unsigned c
    input_len = zimage_len;

    puts("Uncompressing Linux... ");
    - gunzip(input_data, input_len, NULL);
    + gunzip(input_data, input_len, NULL, flush_window);
    puts("Ok, booting the kernel.\n");
    }
    Index: 2.6.14/arch/sh/boot/compressed/misc.c
    ===================================================================
    --- 2.6.14.orig/arch/sh/boot/compressed/misc.c 2005-10-28 21:09:20.000000000 -0700
    +++ 2.6.14/arch/sh/boot/compressed/misc.c 2005-10-28 21:13:20.000000000 -0700
    @@ -23,21 +23,11 @@ typedef unsigned char uch;
    typedef unsigned short ush;
    typedef unsigned long ulg;

    -#define WSIZE 0x8000 /* Window size must be at least 32k, */
    - /* and a power of two */
    -
    -static uch window[WSIZE]; /* Sliding window buffer */
    -static unsigned outcnt = 0; /* bytes in output buffer */
    -
    -static void flush_window(void);
    static void error(char *m);

    extern char input_data[];
    extern int input_len;
    -
    -static long bytes_out = 0;
    static uch *output_data;
    -static unsigned long output_ptr = 0;

    int puts(const char *);

    @@ -74,23 +64,11 @@ int puts(const char *s)
    }
    #endif

    -/* ===========================================================================
    - * Write the output window window[0..outcnt-1] and update bytes_out.
    - * (Used for the decompressed data only.)
    - */
    -static void flush_window(void)
    -{
    - unsigned n;
    - uch *in, *out, ch;
    -
    - in = window;
    - out = &output_data[output_ptr];
    - for (n = 0; n < outcnt; n++)
    - ch = *out++ = *in++;
    -
    - bytes_out += (ulg)outcnt;
    - output_ptr += (ulg)outcnt;
    - outcnt = 0;
    +/* flush the gunzip output window */
    +static void flush_window(const u8 *buf, int len)
    +{
    + while (len--)
    + *output_data++ = *buf++;
    }

    static void error(char *x)
    @@ -114,6 +92,6 @@ void decompress_kernel(void)
    free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;

    puts("Uncompressing Linux... ");
    - gunzip(input_data, input_len, NULL);
    + gunzip(input_data, input_len, NULL, flush_window);
    puts("Ok, booting the kernel.\n");
    }
    Index: 2.6.14/arch/sh64/boot/compressed/misc.c
    ===================================================================
    --- 2.6.14.orig/arch/sh64/boot/compressed/misc.c 2005-10-28 21:09:20.000000000 -0700
    +++ 2.6.14/arch/sh64/boot/compressed/misc.c 2005-10-28 21:13:20.000000000 -0700
    @@ -23,21 +23,11 @@ typedef unsigned char uch;
    typedef unsigned short ush;
    typedef unsigned long ulg;

    -#define WSIZE 0x8000 /* Window size must be at least 32k, */
    - /* and a power of two */
    -
    -static uch window[WSIZE]; /* Sliding window buffer */
    -static unsigned outcnt = 0; /* bytes in output buffer */
    -
    -static void flush_window(void);
    static void error(char *m);

    extern char input_data[];
    extern int input_len;
    -
    -static long bytes_out = 0;
    static uch *output_data;
    -static unsigned long output_ptr = 0;

    static void puts(const char *);

    @@ -54,23 +44,12 @@ void puts(const char *s)
    {
    }

    -/* ===========================================================================
    - * Write the output window window[0..outcnt-1] and update bytes_out.
    - * (Used for the decompressed data only.)
    - */
    -static void flush_window(void)
    +/* flush the gunzip window */
    +static void flush_window(const u8 *buf, int len)
    {
    - unsigned n;
    - uch *in, *out, ch;
    + while(len--)
    + *output_data++ = *buf++;

    - in = window;
    - out = &output_data[output_ptr];
    - for (n = 0; n < outcnt; n++)
    - ch = *out++ = *in++;
    -
    - bytes_out += (ulg) outcnt;
    - output_ptr += (ulg) outcnt;
    - outcnt = 0;
    puts(".");
    }

    @@ -95,7 +74,7 @@ void decompress_kernel(void)

    puts("Uncompressing Linux... ");
    cache_control(CACHE_ENABLE);
    - gunzip(input_data, input_len, NULL);
    + gunzip(input_data, input_len, NULL, flush_window);
    puts("\n");

    #if 0
    Index: 2.6.14/arch/x86_64/boot/compressed/misc.c
    ===================================================================
    --- 2.6.14.orig/arch/x86_64/boot/compressed/misc.c 2005-10-28 21:09:20.000000000 -0700
    +++ 2.6.14/arch/x86_64/boot/compressed/misc.c 2005-10-28 21:13:20.000000000 -0700
    @@ -20,13 +20,6 @@ typedef unsigned char uch;
    typedef unsigned short ush;
    typedef unsigned long ulg;

    -#define WSIZE 0x8000 /* Window size must be at least 32k, */
    - /* and a power of two */
    -
    -static uch window[WSIZE]; /* Sliding window buffer */
    -static unsigned outcnt = 0; /* bytes in output buffer */
    -
    -static void flush_window(void);
    static void error(char *m);

    /*
    @@ -43,9 +36,8 @@ static unsigned char *real_mode; /* Poin
    extern unsigned char input_data[];
    extern int input_len;

    -static long bytes_out = 0;
    +static long bytes_out;
    static uch *output_data;
    -static unsigned long output_ptr = 0;

    static void putstr(const char *);

    @@ -115,43 +107,15 @@ static void putstr(const char *s)
    outb_p(0xff & (pos >> 1), vidport+1);
    }

    -/* ===========================================================================
    - * Write the output window window[0..outcnt-1] and update bytes_out.
    - * (Used for the decompressed data only.)
    - */
    -static void flush_window_low(void)
    +/* flush the gunzip output window */
    +static void flush_window(const u8 *buf, int len)
    {
    - unsigned n;
    - uch *in, *out, ch;
    -
    - in = window;
    - out = &output_data[output_ptr];
    - for (n = 0; n < outcnt; n++)
    - ch = *out++ = *in++;
    -
    - bytes_out += (ulg)outcnt;
    - output_ptr += (ulg)outcnt;
    - outcnt = 0;
    -}
    -
    -static void flush_window_high(void)
    -{
    - unsigned n;
    - uch *in, ch;
    - in = window;
    - for (n = 0; n < outcnt; n++) {
    - ch = *output_data++ = *in++;
    - if ((ulg)output_data == low_buffer_end) output_data=high_buffer_start;
    - }
    -
    - bytes_out += (ulg)outcnt;
    - outcnt = 0;
    -}
    -
    -static void flush_window(void)
    -{
    - if (high_loaded) flush_window_high();
    - else flush_window_low();
    + bytes_out += len;
    + while (len--) {
    + *output_data++ = *buf++;
    + if (high_loaded && output_data == (u8 *)low_buffer_end)
    + output_data = high_buffer_start;
    + }
    }

    static void error(char *x)
    @@ -201,7 +165,7 @@ void setup_output_buffer_if_we_run_high(
    mv->high_buffer_start = high_buffer_start;
    }

    -void close_output_buffer_if_we_run_high(struct moveparams *mv)
    +void close_output_buffer_if_we_run_high(struct moveparams *mv, int bytes_out)
    {
    if (bytes_out > low_buffer_size) {
    mv->lcount = low_buffer_size;
    @@ -232,7 +196,7 @@ int decompress_kernel(struct moveparams
    else setup_output_buffer_if_we_run_high(mv);

    putstr(".\nDecompressing Linux...");
    - gunzip(input_data, input_len, NULL);
    + gunzip(input_data, input_len, NULL, flush_window);
    putstr("done.\nBooting the kernel.\n");
    if (high_loaded) close_output_buffer_if_we_run_high(mv);
    return high_loaded;
    Index: 2.6.14/init/do_mounts_rd.c
    ===================================================================
    --- 2.6.14.orig/init/do_mounts_rd.c 2005-10-28 21:09:20.000000000 -0700
    +++ 2.6.14/init/do_mounts_rd.c 2005-10-28 21:13:20.000000000 -0700
    @@ -278,20 +278,13 @@ typedef unsigned short ush;
    typedef unsigned long ulg;

    #define INBUFSIZ 4096
    -#define WSIZE 0x8000 /* window size--must be a power of two, and */
    - /* at least 32K for zip's deflate method */
    -
    static uch *inbuf;
    -static uch *window;
    -static unsigned outcnt; /* bytes in output buffer */
    static int exit_code;
    static int unzip_error;
    -static long bytes_out;
    static int crd_infd, crd_outfd;

    #define INIT __init

    -static void __init flush_window(void);
    static void __init error(char *m);

    #define NO_INFLATE_MALLOC
    @@ -308,27 +301,17 @@ static void __init fill_inbuf(u8 *buf, i
    error("RAMDISK: ran out of compressed data");
    }

    -/* ===========================================================================
    - * Write the output window window[0..outcnt-1] and update bytes_out.
    - * (Used for the decompressed data only.)
    - */
    -static void __init flush_window(void)
    +/* Write the output window from gunzip */
    +static void __init flush_buffer(const u8 *buf, int len)
    {
    - unsigned n, written;
    - uch *in, ch;
    -
    - written = sys_write(crd_outfd, window, outcnt);
    - if (written != outcnt && unzip_error == 0) {
    - printk(KERN_ERR "RAMDISK: incomplete write (%d != %d) %ld\n",
    - written, outcnt, bytes_out);
    - unzip_error = 1;
    - }
    - in = window;
    - for (n = 0; n < outcnt; n++)
    - ch = *in++;
    + unsigned written;

    - bytes_out += (ulg)outcnt;
    - outcnt = 0;
    + written = sys_write(crd_outfd, buf, len);
    + if (written != len && unzip_error == 0) {
    + printk(KERN_ERR "RAMDISK: incomplete write (%d != %d)\n",
    + written, len);
    + unzip_error = 1;
    + }
    }

    static void __init error(char *x)
    @@ -342,9 +325,7 @@ static int __init crd_load(int in_fd, in
    {
    int result;

    - outcnt = 0; /* bytes in output buffer */
    exit_code = 0;
    - bytes_out = 0;

    crd_infd = in_fd;
    crd_outfd = out_fd;
    @@ -353,17 +334,10 @@ static int __init crd_load(int in_fd, in
    printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n");
    return -1;
    }
    - window = kmalloc(WSIZE, GFP_KERNEL);
    - if (window == 0) {
    - printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n");
    - kfree(inbuf);
    - return -1;
    - }
    - result = gunzip(inbuf, INBUFSIZ, fill_inbuf);
    + result = gunzip(inbuf, INBUFSIZ, fill_inbuf, flush_buffer);
    if (unzip_error)
    result = 1;
    kfree(inbuf);
    - kfree(window);
    return result;
    }

    Index: 2.6.14/init/initramfs.c
    ===================================================================
    --- 2.6.14.orig/init/initramfs.c 2005-10-28 21:09:20.000000000 -0700
    +++ 2.6.14/init/initramfs.c 2005-10-28 21:13:20.000000000 -0700
    @@ -309,12 +309,12 @@ static int __init write_buffer(char *buf
    return len - count;
    }

    -static void __init flush_buffer(char *buf, unsigned len)
    +static void __init flush_buffer(const u8 *buf, int len)
    {
    int written;
    if (message)
    return;
    - while ((written = write_buffer(buf, len)) < len && !message) {
    + while ((written = write_buffer((char *)buf, len)) < len && !message) {
    char c = buf[written];
    if (c == '0') {
    buf += written;
    @@ -337,41 +337,14 @@ typedef unsigned char uch;
    typedef unsigned short ush;
    typedef unsigned long ulg;

    -#define WSIZE 0x8000 /* window size--must be a power of two, and */
    - /* at least 32K for zip's deflate method */
    -
    -static uch *window;
    -
    -static unsigned outcnt; /* bytes in output buffer */
    -static long bytes_out;
    -
    #define INIT __init

    -static void __init flush_window(void);
    static void __init error(char *m);

    #define NO_INFLATE_MALLOC

    #include "../lib/inflate.c"

    -/* ===========================================================================
    - * Write the output window window[0..outcnt-1] and update bytes_out.
    - * (Used for the decompressed data only.)
    - */
    -static void __init flush_window(void)
    -{
    - unsigned n;
    - uch *in, ch;
    -
    - flush_buffer(window, outcnt);
    - in = window;
    - for (n = 0; n < outcnt; n++)
    - ch = *in++;
    -
    - bytes_out += (ulg)outcnt;
    - outcnt = 0;
    -}
    -
    static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only)
    {
    int written, cnt;
    @@ -379,8 +352,7 @@ static char * __init unpack_to_rootfs(ch
    header_buf = kmalloc(110, GFP_KERNEL);
    symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL);
    name_buf = kmalloc(N_ALIGN(PATH_MAX), GFP_KERNEL);
    - window = kmalloc(WSIZE, GFP_KERNEL);
    - if (!window || !header_buf || !symlink_buf || !name_buf)
    + if (!header_buf || !symlink_buf || !name_buf)
    panic("can't allocate buffers");
    state = Start;
    this_header = 0;
    @@ -401,16 +373,13 @@ static char * __init unpack_to_rootfs(ch
    continue;
    }
    this_header = 0;
    - outcnt = 0; /* bytes in output buffer */
    - bytes_out = 0;
    - cnt = gunzip(buf, len, NULL);
    + cnt = gunzip(buf, len, NULL, flush_buffer);
    if (state != Reset)
    error("junk in gzipped archive");
    this_header = saved_offset + cnt;
    buf += cnt;
    len -= cnt;
    }
    - kfree(window);
    kfree(name_buf);
    kfree(symlink_buf);
    kfree(header_buf);
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/
    \
     
     \ /
      Last update: 2005-10-31 22:08    [W:4.357 / U:0.260 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site