Magellan Linux

Contents of /trunk/linterm_tools/fw_builder/make-nk/make-nk.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 658 - (show annotations) (download)
Mon Jan 14 16:57:24 2008 UTC (16 years, 3 months ago) by niro
File MIME type: text/plain
File size: 5870 byte(s)
initial import

1 /*
2 Copyright (C) 2000 by Anders Larsen and Baumer Ident GmbH
3
4 Slightly adapted for the winterm.gaast.project by Wilmer van der Gaast
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., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <asm/types.h>
26 #include <sys/stat.h>
27
28 int verbose = 0;
29
30 u_int8_t signature[7] = "B000FF\n";
31 u_int32_t start = 0x90000;
32 u_int32_t test = 0x17db90;
33
34
35 int usage(char *const argv0)
36 {
37 fprintf(stderr, "Puts a kernel and (optionally) initrd together in one nk.bin file.\n"
38 "\n"
39 "Read the documentation before using this tool!\n"
40 "\n"
41 "Usage: %s -k <kernel> [<other options>]\n"
42 "\n"
43 "Options:\n"
44 "-k <file>\tKernel file (MUST be in bzImage format)\n"
45 "-i <file>\tInitial ramdisk file (default: none)\n"
46 "-m <size>\tMemory size (dec) in KB (default: see boot.S)\n"
47 "-r <addr>\tOffset of RAM-disk (default: calculated from memsize)\n"
48 "-o <file>\tOutput file (default: nk.bin)\n"
49 "-v\t\tVerbose mode\n"
50 "-h\t\tThis information\n", argv0);
51
52 return EXIT_FAILURE;
53 }
54
55
56 int copy(char const *name, u_int32_t offset, u_int32_t addr, FILE * fpo)
57 {
58 int ch;
59 u_int32_t cksum = 0;
60 u_int32_t size = 0;
61 FILE *fpi;
62
63 if (!(fpi = fopen(name, "r"))) {
64 perror("Can't open input file");
65 return EXIT_FAILURE;
66 }
67 fseek(fpo, 3 * sizeof(u_int32_t), SEEK_CUR);
68 if (offset)
69 fseek(fpi, offset, SEEK_SET);
70 while ((ch = getc(fpi)) != EOF) {
71 size++;
72 cksum += ch;
73 putc(ch, fpo);
74 }
75 fseek(fpo, -(long) (size + 3 * sizeof(u_int32_t)), SEEK_CUR);
76 fwrite(&addr, sizeof(addr), 1, fpo);
77 fwrite(&size, sizeof(size), 1, fpo);
78 fwrite(&cksum, sizeof(cksum), 1, fpo);
79 fseek(fpo, size, SEEK_CUR);
80
81 if (verbose)
82 printf("%16s @ %08x, %7d bytes (checksum %08x)\n", name,
83 addr, size, cksum);
84
85 fclose(fpi);
86 return size;
87 }
88
89
90 int main(int argc, char *const *argv)
91 {
92 int ch;
93 u_int16_t offset;
94 u_int32_t memsize = 0;
95 u_int32_t rootaddr = 0;
96 u_int32_t rootsize = 0;
97 u_int32_t linuxoff;
98 u_int32_t ul;
99 char version[41];
100 FILE *fpi;
101 FILE *fpo;
102 char const *cp;
103 struct stat statbuf;
104
105 char *kernel = NULL;
106 char *initrd = NULL;
107 char *output = "nk.bin";
108
109 while ((ch = getopt(argc, argv, "k:i:o:m:r:vh")) != EOF)
110 switch (ch) {
111 case 'k':
112 kernel = strdup(optarg);
113 break;
114
115 case 'i':
116 initrd = strdup(optarg);
117
118 if (stat(initrd, &statbuf)) {
119 perror("Can't stat initrd");
120 return EXIT_FAILURE;
121 }
122 rootsize = statbuf.st_size;
123
124 break;
125
126 case 'o':
127 output = strdup(optarg);
128 break;
129
130 case 'm':
131 /* Subtracting 1024 here because the kernel asks for
132 *extended* memory size. */
133 memsize = strtol(optarg, 0, 10) - 1024;
134 break;
135
136 case 'r':
137 rootaddr = strtol(optarg, 0, 16);
138 break;
139
140 case 'v':
141 verbose++;
142 break;
143
144 default:
145 return usage(argv[0]);
146 }
147
148 if (kernel == NULL )
149 return usage(argv[0]);
150
151
152 // extract information from kernel
153 if (!(fpi = fopen(kernel, "r"))) {
154 perror("Can't open kernel");
155 return EXIT_FAILURE;
156 }
157
158 fseek(fpi, 0x1f1, SEEK_SET);
159 fread(&linuxoff, sizeof(linuxoff), 1, fpi);
160 fseek(fpi, 0x20e, SEEK_SET);
161 fread(&offset, sizeof(offset), 1, fpi);
162 fseek(fpi, offset + 0x200, SEEK_SET); // SETUPSEG - INITSEG
163 fread(version, sizeof(version), 1, fpi);
164 version[sizeof(version) - 1] = 0;
165 fclose(fpi);
166 linuxoff = ((linuxoff & 0xff) + 1) * 512;
167
168
169 // update information in "boot"
170 if (!(fpi = fopen("boot", "r+"))) {
171 perror("Can't open boot");
172 return EXIT_FAILURE;
173 }
174
175 // copy kernel version string
176 if ((cp = strtok(version, " ")) != NULL) {
177 fseek(fpi, 0x22e, SEEK_SET); // 0x20e + Minix header
178 fread(&offset, sizeof(offset), 1, fpi);
179 fseek(fpi, offset + 0x26, SEEK_SET); // Minix header + "Linux "
180 fwrite(cp, strlen(cp) + 1, 1, fpi);
181 }
182 // get/set memory size
183 fseek(fpi, 0x200, SEEK_SET); // 0x1e0 + Minix header
184 if (memsize == 0)
185 fread(&memsize, sizeof(memsize), 1, fpi);
186 else
187 fwrite(&memsize, sizeof(memsize), 1, fpi);
188
189 if (memsize != 0)
190 memsize = (memsize + 1024) * 1024;
191
192 if (initrd) {
193 // write initrd info
194 if (rootaddr == 0) {
195 if (memsize != 0)
196 rootaddr = (memsize - rootsize) & 0xfffe0000;
197 else
198 rootaddr = 0x300000; /* Let's hope the kernel is <2MB! :-) */
199 }
200 fseek(fpi, 0x238, SEEK_SET);
201 fwrite(&rootaddr, sizeof(rootaddr), 1, fpi);
202 fwrite(&rootsize, sizeof(rootsize), 1, fpi);
203 fclose(fpi);
204 }
205
206
207 // write NK.bin header
208 if (!(fpo = fopen(output, "w+"))) {
209 perror("Can't open output file");
210 return EXIT_FAILURE;
211 }
212 fwrite(signature, sizeof(signature), 1, fpo);
213 fwrite(&start, sizeof(start), 1, fpo);
214 fwrite(&test, sizeof(test), 1, fpo);
215
216 copy("boot", 32, 0x90000, fpo);
217 copy(kernel, linuxoff, 0x100000, fpo);
218 if (initrd)
219 copy(initrd, 0, rootaddr, fpo);
220
221 // write NK.bin trailer
222 ul = 0;
223 fwrite(&ul, sizeof(ul), 1, fpo);
224 // this is the real entry point, start seems to be bogus, or something else?
225 ul = 0x91000;
226 fwrite(&ul, sizeof(ul), 1, fpo);
227 ul = 0;
228 fwrite(&ul, sizeof(ul), 1, fpo);
229
230 fclose(fpo);
231
232 return EXIT_SUCCESS;
233 }