~ubuntu-branches/ubuntu/precise/silo/precise

« back to all changes in this revision

Viewing changes to tilo/tilo.c

  • Committer: Bazaar Package Importer
  • Author(s): Fabio M. Di Nitto
  • Date: 2007-10-25 09:28:08 UTC
  • mfrom: (15.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20071025092808-1yhj12t7s4zqsfu5
Tags: 1.4.13a+git20070930-1ubuntu1
* Merge from debian unstable, remaining changes:
  - Build with -fno-stack-protector.
  - Change silo.postinst to automatically update the boot block without
    invoking siloconfig and keep asking questions on upgrades.
  - Convert silo.conf to use /dev/disk/by-uuid.
  - Ubuntu maintainer foobar.
  - Fix debian/rules call to dh_installdocs.
  - Drop the requirement of gcc-4.1 and start using default gcc.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* TILO: The TFTP Image LOader
 
2
   
 
3
   Copyright (C) 1996 Jakub Jelinek
 
4
                 1998 Jan Vondrak
 
5
   
 
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.
 
10
   
 
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.
 
15
 
 
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,
 
19
   USA.  */
 
20
 
 
21
#include <silo.h>
 
22
#include <setjmp.h>
 
23
#ifndef NULL
 
24
#define NULL (void *)0
 
25
#endif
 
26
 
 
27
#ifndef LARGETILO
 
28
#define MOVED_BASE 0x3c0000
 
29
#else
 
30
#define MOVED_BASE 0x4c0000
 
31
#endif
 
32
 
 
33
/*
 
34
 * gzip declarations
 
35
 */
 
36
 
 
37
#define OF(args)  args
 
38
#define STATIC static
 
39
 
 
40
#define memzero(s, n)     memset ((s), 0, (n))
 
41
 
 
42
typedef unsigned char uch;
 
43
typedef unsigned short ush;
 
44
typedef unsigned long ulg;
 
45
 
 
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 */
 
49
 
 
50
static unsigned outcnt = 0;     /* bytes in output buffer */
 
51
 
 
52
/* gzip flag byte */
 
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 */
 
60
 
 
61
#define Assert(cond,msg)
 
62
#define Trace(x)
 
63
#define Tracev(x)
 
64
#define Tracevv(x)
 
65
#define Tracec(c,x)
 
66
#define Tracecv(c,x)
 
67
 
 
68
static void flush_window (void);
 
69
static void error (char *);
 
70
#define gzip_mark mark
 
71
inline void gzip_release (void **p)
 
72
{
 
73
    release (*p);
 
74
}
 
75
 
 
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);
 
80
 
 
81
jmp_buf gunzip_env;
 
82
#define get_byte() (*get_input_fun)()
 
83
#define unget_byte() (*unget_input_fun)()
 
84
 
 
85
#include "../common/inflate.c"
 
86
 
 
87
static void error (char *m)
 
88
{
 
89
    printf ("\nDecompression error: %s\n", m);
 
90
    longjmp (gunzip_env, 1);
 
91
}
 
92
 
 
93
static void flush_window ()
 
94
{
 
95
    ulg c = crc;
 
96
    unsigned n;
 
97
    uch *in, ch;
 
98
    in = 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);
 
104
    }
 
105
    crc = c;
 
106
    bytes_out += (ulg) outcnt;
 
107
    outcnt = 0;
 
108
}
 
109
 
 
110
int decompress (char *outptr, char *outptrlim, unsigned char (*get_input) (void), void (*unget_input) (void))
 
111
{
 
112
    void *save_ptr;
 
113
    static int first = 1;
 
114
 
 
115
    gzip_mark (&save_ptr);
 
116
   
 
117
    if (setjmp (gunzip_env)) {
 
118
        gzip_release (&save_ptr);
 
119
        return -1;
 
120
    }
 
121
    output_data = (unsigned char *)outptr;
 
122
    output_limit = (unsigned char *)outptrlim;
 
123
    get_input_fun = get_input;
 
124
    unget_input_fun = unget_input;
 
125
    bytes_out = 0;
 
126
    crc = 0xffffffffL;
 
127
    if (first) {
 
128
        makecrc ();
 
129
        first = 0;
 
130
    }
 
131
    gunzip ();
 
132
    gzip_release (&save_ptr);
 
133
#ifdef TILO_DEBUG
 
134
    printf("Returning from decompress()\n");
 
135
#endif
 
136
    return bytes_out;
 
137
}
 
138
 
 
139
static unsigned char *gzminp;
 
140
static unsigned char get_input(void)
 
141
{
 
142
    return *gzminp++;
 
143
}
 
144
 
 
145
static void unget_input(void)
 
146
{
 
147
    gzminp--;
 
148
}
 
149
 
 
150
extern char start, main_text_start, main_text_end, main_data_start, main_data_end, main_rodata_start, main_rodata_end, __bss_start;
 
151
 
 
152
struct ImageInfo
 
153
{
 
154
unsigned packed_start;
 
155
unsigned packed_len;
 
156
unsigned unpacked_len;          /* this is meaningful for the kernel images only */
 
157
unsigned root_start;            /* this is meaningful for the kernel images only */
 
158
};
 
159
 
 
160
extern struct ImageInfo image_table[4]; /* Sun4 kernel, Sun4c/d/m kernel, Sun4u kernel, root image */
 
161
 
 
162
#define SUN4_KERNEL     0
 
163
#define SUN4C_KERNEL    1
 
164
#define SUN4U_KERNEL    2
 
165
#define ROOT_IMAGE      3
 
166
 
 
167
#define HDRS_TAG        (('H'<<24) | ('d'<<16) | ('r'<<8) | 'S')
 
168
 
 
169
char *my_main (struct linux_romvec *promvec, void *cifh, void *cifs)
 
170
{
 
171
char *orig_code,*moved_code,*moved_ramdisk,*moved_kernel,*kernel_base;
 
172
unsigned *p,*q = NULL;
 
173
int kernel_number;
 
174
 
 
175
    prom_init(promvec, cifh, cifs);
 
176
    
 
177
    printf ("TILO\n");
 
178
 
 
179
    if (cifh)
 
180
        {
 
181
        kernel_number = SUN4U_KERNEL;           /* Sun4u */
 
182
        printf("Selecting sun4u kernel...\n");
 
183
        }
 
184
    else if ((long)promvec == 0x4000)
 
185
        {
 
186
        kernel_number = SUN4_KERNEL;            /* Sun4 */
 
187
        printf("Selecting sun4 kernel...\n");
 
188
        }
 
189
    else
 
190
        {
 
191
        kernel_number = SUN4C_KERNEL;           /* Sun4c/d/m */
 
192
        printf("Selecting sun4cdm kernel...\n");
 
193
        }
 
194
        
 
195
    if (image_table[kernel_number].packed_len == 0)
 
196
        {
 
197
        printf ("ERROR: No kernel for this architecture in this TILO image\n");
 
198
        prom_halt ();
 
199
        }
 
200
                                        
 
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);
 
205
#ifdef TILO_DEBUG
 
206
    printf("Locations: moved_code=%x  moved_ramdisk=%x moved_kernel=%x\n",
 
207
           moved_code, moved_ramdisk, moved_kernel);
 
208
#endif
 
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);
 
211
 
 
212
    gzminp = (unsigned char *)moved_kernel;             /* decompress kernel */
 
213
    kernel_base = (char*) 0x4000;
 
214
 
 
215
    if (decompress (kernel_base, kernel_base + ((image_table[kernel_number].unpacked_len
 
216
                 + 0xfff) & ~0xfff), get_input, unget_input) == -1)
 
217
        {
 
218
        printf ("\nKernel decompression error\n");
 
219
        prom_halt();
 
220
        }
 
221
 
 
222
    switch (kernel_number)
 
223
        {
 
224
        case SUN4U_KERNEL:
 
225
                                                /* find HdrS in Sun4u kernel */
 
226
                q = (unsigned*)kernel_base + 2;
 
227
                break;
 
228
    
 
229
        case SUN4C_KERNEL:
 
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 */
 
234
                                                
 
235
                while (q < p && *q != HDRS_TAG)
 
236
                        q++;
 
237
                break;
 
238
                
 
239
        default:
 
240
                                                /* find HdrS in Sun4 kernel */
 
241
                printf ("Sun4 kernel not supported yet\n");
 
242
                prom_halt ();
 
243
                break;
 
244
        
 
245
        }
 
246
 
 
247
    if (*q != HDRS_TAG)
 
248
        {
 
249
        printf ("Can't find HdrS tag in kernel\n");
 
250
        prom_halt ();
 
251
        }
 
252
 
 
253
    /* reset root flags */
 
254
    q[2] &= 0xffff0000;
 
255
    /* Set root device and flags. Basically read-write. 0x0100 is ramdisk */
 
256
    q[3] = 0x01000000;
 
257
    q[4] = image_table[kernel_number].root_start;
 
258
    q[5] = image_table[ROOT_IMAGE].packed_len;
 
259
 
 
260
                                                /* move root image */
 
261
    memmove ((void*)(image_table[kernel_number].root_start & 0x3fffff),
 
262
        moved_ramdisk, image_table[ROOT_IMAGE].packed_len);
 
263
#ifdef TILO_DEBUG
 
264
    printf("Returning from my_main() with address %x\n", kernel_base);
 
265
#endif
 
266
    return kernel_base;                 /* return address to jump into kernel */
 
267
}