• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/src/linux/linux-2.6/arch/arm26/boot/compressed/
1/*
2 * misc.c
3 *
4 * This is a collection of several routines from gzip-1.0.3
5 * adapted for Linux.
6 *
7 * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
8 *
9 * Modified for ARM Linux by Russell King
10 *
11 * Nicolas Pitre <nico@visuaide.com>  1999/04/14 :
12 *  For this code to run directly from Flash, all constant variables must
13 *  be marked with 'const' and all other variables initialized at run-time
14 *  only.  This way all non constant variables will end up in the bss segment,
15 *  which should point to addresses in RAM and cleared to 0 on start.
16 *  This allows for a much quicker boot time.
17 */
18
19unsigned int __machine_arch_type;
20
21#include <linux/kernel.h>
22
23#include <asm/uaccess.h>
24#include "uncompress.h"
25
26#ifdef STANDALONE_DEBUG
27#define puts printf
28#endif
29
30#define __ptr_t void *
31
32/*
33 * Optimised C version of memzero for the ARM.
34 */
35void __memzero (__ptr_t s, size_t n)
36{
37	union { void *vp; unsigned long *ulp; unsigned char *ucp; } u;
38	int i;
39
40	u.vp = s;
41
42	for (i = n >> 5; i > 0; i--) {
43		*u.ulp++ = 0;
44		*u.ulp++ = 0;
45		*u.ulp++ = 0;
46		*u.ulp++ = 0;
47		*u.ulp++ = 0;
48		*u.ulp++ = 0;
49		*u.ulp++ = 0;
50		*u.ulp++ = 0;
51	}
52
53	if (n & 1 << 4) {
54		*u.ulp++ = 0;
55		*u.ulp++ = 0;
56		*u.ulp++ = 0;
57		*u.ulp++ = 0;
58	}
59
60	if (n & 1 << 3) {
61		*u.ulp++ = 0;
62		*u.ulp++ = 0;
63	}
64
65	if (n & 1 << 2)
66		*u.ulp++ = 0;
67
68	if (n & 1 << 1) {
69		*u.ucp++ = 0;
70		*u.ucp++ = 0;
71	}
72
73	if (n & 1)
74		*u.ucp++ = 0;
75}
76
77static inline __ptr_t memcpy(__ptr_t __dest, __const __ptr_t __src,
78			    size_t __n)
79{
80	int i = 0;
81	unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src;
82
83	for (i = __n >> 3; i > 0; i--) {
84		*d++ = *s++;
85		*d++ = *s++;
86		*d++ = *s++;
87		*d++ = *s++;
88		*d++ = *s++;
89		*d++ = *s++;
90		*d++ = *s++;
91		*d++ = *s++;
92	}
93
94	if (__n & 1 << 2) {
95		*d++ = *s++;
96		*d++ = *s++;
97		*d++ = *s++;
98		*d++ = *s++;
99	}
100
101	if (__n & 1 << 1) {
102		*d++ = *s++;
103		*d++ = *s++;
104	}
105
106	if (__n & 1)
107		*d++ = *s++;
108
109	return __dest;
110}
111
112/*
113 * gzip delarations
114 */
115#define OF(args)  args
116#define STATIC static
117
118typedef unsigned char  uch;
119typedef unsigned short ush;
120typedef unsigned long  ulg;
121
122#define WSIZE 0x8000		/* Window size must be at least 32k, */
123				/* and a power of two */
124
125static uch *inbuf;		/* input buffer */
126static uch window[WSIZE];	/* Sliding window buffer */
127
128static unsigned insize;		/* valid bytes in inbuf */
129static unsigned inptr;		/* index of next byte to be processed in inbuf */
130static unsigned outcnt;		/* bytes in output buffer */
131
132/* gzip flag byte */
133#define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
134#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
135#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
136#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
137#define COMMENT      0x10 /* bit 4 set: file comment present */
138#define ENCRYPTED    0x20 /* bit 5 set: file is encrypted */
139#define RESERVED     0xC0 /* bit 6,7:   reserved */
140
141#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
142
143/* Diagnostic functions */
144#ifdef DEBUG
145#  define Assert(cond,msg) {if(!(cond)) error(msg);}
146#  define Trace(x) fprintf x
147#  define Tracev(x) {if (verbose) fprintf x ;}
148#  define Tracevv(x) {if (verbose>1) fprintf x ;}
149#  define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
150#  define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
151#else
152#  define Assert(cond,msg)
153#  define Trace(x)
154#  define Tracev(x)
155#  define Tracevv(x)
156#  define Tracec(c,x)
157#  define Tracecv(c,x)
158#endif
159
160static int  fill_inbuf(void);
161static void flush_window(void);
162static void error(char *m);
163static void gzip_mark(void **);
164static void gzip_release(void **);
165
166extern char input_data[];
167extern char input_data_end[];
168
169static uch *output_data;
170static ulg output_ptr;
171static ulg bytes_out;
172
173static void *malloc(int size);
174static void free(void *where);
175static void error(char *m);
176static void gzip_mark(void **);
177static void gzip_release(void **);
178
179static void puts(const char *);
180
181extern int end;
182static ulg free_mem_ptr;
183static ulg free_mem_ptr_end;
184
185#define HEAP_SIZE 0x3000
186
187#include "../../../../lib/inflate.c"
188
189#ifndef STANDALONE_DEBUG
190static void *malloc(int size)
191{
192	void *p;
193
194	if (size <0) error("Malloc error");
195	if (free_mem_ptr <= 0) error("Memory error");
196
197	free_mem_ptr = (free_mem_ptr + 3) & ~3;	/* Align */
198
199	p = (void *)free_mem_ptr;
200	free_mem_ptr += size;
201
202	if (free_mem_ptr >= free_mem_ptr_end)
203		error("Out of memory");
204	return p;
205}
206
207static void free(void *where)
208{ /* gzip_mark & gzip_release do the free */
209}
210
211static void gzip_mark(void **ptr)
212{
213	arch_decomp_wdog();
214	*ptr = (void *) free_mem_ptr;
215}
216
217static void gzip_release(void **ptr)
218{
219	arch_decomp_wdog();
220	free_mem_ptr = (long) *ptr;
221}
222#else
223static void gzip_mark(void **ptr)
224{
225}
226
227static void gzip_release(void **ptr)
228{
229}
230#endif
231
232/* ===========================================================================
233 * Fill the input buffer. This is called only when the buffer is empty
234 * and at least one byte is really needed.
235 */
236int fill_inbuf(void)
237{
238	if (insize != 0)
239		error("ran out of input data");
240
241	inbuf = input_data;
242	insize = &input_data_end[0] - &input_data[0];
243
244	inptr = 1;
245	return inbuf[0];
246}
247
248/* ===========================================================================
249 * Write the output window window[0..outcnt-1] and update crc and bytes_out.
250 * (Used for the decompressed data only.)
251 */
252void flush_window(void)
253{
254	ulg c = crc;
255	unsigned n;
256	uch *in, *out, ch;
257
258	in = window;
259	out = &output_data[output_ptr];
260	for (n = 0; n < outcnt; n++) {
261		ch = *out++ = *in++;
262		c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
263	}
264	crc = c;
265	bytes_out += (ulg)outcnt;
266	output_ptr += (ulg)outcnt;
267	outcnt = 0;
268	puts(".");
269}
270
271static void error(char *x)
272{
273	int ptr;
274
275	puts("\n\n");
276	puts(x);
277	puts("\n\n -- System halted");
278
279	while(1);	/* Halt */
280}
281
282#ifndef STANDALONE_DEBUG
283
284ulg
285decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p,
286		  int arch_id)
287{
288	output_data		= (uch *)output_start;	/* Points to kernel start */
289	free_mem_ptr		= free_mem_ptr_p;
290	free_mem_ptr_end	= free_mem_ptr_end_p;
291	__machine_arch_type	= arch_id;
292
293	arch_decomp_setup();
294
295	makecrc();
296	puts("Uncompressing Linux...");
297	gunzip();
298	puts(" done, booting the kernel.\n");
299	return output_ptr;
300}
301#else
302
303char output_buffer[1500*1024];
304
305int main()
306{
307	output_data = output_buffer;
308
309	makecrc();
310	puts("Uncompressing Linux...");
311	gunzip();
312	puts("done.\n");
313	return 0;
314}
315#endif
316
317