1
/* Self decompression and image decompression routines
3
Copyright (C) 1993 Hannu Savolainen
4
1996,1998 Jakub Jelinek
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or
9
(at your option) any later version.
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
GNU General Public License for more details.
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
24
#define NULL (void *)0
34
#define memzero(s, n) memset ((s), 0, (n))
36
typedef unsigned char uch;
37
typedef unsigned short ush;
38
typedef unsigned long ulg;
40
#define WSIZE 0x8000 /* Window size must be at least 32k, */
41
/* and a power of two */
42
static uch window[WSIZE]; /* Sliding window buffer */
44
static unsigned outcnt = 0; /* bytes in output buffer */
47
#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
48
#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
49
#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
50
#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
51
#define COMMENT 0x10 /* bit 4 set: file comment present */
52
#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
53
#define RESERVED 0xC0 /* bit 6,7: reserved */
55
#define Assert(cond,msg)
62
static void flush_window (void);
63
static void error (char *);
64
#define gzip_mark mark
65
inline void gzip_release (void **p)
70
static long bytes_out;
71
static uch *output_data, *output_limit;
72
static unsigned char (*get_input_fun) (void);
73
static void (*unget_input_fun) (void);
76
#define get_byte() (*get_input_fun)()
77
#define unget_byte() (*unget_input_fun)()
79
#include "../common/inflate.c"
81
static void error (char *m)
83
printf ("\nDecompression error: %s\n", m);
84
longjmp (gunzip_env, 1);
87
static void flush_window ()
93
if (output_data + outcnt > output_limit)
94
error ("uncompressed image too long - wouldn't fit into destination");
95
for (n = 0; n < outcnt; n++) {
96
ch = *output_data++ = *in++;
97
c = crc_32_tab[((int) c ^ ch) & 0xff] ^ (c >> 8);
100
bytes_out += (ulg) outcnt;
104
int decompress (char *outptr, char *outptrlim, unsigned char (*get_input) (void), void (*unget_input) (void))
107
static int first = 1;
109
gzip_mark (&save_ptr);
110
if (setjmp (gunzip_env)) {
111
gzip_release (&save_ptr);
114
output_data = (uch *)outptr;
115
output_limit = (uch *)outptrlim;
116
get_input_fun = get_input;
117
unget_input_fun = unget_input;
125
gzip_release (&save_ptr);
129
static unsigned char *gzminp;
130
static unsigned char get_input(void)
135
static void unget_input(void)
140
extern char main_text_start, main_text_end, main_data_start, main_data_end, main_rodata_start, main_rodata_end, __bss_start;
142
/* This has to be in data section, so that it does not get cleared. See crt0.S for details. */
143
unsigned char *gzminpi = (unsigned char *)0xdeadbeef;
145
extern int bootmain(void);
147
unsigned my_main(struct linux_romvec *promvec, void *cifh, void *cifs)
149
prom_init(promvec, cifh, cifs);
152
prom_puts ("SILO", 4);
157
printf(" Version %s\n", VERSION);
160
unsigned short *pt = (unsigned short *)gzminpi;
166
gzminpi = (unsigned char *)pt;
169
if (decompress ((char *)0x200000, (char *)&_start, get_input, unget_input) == -1) {
170
printf ("\nInternal error\n");
173
memcpy (&main_text_start, (char *)0x200000, &main_text_end - &main_text_start);
174
memcpy (&main_rodata_start, (char *)0x200000 + (&main_text_end - &main_text_start), &main_rodata_end - &main_rodata_start);
175
memcpy (&main_data_start, (char *)0x200000 + (&main_text_end - &main_text_start) + (&main_rodata_end - &main_rodata_start), &main_data_end - &main_data_start);
177
unsigned char *cp = (unsigned char *)LARGE_RELOC;
178
unsigned short *pt = (unsigned short *)((char *)0x200000 + (&main_text_end - &main_text_start) +
179
(&main_rodata_end - &main_rodata_start) + (&main_data_end - &main_data_start));
187
cp = (unsigned char *)LARGE_RELOC;