~ubuntu-branches/ubuntu/hardy/silo/hardy-updates

« back to all changes in this revision

Viewing changes to tilo/maketilo.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
 
 
2
/*
 
3
        Jan Vondrak (C) 1998
 
4
        Jakub Jelinek (C) 1998
 
5
 
 
6
        A simple program which appends the kernel and root images
 
7
        to the boot loader and patches the addresses in its image_table[]
 
8
        
 
9
        Parameters:
 
10
                        kernel4=<filename>
 
11
                        kernel4c=<filename>
 
12
                        kernel4u=<filename>
 
13
                                ... compressed kernel images (in a.out format)
 
14
                        size4=<bytes>
 
15
                        size4c=<bytes>
 
16
                        size4u=<bytes>
 
17
                                ... original sizes of kernel images (uncompressed)
 
18
                        root4=<addr>
 
19
                        root4c=<addr>
 
20
                        root4u=<addr>
 
21
                                ... virtual address of root image for each kernel (in hex)
 
22
                        root=<filename>
 
23
                                ... compressed root image
 
24
                        out=<filename>
 
25
                                ... the output file
 
26
*/
 
27
 
 
28
 
 
29
#include <stdio.h>
 
30
#include <sys/stat.h>
 
31
#include <stdlib.h>
 
32
#include <string.h>
 
33
#include "b.h"
 
34
#include "b2.h"
 
35
 
 
36
#define MAX_BOOT_LEN    0x400000
 
37
 
 
38
char output_buffer[MAX_BOOT_LEN];
 
39
 
 
40
struct ImageInfo {
 
41
        unsigned packed_start;
 
42
        unsigned packed_len;
 
43
        unsigned unpacked_len;
 
44
        unsigned root_start;
 
45
};
 
46
 
 
47
int root_tweak (char *s)
 
48
{
 
49
        unsigned p;
 
50
 
 
51
        p = strtoul (s, NULL, 16);              /* read virtual address in hex */
 
52
        return p ? (p + 32 + 0x1fff) & ~0x1fff : 0;     /* add 32 bytes and round to 8 KB */
 
53
}
 
54
 
 
55
int main (int argc, char **argv)
 
56
{
 
57
        int i,len,rootlen;
 
58
        FILE *f, *g;
 
59
        struct ImageInfo *ii;
 
60
 
 
61
        char *sun4_kernel_start;
 
62
        char *sun4c_kernel_start;
 
63
        char *sun4u_kernel_start;
 
64
        char *root_image_start;
 
65
        char *output_end;
 
66
 
 
67
        int sun4_size = 0, sun4_root = 0;
 
68
        int sun4c_size = 0, sun4c_root = 0;
 
69
        int sun4u_size = 0, sun4u_root = 0;
 
70
 
 
71
        char *sun4_kernel = 0;
 
72
        char *sun4c_kernel = 0;
 
73
        char *sun4u_kernel = 0;
 
74
        char *root_image = 0;
 
75
        char *output_file = 0;
 
76
 
 
77
        if (argc < 4) {
 
78
                fprintf (stderr, "Usage: maketilo\n"
 
79
                "\tsun4=<sun4 gzipped kernel> size4=<sun4 orig size> root4=<sun4 root address>\n"
 
80
                "\tsun4c=<sun4c gzipped size> size4c=<sun4c orig size> root4c=<sun4c root address>\n"
 
81
                "\tsun4u=<sun4u gzipped kernel> size4u=<sun4u orig size> root4u=<sun4u root address>\n"
 
82
                "\troot=<root image>\n"
 
83
                "\tout=<output file>\n");
 
84
                return -1;
 
85
        }
 
86
 
 
87
        for (i=1;i<argc;i++) {
 
88
                if (!strncmp (argv[i], "sun4=", 5))
 
89
                        sun4_kernel = argv[i] + 5;
 
90
                else if (!strncmp (argv[i], "sun4c=", 6))
 
91
                        sun4c_kernel = argv[i] + 6;
 
92
                else if (!strncmp (argv[i], "sun4u=", 6))
 
93
                        sun4u_kernel = argv[i] + 6;
 
94
                else if (!strncmp (argv[i], "size4=", 6))
 
95
                        sun4_size = atoi (argv[i]+6);
 
96
                else if (!strncmp (argv[i], "size4c=", 7))
 
97
                        sun4c_size = atoi (argv[i]+7);
 
98
                else if (!strncmp (argv[i], "size4u=", 7))
 
99
                        sun4u_size = atoi (argv[i]+7);
 
100
                else if (!strncmp (argv[i], "root4=", 6))
 
101
                        sun4_root = root_tweak (argv[i]+6);
 
102
                else if (!strncmp (argv[i], "root4c=", 7))
 
103
                        sun4c_root = root_tweak (argv[i]+7);
 
104
                else if (!strncmp (argv[i], "root4u=", 7))
 
105
                        sun4u_root = root_tweak (argv[i]+7);
 
106
                else if (!strncmp (argv[i], "root=", 5))
 
107
                        root_image = argv[i] + 5;
 
108
                else if (!strncmp (argv[i], "out=", 4))
 
109
                        output_file = argv[i] + 4;
 
110
        }
 
111
        
 
112
        if (!sun4_kernel) {
 
113
                /*fprintf (stderr, "WARNING: Kernel for Sun4 not specified\n");*/
 
114
        } else if (!sun4_size || !sun4_root) {
 
115
                fprintf (stderr, "WARNING: Original size and root address must be specified for Sun4\n");
 
116
                return -1;
 
117
        }
 
118
        
 
119
        if (!sun4c_kernel) {
 
120
                fprintf (stderr, "WARNING: Kernel for Sun4c/m/d not specified\n");
 
121
        } else if (!sun4c_size || !sun4c_root) {
 
122
                fprintf (stderr, "ERROR: Original size and root address must be specified for Sun4c\n");
 
123
                return -1;
 
124
        }
 
125
        
 
126
        if (!sun4u_kernel) {
 
127
                fprintf (stderr, "WARNING: Kernel for Sun4u not specified\n");
 
128
        } else if (!sun4u_size || !sun4u_root) {
 
129
                fprintf (stderr, "ERROR: Original size and root address must be specified for Sun4u\n");
 
130
                return -1;
 
131
        }
 
132
        
 
133
        if (!root_image) {
 
134
                fprintf (stderr, "ERROR: Root image not specified\n");
 
135
                return -1;
 
136
        }
 
137
                
 
138
        if (!output_file) {
 
139
                fprintf (stderr, "ERROR: Output file not specified\n");
 
140
                return -1;
 
141
        }
 
142
        
 
143
        g = fopen (root_image, "rb");
 
144
        if (!g) {
 
145
                fprintf (stderr, "Can't load %s\n", root_image);
 
146
                return -1;
 
147
        }
 
148
        
 
149
        fseek (g, 0, SEEK_END);
 
150
        rootlen = ftell (g);
 
151
        fseek (g, 0, SEEK_SET);
 
152
        
 
153
        if (rootlen + sun4_size + 0x4000 + 0x10000 >= 0x330000 ||
 
154
            rootlen + sun4c_size + 0x4000 + 0x10000 >= 0x330000 ||
 
155
            rootlen + sun4u_size + 0x4000 + 0x10000 >= 0x330000) {
 
156
                printf("Images are large. Will load on machines with at least 5M mapped by PROM only\n");
 
157
        
 
158
                for (i=0; i<LARGE_BOOT_LEN; i++)
 
159
                        output_buffer[i] = large_boot_loader[i];
 
160
        } else
 
161
                for (i=0; i<BOOT_LEN; i++)
 
162
                        output_buffer[i] = boot_loader[i];
 
163
        
 
164
        sun4_kernel_start = output_buffer + BOOT_LEN;
 
165
 
 
166
        if (sun4_kernel) {
 
167
                f = fopen (sun4_kernel, "rb");
 
168
                if (!f) {
 
169
                        fprintf (stderr, "Can't load %s\n", sun4_kernel);
 
170
                        return -1;
 
171
                }
 
172
                
 
173
                fseek (f, 0, SEEK_END);
 
174
                len = ftell (f);
 
175
                fseek (f, 0, SEEK_SET);
 
176
                fread (sun4_kernel_start, 1, len, f);
 
177
                fclose (f);
 
178
        } else
 
179
                len = 0;
 
180
 
 
181
        sun4c_kernel_start = sun4_kernel_start + len;
 
182
 
 
183
        if (sun4c_kernel) {
 
184
                f = fopen (sun4c_kernel, "rb");
 
185
                if (!f) {
 
186
                        fprintf (stderr, "Can't load %s\n", sun4c_kernel);
 
187
                        return -1;
 
188
                }
 
189
                
 
190
                fseek (f, 0, SEEK_END);
 
191
                len = ftell (f);
 
192
                fseek (f, 0, SEEK_SET);
 
193
                fread (sun4c_kernel_start, 1, len, f);
 
194
                fclose (f);
 
195
        } else
 
196
                len = 0;
 
197
 
 
198
        sun4u_kernel_start = sun4c_kernel_start + len;
 
199
 
 
200
        if (sun4u_kernel) {
 
201
                f = fopen (sun4u_kernel, "rb");
 
202
                if (!f) {
 
203
                        fprintf (stderr, "Can't load %s\n", sun4u_kernel);
 
204
                        return -1;
 
205
                }
 
206
                
 
207
                fseek (f, 0, SEEK_END);
 
208
                len = ftell (f);
 
209
                fseek (f, 0, SEEK_SET);
 
210
                fread (sun4u_kernel_start, 1, len, f);
 
211
                fclose (f);
 
212
        } else
 
213
                len = 0;
 
214
 
 
215
        root_image_start = sun4u_kernel_start + len;
 
216
        
 
217
        fread (root_image_start, 1, rootlen, g);
 
218
        fclose (g);
 
219
 
 
220
        output_end = root_image_start + rootlen;
 
221
 
 
222
        /* patch code, data and BSS size in the .out header */
 
223
        *(unsigned*)(output_buffer+4) = output_end - output_buffer;
 
224
        *(unsigned*)(output_buffer+8) = 0;
 
225
        *(unsigned*)(output_buffer+12) = 0;
 
226
 
 
227
        /* fill image_table[] in the boot loader */
 
228
        ii = (struct ImageInfo*)(output_buffer + 40);                   
 
229
 
 
230
        if (sun4_kernel) {
 
231
                ii[0].packed_start = sun4_kernel_start - output_buffer - 32;
 
232
                ii[0].packed_len = sun4c_kernel_start - sun4_kernel_start;
 
233
                ii[0].unpacked_len = sun4_size;
 
234
                ii[0].root_start = sun4_root;
 
235
        } else {
 
236
                ii[0].packed_start = 0;
 
237
                ii[0].packed_len = 0;
 
238
                ii[0].unpacked_len = 0;
 
239
                ii[0].root_start = 0;
 
240
        }
 
241
 
 
242
        if (sun4c_kernel) {
 
243
                ii[1].packed_start = sun4c_kernel_start - output_buffer - 32;
 
244
                ii[1].packed_len = sun4u_kernel_start - sun4c_kernel_start;
 
245
                ii[1].unpacked_len = sun4c_size;
 
246
                ii[1].root_start = sun4c_root;
 
247
        } else {
 
248
                ii[1].packed_start = 0;
 
249
                ii[1].packed_len = 0;
 
250
                ii[1].unpacked_len = 0;
 
251
                ii[1].root_start = 0;
 
252
        }
 
253
        
 
254
        if (sun4u_kernel) {
 
255
                ii[2].packed_start = sun4u_kernel_start - output_buffer - 32;
 
256
                ii[2].packed_len = root_image_start - sun4u_kernel_start;
 
257
                ii[2].unpacked_len = sun4u_size;
 
258
                ii[2].root_start = sun4u_root;
 
259
        } else {
 
260
                ii[2].packed_start = 0;
 
261
                ii[2].packed_len = 0;
 
262
                ii[2].unpacked_len = 0;
 
263
                ii[2].root_start = 0;
 
264
        }
 
265
        
 
266
        ii[3].packed_start = root_image_start - output_buffer - 32;
 
267
        ii[3].packed_len = output_end - root_image_start;
 
268
        ii[3].unpacked_len = 0;
 
269
        ii[3].root_start = 0;
 
270
 
 
271
        f = fopen (output_file, "wb");
 
272
        if (!f) {
 
273
                fprintf (stderr, "Can't open %s for writing\n", output_file);
 
274
                return -1;
 
275
        }
 
276
        
 
277
        fwrite (output_buffer, 1, output_end - output_buffer, f);
 
278
        fclose (f);
 
279
        
 
280
        return 0;
 
281
}