ftp://ftp.lnxi.com/pub/mkelfImage/mkelfImage-2.7.tar.gz Signed-off-by: Stefan Reinauer <stepan@coresystems.de> Acked-by: Stefan Reinauer <stepan@coresystems.de> git-svn-id: svn://svn.coreboot.org/coreboot/trunk@3103 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
		
			
				
	
	
		
			171 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			171 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include <string.h>
 | |
| #include <stdlib.h>
 | |
| 
 | |
| /*
 | |
|  * gzip support routine declartions..
 | |
|  * =========================================================
 | |
|  */
 | |
| 
 | |
| #ifdef DEBUG
 | |
| #  define Trace(x) 
 | |
| #  define Tracev(x)
 | |
| #  define Tracevv(x)
 | |
| #  define Tracec(c,x)
 | |
| #  define Tracecv(c,x)
 | |
| #  define DBG(x) printf x
 | |
| #else
 | |
| #  define Trace(x)
 | |
| #  define Tracev(x)
 | |
| #  define Tracevv(x)
 | |
| #  define Tracec(c,x)
 | |
| #  define Tracecv(c,x)
 | |
| #  define DBG(x)
 | |
| #endif
 | |
| 
 | |
| void error(char *str)
 | |
| {
 | |
| 	DBG(("%s\n", str));
 | |
| }
 | |
| 
 | |
| static unsigned char *inbuf;	/* input buffer */
 | |
| static unsigned int insize;	/* valid bytes in inbuf */
 | |
| static unsigned int inptr;	/* index of next byte to be processed in inbuf */
 | |
| 
 | |
| #if !defined(DEBUG)
 | |
| #define get_byte()  (inptr < insize ? inbuf[inptr++] : 0)
 | |
| #else
 | |
| static unsigned char get_byte(void)
 | |
| {
 | |
| 	static int count;
 | |
| 	unsigned char byte = (inptr < insize ? inbuf[inptr++] : 0);
 | |
| #if 0
 | |
| 	printf("%02x ", byte);
 | |
| 	if ((++count & 0x0f) == 0) {
 | |
| 		printf("\n");
 | |
| 	}
 | |
| #endif
 | |
| 	return byte;
 | |
| }
 | |
| 
 | |
| #endif
 | |
| 
 | |
| static void flush_window(void);
 | |
| 
 | |
| static long bytes_out;		/* total bytes compressed */
 | |
| static unsigned outcnt;		/* bytes in output buffer */
 | |
| 
 | |
| #define WSIZE 0x8000		/* Window size must be at least 32k, and a power of two */
 | |
| static unsigned char window[WSIZE];	/* Sliding window buffer */
 | |
| 
 | |
| /*
 | |
|  * gzip declarations
 | |
|  */
 | |
| 
 | |
| #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;
 | |
| 
 | |
| 
 | |
| 
 | |
| #include "inflate.c"
 | |
| 
 | |
| 
 | |
| /* Variables that gunzip doesn't need to see... */
 | |
| static unsigned char *output_ptr;
 | |
| static unsigned long end_offset;
 | |
| static struct unzip_region {
 | |
| 	unsigned long start;
 | |
| 	unsigned long end_offset;
 | |
| } unzip_region;
 | |
| 
 | |
| /* Data provided by the header */
 | |
| extern unsigned char zipped_data[];
 | |
| extern unsigned char zipped_data_end[];
 | |
| extern unsigned char entry;
 | |
| /* Assembly language routines */
 | |
| extern void jmp_to_program_entry(void *);
 | |
| 
 | |
| /* ===========================================================================
 | |
|  * Write the output window window[0..outcnt-1] and update crc and bytes_out.
 | |
|  * (Used for the decompressed data only.)
 | |
|  */
 | |
| static void flush_window(void)
 | |
| {
 | |
| 	ulg c = crc;		/* temporary variable */
 | |
| 	unsigned n;
 | |
| 	unsigned long limit;
 | |
| 	uch *in, *out, ch;
 | |
| 
 | |
| 	limit = outcnt;
 | |
| 
 | |
| 
 | |
| 	n = 0;
 | |
| 	in = window;
 | |
| 	while (n < outcnt) {
 | |
| 		limit = end_offset - bytes_out +n;
 | |
| 		if (limit > outcnt) {
 | |
| 			limit = outcnt;
 | |
| 		}
 | |
| 		out = output_ptr;
 | |
| 		DBG(("flush 0x%08lx start 0x%08lx limit 0x%08lx\n", 
 | |
| 			(unsigned long) out, (unsigned long)n, limit));
 | |
| 		for (; n < limit; n++) {
 | |
| 			ch = *out++ = *in++;
 | |
| 			c = crc_32_tab[((int) c ^ ch) & 0xff] ^ (c >> 8);
 | |
| 		}
 | |
| 		crc = c;
 | |
| 		bytes_out += (out - output_ptr);
 | |
| 		output_ptr = out;
 | |
| 		if (bytes_out == end_offset) {
 | |
| 			if (output_ptr == (unsigned char *)(&unzip_region+1)) {
 | |
| 				output_ptr = (unsigned char *)(unzip_region.start);
 | |
| 				end_offset = unzip_region.end_offset;
 | |
| 			} else {
 | |
| 				output_ptr = (unsigned char *)&unzip_region;
 | |
| 				end_offset += sizeof(unzip_region);
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	outcnt = 0;
 | |
| }
 | |
| 
 | |
| 
 | |
| void gunzip_setup(void)
 | |
| {
 | |
| 	DBG(("gunzip_setup\n"));
 | |
| 	outcnt = 0;
 | |
| 	bytes_out = 0;
 | |
| 
 | |
| 	end_offset = sizeof(unzip_region);
 | |
| 	output_ptr = (unsigned char *)&unzip_region;
 | |
| 
 | |
| 	inbuf = &zipped_data[0];
 | |
| 	insize = zipped_data_end - zipped_data;
 | |
| 	inptr = 0;
 | |
| 
 | |
| 	makecrc();
 | |
| 	DBG(("gunzip_setup_done\n"));
 | |
| }
 | |
| 
 | |
| 
 | |
| int kunzip(int argc, char **argv)
 | |
| {
 | |
| 	DBG(("kunzip\n"));
 | |
| 	gunzip_setup();
 | |
| 	DBG(("pre_gunzip\n"));
 | |
| 	if (gunzip() != 0) {
 | |
| 		error("gunzip failed");
 | |
| 		while(1) {}
 | |
| 		return -1;
 | |
| 	}
 | |
| 	DBG(("pre_jmp_to_program_entry: %p\n", &entry ));
 | |
| 	jmp_to_program_entry(&entry);
 | |
| 	return 0;
 | |
| }
 |