1
/* TILO: The TFTP Image LOader
3
Copyright (C) 1996 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
28
#define MOVED_BASE 0x3c0000
30
#define MOVED_BASE 0x4c0000
40
#define memzero(s, n) memset ((s), 0, (n))
42
typedef unsigned char uch;
43
typedef unsigned short ush;
44
typedef unsigned long ulg;
46
#define WSIZE 0x8000 /* Window size must be at least 32k, */
47
/* and a power of two */
48
static uch window[WSIZE]; /* Sliding window buffer */
50
static unsigned outcnt = 0; /* bytes in output buffer */
53
#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
54
#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
55
#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
56
#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
57
#define COMMENT 0x10 /* bit 4 set: file comment present */
58
#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
59
#define RESERVED 0xC0 /* bit 6,7: reserved */
61
#define Assert(cond,msg)
68
static void flush_window (void);
69
static void error (char *);
70
#define gzip_mark mark
71
inline void gzip_release (void **p)
76
static long bytes_out;
77
static uch *output_data, *output_limit;
78
static unsigned char (*get_input_fun) (void);
79
static void (*unget_input_fun) (void);
82
#define get_byte() (*get_input_fun)()
83
#define unget_byte() (*unget_input_fun)()
85
#include "../common/inflate.c"
87
static void error (char *m)
89
printf ("\nDecompression error: %s\n", m);
90
longjmp (gunzip_env, 1);
93
static void flush_window ()
99
if (output_data + outcnt > output_limit)
100
error ("uncompressed image too long - wouldn't fit into destination");
101
for (n = 0; n < outcnt; n++) {
102
ch = *output_data++ = *in++;
103
c = crc_32_tab[((int) c ^ ch) & 0xff] ^ (c >> 8);
106
bytes_out += (ulg) outcnt;
110
int decompress (char *outptr, char *outptrlim, unsigned char (*get_input) (void), void (*unget_input) (void))
113
static int first = 1;
115
gzip_mark (&save_ptr);
117
if (setjmp (gunzip_env)) {
118
gzip_release (&save_ptr);
121
output_data = (unsigned char *)outptr;
122
output_limit = (unsigned char *)outptrlim;
123
get_input_fun = get_input;
124
unget_input_fun = unget_input;
132
gzip_release (&save_ptr);
134
printf("Returning from decompress()\n");
139
static unsigned char *gzminp;
140
static unsigned char get_input(void)
145
static void unget_input(void)
150
extern char start, main_text_start, main_text_end, main_data_start, main_data_end, main_rodata_start, main_rodata_end, __bss_start;
154
unsigned packed_start;
156
unsigned unpacked_len; /* this is meaningful for the kernel images only */
157
unsigned root_start; /* this is meaningful for the kernel images only */
160
extern struct ImageInfo image_table[4]; /* Sun4 kernel, Sun4c/d/m kernel, Sun4u kernel, root image */
162
#define SUN4_KERNEL 0
163
#define SUN4C_KERNEL 1
164
#define SUN4U_KERNEL 2
167
#define HDRS_TAG (('H'<<24) | ('d'<<16) | ('r'<<8) | 'S')
169
char *my_main (struct linux_romvec *promvec, void *cifh, void *cifs)
171
char *orig_code,*moved_code,*moved_ramdisk,*moved_kernel,*kernel_base;
172
unsigned *p,*q = NULL;
175
prom_init(promvec, cifh, cifs);
181
kernel_number = SUN4U_KERNEL; /* Sun4u */
182
printf("Selecting sun4u kernel...\n");
184
else if ((long)promvec == 0x4000)
186
kernel_number = SUN4_KERNEL; /* Sun4 */
187
printf("Selecting sun4 kernel...\n");
191
kernel_number = SUN4C_KERNEL; /* Sun4c/d/m */
192
printf("Selecting sun4cdm kernel...\n");
195
if (image_table[kernel_number].packed_len == 0)
197
printf ("ERROR: No kernel for this architecture in this TILO image\n");
201
orig_code = (char*) 0x4000;
202
moved_code = (char*) MOVED_BASE;
203
moved_ramdisk = (char*)((long)(moved_code - image_table[ROOT_IMAGE].packed_len) & ~0xfff);
204
moved_kernel = (char*)((long)(moved_ramdisk - image_table[kernel_number].packed_len) & ~0xfff);
206
printf("Locations: moved_code=%x moved_ramdisk=%x moved_kernel=%x\n",
207
moved_code, moved_ramdisk, moved_kernel);
209
memmove (moved_ramdisk, orig_code + image_table[ROOT_IMAGE].packed_start, image_table[ROOT_IMAGE].packed_len);
210
memmove (moved_kernel, orig_code + image_table[kernel_number].packed_start, image_table[kernel_number].packed_len);
212
gzminp = (unsigned char *)moved_kernel; /* decompress kernel */
213
kernel_base = (char*) 0x4000;
215
if (decompress (kernel_base, kernel_base + ((image_table[kernel_number].unpacked_len
216
+ 0xfff) & ~0xfff), get_input, unget_input) == -1)
218
printf ("\nKernel decompression error\n");
222
switch (kernel_number)
225
/* find HdrS in Sun4u kernel */
226
q = (unsigned*)kernel_base + 2;
230
/* find HdrS in Sun4c/m/d kernel */
231
p = (unsigned*)kernel_base;
232
p += *p & 0xffff; /* extract jump offset */
233
q = p - 16; /* from the branch instruction */
235
while (q < p && *q != HDRS_TAG)
240
/* find HdrS in Sun4 kernel */
241
printf ("Sun4 kernel not supported yet\n");
249
printf ("Can't find HdrS tag in kernel\n");
253
/* reset root flags */
255
/* Set root device and flags. Basically read-write. 0x0100 is ramdisk */
257
q[4] = image_table[kernel_number].root_start;
258
q[5] = image_table[ROOT_IMAGE].packed_len;
260
/* move root image */
261
memmove ((void*)(image_table[kernel_number].root_start & 0x3fffff),
262
moved_ramdisk, image_table[ROOT_IMAGE].packed_len);
264
printf("Returning from my_main() with address %x\n", kernel_base);
266
return kernel_base; /* return address to jump into kernel */