ppc32: Switch arch/ppc/boot to zlib_inflate
PATCH 1/1 ppc32: Switch arch/ppc/boot to zlib_inflate
The following patch switches arch/ppc/boot over from using its own version of zlib to the code found under lib/zlib_inflate. The plus side to this, is one less version of zlib stuff around in the kernel. The downside is that the zlib code is ~8kB larger now, so I'm not sure if this is a good idea. This has been tested on both a Motorola LoPEC (which exercised the misc-common parts) and a pmac (which exercised the openfirmware/common.c parts).
Sam, any kbuild comments? I'm assuming that this is the best way to get these files built here.
arch/ppc/boot/lib/Makefile +14 -1
@@ -4,5 +4,18 @@ CFLAGS_kbd.o += -Idrivers/char -lib-y := zlib.o div64.o +$(obj)/infblock.o: lib/zlib_inflate/infblock.c + $(call cmd,cc_o_c) +$(obj)/infcodes.o: lib/zlib_inflate/infcodes.c + $(call cmd,cc_o_c) +$(obj)/inffast.o: lib/zlib_inflate/inffast.c + $(call cmd,cc_o_c) +$(obj)/inflate.o: lib/zlib_inflate/inflate.c + $(call cmd,cc_o_c) +$(obj)/inftrees.o: lib/zlib_inflate/inftrees.c + $(call cmd,cc_o_c) +$(obj)/infutil.o: lib/zlib_inflate/infutil.c + $(call cmd,cc_o_c) + +lib-y := infblock.o infcodes.o inffast.o inflate.o inftrees.o infutil.o div64.o lib-$(CONFIG_VGA_CONSOLE) += vreset.o kbd.o
arch/ppc/boot/lib/zlib.c deleted +0 -2169
2,169 lines not on this page · raw message
arch/ppc/boot/common/misc-common.c +9 -16
@@ -17,7 +17,7 @@#include <stdarg.h> /* for va_ bits */ #include <linux/config.h> #include <linux/string.h> -#include "zlib.h" +#include <linux/zlib.h> #include "nonstdio.h" /* If we're on a PReP, assume we have a keyboard controller
@@ -202,11 +202,10 @@ void error(char *x)while (1 );/* Halt */ } -void *zalloc (void *x,unsigned items,unsigned size) +static void *zalloc (unsigned size) {void *p = avail_ram; - size *= items; size = (size +7 ) &-8 ; avail_ram += size;if (avail_ram > end_avail) {
@@ -216,18 +215,12 @@ void *zalloc(void *x, unsigned items, unreturn p; } -void zfree (void *x,void *addr,unsigned nb) -{ -} -#define HEAD_CRC 2#define EXTRA_FIELD 4#define ORIG_NAME 8#define COMMENT 0x10#define RESERVED 0xe0 -#define DEFLATED 8 -void gunzip (void *dst,int dstlen,unsigned char *src,int *lenp) {z_stream s;
@@ -236,7 +229,7 @@ void gunzip(void *dst, int dstlen, unsig/* skip header */ i =10 ; flags = src[3 ]; -if (src[2 ] !=DEFLATED || (flags &RESERVED ) !=0 ) { +if (src[2 ] !=Z_DEFLATED || (flags &RESERVED ) !=0 ) {puts ("bad gzipped data\n" );exit (); }
@@ -255,24 +248,24 @@ void gunzip(void *dst, int dstlen, unsigexit (); } - s.zalloc = zalloc; - s.zfree = zfree; - r =inflateInit2 (&s, -MAX_WBITS ); +/* Initialize ourself. */ + s.workspace =zalloc (zlib_inflate_workspacesize ()); + r =zlib_inflateInit2 (&s, -MAX_WBITS );if (r !=Z_OK ) { -puts ("inflateInit2 returned " );puthex (r);puts ("\n" ); +puts ("zlib_inflateInit2 returned " );puthex (r);puts ("\n" );exit (); } s.next_in = src + i; s.avail_in = *lenp - i; s.next_out = dst; s.avail_out = dstlen; - r =inflate (&s,Z_FINISH ); + r =zlib_inflate (&s,Z_FINISH );if (r !=Z_OK && r !=Z_STREAM_END ) {puts ("inflate returned " );puthex (r);puts ("\n" );exit (); } *lenp = s.next_out - (unsigned char *) dst; -inflateEnd (&s); +zlib_inflateEnd (&s); }void
arch/ppc/boot/openfirmware/coffmain.c +0 -1
@@ -12,7 +12,6 @@#include "nonstdio.h" #include "of1275.h" -#include "zlib.h" /* Passed from the linker */ extern char __image_begin, __image_end;
arch/ppc/boot/simple/misc-embedded.c +0 -1
@@ -22,7 +22,6 @@#endif #include "nonstdio.h" -#include "zlib.h" /* The linker tells us where the image is. */ extern char __image_begin, __image_end;
arch/ppc/boot/openfirmware/common.c +43 -61
139 lines not on this page · raw message
arch/ppc/boot/simple/misc.c +1 -2
@@ -29,7 +29,6 @@#include <asm/reg.h> #include "nonstdio.h" -#include "zlib.h" /* Default cmdline */ #ifdef CONFIG_CMDLINE
@@ -220,7 +219,7 @@ decompress_kernel(unsigned long load_addputs ("\n" );puts ("Uncompressing Linux..." ); -gunzip (NULL ,0x400000 , zimage_start, &zimage_size); +gunzip (0x0 ,0x400000 , zimage_start, &zimage_size);puts ("done.\n" );/* get the bi_rec address */
arch/ppc/boot/include/zlib.h deleted +0 -430
430 lines not on this page · raw message
Signature · 2 lines
Tom Rini http://gate.crashing.org/~trini/
RFC PATCH 1/2 zlib_inflate: Move zlib_inflateSync & friends
Quoted 5 lines · Tom Rini
The following patch switches
arch/ppc/bootover from using its own version of zlib to the code found underlib/zlib_inflate. The plus side to this, is one less version of zlib stuff around in the kernel. The downside is that the zlib code is ~8kB larger now, so I'm not sure if this is a good idea.
So, to try and get around this growth in size, I decided to see how bad things would look, and how much it would take, to get the size back down to what it was. After messing around, I've come up with two patches, which in the end shrink the overall size slightly. The first, and I hope least objectionable is to move zlib_inflateSync, and related bits used by PPP into inflate_sync.c. This saves us 169 bytes.
lib/zlib_inflate/inflate_sync.c new file +148 -0
@@ -0,0 +1,148 @@ +/* inflate.c -- zlib interface to inflate modules +* Copyright (C) 1995-1998 Mark Adler +* For conditions of distribution and use, see copyright notice in zlib.h +*/ + +#include <linux/zutil.h> +#include "infblock.h" +#include "infutil.h" + +int zlib_inflateSync ( +z_streamp z +) +{ +uInt n;/* number of bytes to look at */ +Byte *p;/* pointer to bytes */ +uInt m;/* number of marker bytes found in a row */ +uLong r, w;/* temporaries to save total_in and total_out */ + +/* set up */ +if (z ==NULL || z->state ==NULL ) +return Z_STREAM_ERROR ; +if (z->state->mode !=I_BAD ) + { + z->state->mode =I_BAD ; + z->state->sub.marker =0 ; + } +if ((n = z->avail_in) ==0 ) +return Z_BUF_ERROR ; + p = z->next_in; + m = z->state->sub.marker; + +/* search */ +while (n && m <4 ) + { +static const Byte mark[4 ] = {0 ,0 ,0xff ,0xff }; +if (*p == mark[m]) + m++; +else if (*p) + m =0 ; +else + m =4 - m; + p++, n--; + } + +/* restore */ + z->total_in += p - z->next_in; + z->next_in = p; + z->avail_in = n; + z->state->sub.marker = m; + +/* return no joy or set up to restart on a new block */ +if (m !=4 ) +return Z_DATA_ERROR ; + r = z->total_in; w = z->total_out; +zlib_inflateReset (z); + z->total_in = r; z->total_out = w; + z->state->mode =BLOCKS ; +return Z_OK ; +} + + +/* Returns true if inflate is currently at the end of a block generated +* by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP +* implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH +* but removes the length bytes of the resulting empty stored block. When +* decompressing, PPP checks that at the end of input packet, inflate is +* waiting for these length bytes. +*/ +int zlib_inflateSyncPoint ( +z_streamp z +) +{ +if (z ==NULL || z->state ==NULL || z->state->blocks ==NULL ) +return Z_STREAM_ERROR ; +return zlib_inflate_blocks_sync_point (z->state->blocks); +} + +/* +* This subroutine adds the data at next_in/avail_in to the output history +* without performing any output. The output buffer must be "caught up"; +* i.e. no pending output (hence s->read equals s->write), and the state must +* be BLOCKS (i.e. we should be willing to see the start of a series of +* BLOCKS). On exit, the output will also be caught up, and the checksum +* will have been updated if need be. +*/ +static int zlib_inflate_addhistory (inflate_blocks_statef *s, +z_stream *z) +{ +uLong b;/* bit buffer */ /* NOT USED HERE */ +uInt k;/* bits in bit buffer */ /* NOT USED HERE */ +uInt t;/* temporary storage */ +Byte *p;/* input data pointer */ +uInt n;/* bytes available there */ +Byte *q;/* output window write pointer */ +uInt m;/* bytes to end of window or read pointer */ + +if (s->read != s->write) +return Z_STREAM_ERROR ; +if (s->mode !=TYPE ) +return Z_DATA_ERROR ; + +/* we're ready to rock */ +LOAD +/* while there is input ready, copy to output buffer, moving +* pointers as needed. +*/ + while (n) { + t = n;/* how many to do */ +/* is there room until end of buffer? */ +if (t > m) t = m; +/* update check information */ +if (s->checkfn !=NULL ) + s->check = (*s->checkfn)(s->check, q, t); +memcpy (q, p, t); + q += t; + p += t; + n -= t; + z->total_out += t; + s->read = q;/* drag read pointer forward */ +/* WWRAP */ /* expand WWRAP macro by hand to handle s->read */ +if (q == s->end) { + s->read = q = s->window; + m =WAVAIL ; + } + } +UPDATE + return Z_OK; +} + + +/* +* This subroutine adds the data at next_in/avail_in to the output history +* without performing any output. The output buffer must be "caught up"; +* i.e. no pending output (hence s->read equals s->write), and the state must +* be BLOCKS (i.e. we should be willing to see the start of a series of +* BLOCKS). On exit, the output will also be caught up, and the checksum +* will have been updated if need be. +*/ + +int zlib_inflateIncomp ( +z_stream *z + +) +{ +if (z->state->mode !=BLOCKS ) +return Z_DATA_ERROR ; +return zlib_inflate_addhistory (z->state->blocks, z); +}
lib/zlib_inflate/Makefile +1 -1
@@ -16,4 +16,4 @@ obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate.o zlib_inflate-objs := infblock.o infcodes.o inffast.o inflate.o \ - inftrees.o infutil.o inflate_syms.o + inflate_sync.o inftrees.o infutil.o inflate_syms.o
lib/zlib_inflate/inflate.c +0 -141
144 lines not on this page · raw message
Signature · 2 lines
Tom Rini http://gate.crashing.org/~trini/
RFC PATCH 2/2 zlib_inflate: Add __BOOTER__ around zlib_inflate_trees_fixed(...)
Quoted 8 lines · Tom Rini
Quoted 5 lines · Tom Rini
The following patch switches
arch/ppc/bootover from using its own version of zlib to the code found underlib/zlib_inflate. The plus side to this, is one less version of zlib stuff around in the kernel. The downside is that the zlib code is ~8kB larger now, so I'm not sure if this is a good idea.
Quoted 6 lines
So, to try and get around this growth in size, I decided to see how bad things would look, and how much it would take, to get the size back down to what it was. After messing around, I've come up with two patches, which in the end shrink the overall size slightly. The first, and I hope least objectionable is to move
zlib_inflateSync, and related bits used by PPP intoinflate_sync.c. This saves us 169 bytes.
This is the second part of what I found. zlib_inflate_trees_fixed(...) isn't called in decompressing a kernel. Dropping this, and the call to it saves ~8kB. __BOOTER__ is a flag already passed along during the build of arch/ppc/boot/. But, I'm going to guess doing it this way is just too ugly. zlib_inflate_trees_fixed(...) itself could be moved into another file, but that leaves the problem of having to provide some sort of stub function, and perhaps making zlib_inflate_trees_fixed return Z_OK (real version) or Z_STREAM_ERROR (stub).
Or if anyone else has a better idea, I'd be glad to give that a shot. Thanks.
lib/zlib_inflate/infblock.c +2 -0
@@ -134,6 +134,7 @@ int zlib_inflate_blocks(DUMPBITS (t) s->mode = LENS; /* get length of stored block */break ; +#ifndef __BOOTER__case 1 :/* fixed */ {uInt bl, bd;
@@ -150,6 +151,7 @@ int zlib_inflate_blocks(DUMPBITS (3 ) s->mode = CODES;break ; +#endif case 2 :/* dynamic */ DUMPBITS (3 ) s->mode = TABLE;
lib/zlib_inflate/inftrees.c +2 -0
@@ -374,6 +374,7 @@ int zlib_inflate_trees_dynamic( } +#ifndef __BOOTER__/* build fixed tables only once--keep them here */ #include "inffixed.h"
@@ -392,3 +393,4 @@ int zlib_inflate_trees_fixed( *td = fixed_td; return Z_OK; } +#endif
Signature · 2 lines
Tom Rini http://gate.crashing.org/~trini/
Re: [PATCH,RFC 2.6.9-rc1 2/2] zlib_inflate: Add __BOOTER__ around zlib_inflate_trees_fixed(...)
Quoted 2 lines · Tom Rini
This is the second part of what I found.
zlib_inflate_trees_fixed(...)isn't called in decompressing a kernel. Dropping this, and the call to
I think it is just luck that gzip hasn't used the fixed table in compressing the kernel. I don't think we have any guarantee that gzip won't use the fixed table.
Just out of interest, how big is a bzip2 decompressor?
Regards,
Paul.
Re: [PATCH,RFC 2.6.9-rc1 2/2] zlib_inflate: Add __BOOTER__ around zlib_inflate_trees_fixed(...)
Quoted 8 lines · Paul Mackerras
Quoted 2 lines · Tom Rini
This is the second part of what I found.
zlib_inflate_trees_fixed(...)isn't called in decompressing a kernel. Dropping this, and the call toI think it is just luck that gzip hasn't used the fixed table in compressing the kernel. I don't think we have any guarantee that gzip won't use the fixed table.
That is a good point. Looking at arch/ppc/boot/lib/zlib.c it generates the table, instead of having a static one. So perhaps we should move to that instead for lib/zlib_inflate ?
Signature · 2 lines
Tom Rini http://gate.crashing.org/~trini/
Re: [PATCH,RFC 2.6.9-rc1 2/2] zlib_inflate: Add __BOOTER__ around zlib_inflate_trees_fixed(...)
Quoted 7 lines · Tom Rini
Quoted 5 lines · Paul Mackerras
Quoted 2 lines · Tom Rini
This is the second part of what I found.
zlib_inflate_trees_fixed(...)isn't called in decompressing a kernel. Dropping this, and the call to
Quoted 7 lines
Quoted 3 lines
I think it is just luck that gzip hasn't used the fixed table in compressing the kernel. I don't think we have any guarantee that gzip won't use the fixed table.
That is a good point. Looking at
arch/ppc/boot/lib/zlib.cit generates the table, instead of having a static one. So perhaps we should move to that instead forlib/zlib_inflate?
I've moved lib/zlib_inflate over to generating the table. But, in trying to test it, I haven't been able to find anything that will actually use this (it appears that using this static table was something that pkzip introduced long ago as an alternative method of good compression / speed) so I can't actually test it. But the image size is back in line.
Signature · 2 lines
Tom Rini http://gate.crashing.org/~trini/