Browse Source

Restructured to allow per-object image formats

tags/v0.9.3
Michael Brown 19 years ago
parent
commit
510de6cb8c
1 changed files with 39 additions and 321 deletions
  1. 39
    321
      src/core/osloader.c

+ 39
- 321
src/core/osloader.c View File

@@ -29,351 +29,71 @@ Modifications: Ken Yap (for Etherboot/16)
29 29
  * your option) any later version.
30 30
  */
31 31
 
32
-#include "etherboot.h"
32
+#include "io.h"
33
+#include "heap.h"
33 34
 #include "memsizes.h"
34 35
 
35
-#ifdef KEEP_IT_REAL
36
+/* Linker symbols */
37
+extern char _text[];
38
+extern char _end[];
36 39
 
37
-#warning "All download mechanisms are broken under KEEP_IT_REAL"
38
-
39
-os_download_t probe_image(unsigned char *data, unsigned int len) {
40
-	return 0;
41
-}
42
-
43
-int load_block(unsigned char *data, unsigned int block, unsigned int len, int eof) {
44
-	return 1;
45
-}
46
-
47
-#else /* KEEP_IT_REAL */
48
-
49
-
50
-struct os_entry_regs os_regs;
51
-
52
-static struct ebinfo		loaderinfo = {
53
-	VERSION_MAJOR, VERSION_MINOR,
54
-	0
55
-};
56
-
57
-#define LOAD_DEBUG 0
58
-
59
-static int prep_segment(unsigned long start, unsigned long mid, unsigned long end,
60
-	unsigned long istart, unsigned long iend);
61
-static unsigned long find_segment(unsigned long size, unsigned long align);
62
-static sector_t dead_download ( unsigned char *data, unsigned int len, int eof);
63
-static void done(int do_cleanup);
64
-
65
-#if defined(IMAGE_FREEBSD) && defined(ELF_IMAGE)
66
-static void elf_freebsd_probe(void);
67
-static void elf_freebsd_fixup_segment(void);
68
-static void elf_freebsd_find_segment_end(void);
69
-static int elf_freebsd_debug_loader(unsigned int offset);
70
-static void elf_freebsd_boot(unsigned long entry);
71
-#else
72
-#define elf_freebsd_probe() do {} while(0)
73
-#define elf_freebsd_fixup_segment()  do {} while(0)
74
-#define elf_freebsd_find_segment_end() do {} while(0)
75
-#define elf_freebsd_debug_loader(off) (0)
76
-#define elf_freebsd_boot(entry) do {} while(0)
77
-#endif
78
-#if defined(IMAGE_FREEBSD) && defined(AOUT_IMAGE)
79
-static void aout_freebsd_probe(void);
80
-static void aout_freebsd_boot(void);
81
-#else
82
-#define aout_freebsd_probe() do {} while(0)
83
-#define aout_freebsd_boot() do {} while(0)
84
-#endif
85
-
86
-/**************************************************************************
87
-dead_download - Restart etherboot if probe image fails
88
-**************************************************************************/
89
-static sector_t dead_download ( unsigned char *data __unused, unsigned int len __unused, int eof __unused) {
90
-        longjmp(restart_etherboot, -2);
91
-}
92
-
93
-#ifdef	IMAGE_MULTIBOOT
94
-#include "../arch/i386/core/multiboot_loader.c"
95
-#else
96
-#define multiboot_probe(data, len) do {} while(0)
97
-#define multiboot_boot(entry) do {} while(0)
98
-#endif
99
-
100
-
101
-#ifdef WINCE_IMAGE
102
-#include "../arch/i386/core/wince_loader.c"
103
-#endif
104
-
105
-#ifdef AOUT_IMAGE
106
-#include "../arch/i386/core/aout_loader.c"
107
-#endif
108
-
109
-#ifdef TAGGED_IMAGE
110
-#include "../arch/i386/core/tagged_loader.c"
111
-#endif
112
-
113
-#if defined(ELF_IMAGE) || defined(ELF64_IMAGE)
114
-#include "elf_loader.c"
115
-#endif
116
-
117
-#if defined(COFF_IMAGE) 
118
-#include "../arch/e1/core/coff_loader.c"
119
-#endif
120
-
121
-#ifdef IMAGE_FREEBSD
122
-#include "../arch/i386/core/freebsd_loader.c"
123
-#endif
124
-
125
-#ifdef PXE_IMAGE
126
-#include "../arch/i386/core/pxe_loader.c"
127
-#endif
128
-
129
-#ifdef RAW_IMAGE
130
-#include "../arch/armnommu/core/raw_loader.c"
131
-#endif
132
-
133
-static void done(int do_cleanup)
134
-{
135
-#ifdef	SIZEINDICATOR
136
-	printf("K ");
137
-#endif
138
-	printf("done\n");
139
-	/* We may not want to do the cleanup: when booting a PXE
140
-	 * image, for example, we need to leave the network card
141
-	 * enabled, and it helps debugging if the serial console
142
-	 * remains enabled.  The call the cleanup() will be triggered
143
-	 * when the PXE stack is shut down.
144
-	 */
145
-	if ( do_cleanup ) {
146
-		cleanup();
147
-		/* arch_on_exit(0); */
148
-	}
149
-}
150
-
151
-static int prep_segment(unsigned long start, unsigned long mid, unsigned long end,
152
-	unsigned long istart __unused, unsigned long iend __unused)
153
-{
40
+int prep_segment ( physaddr_t start, physaddr_t mid, physaddr_t end ) {
154 41
 	unsigned fit, i;
155 42
 
156
-#if LOAD_DEBUG
157
-	printf ( "\nAbout to prepare segment [%lX,%lX)\n", start, end );
158
-	sleep ( 3 );
159
-#endif
43
+	DBG ( "OSLOADER preparing segment [%lX,%lX)\n", start, end );
160 44
 
161
-	if (mid > end) {
162
-		printf("filesz > memsz\n");
45
+	if ( mid > end ) {
46
+		DBG ( "OSLOADER got filesz > memsz\n" );
163 47
 		return 0;
164 48
 	}
165
-	if ((end > virt_to_phys(_text)) && 
166
-		(start < virt_to_phys(_end))) {
167
-		printf("segment [%lX, %lX) overlaps etherboot [%lX, %lX)\n",
168
-			start, end,
169
-			virt_to_phys(_text), virt_to_phys(_end)
170
-			);
49
+
50
+	/* Check for overlap with Etherboot runtime image */
51
+	if ( ( end > virt_to_phys ( _text ) ) && 
52
+	     ( start < virt_to_phys ( _end ) ) ) {
53
+		DBG ( "OSLOADER got segment [%lX, %lX) "
54
+		      "overlapping etherboot [%lX, %lX)\n",
55
+		      start, end,
56
+		      virt_to_phys ( _text ), virt_to_phys ( _end ) );
171 57
 		return 0;
172 58
 	}
173
-	if ((end > heap_ptr) && (start < heap_bot)) {
174
-		printf("segment [%lX, %lX) overlaps heap [%lX, %lX)\n",
175
-			start, end,
176
-			heap_ptr, heap_bot
177
-			);
59
+
60
+	/* Check for overlap with used portion of heap.  Since the
61
+	 * heap code just finds the biggest available memory area, we
62
+	 * check only against the used heap area, rather than the
63
+	 * whole heap area.
64
+	 */
65
+	if ( ( end > heap_ptr ) && ( start < heap_end ) ) {
66
+		DBG ( "OSLOADER got segment [%lX, %lX) "
67
+		      "overlapping used heap [%lX, %lX)\n",
68
+		      start, end, heap_ptr, heap_end );
178 69
 		return 0;
179 70
 	}
71
+
72
+	/* Check that block fits entirely inside a single memory region */
180 73
 	fit = 0;
181
-	for(i = 0; i < meminfo.map_count; i++) {
74
+	for ( i = 0 ; i < meminfo.map_count ; i++ ) {
182 75
 		unsigned long long r_start, r_end;
76
+
183 77
 		if (meminfo.map[i].type != E820_RAM)
184 78
 			continue;
79
+
185 80
 		r_start = meminfo.map[i].addr;
186 81
 		r_end = r_start + meminfo.map[i].size;
187
-		if ((start >= r_start) && (end <= r_end)) {
82
+		if ( ( start >= r_start ) && ( end <= r_end ) ) {
188 83
 			fit = 1;
189 84
 			break;
190 85
 		}
191 86
 	}
192
-	if (!fit) {
193
-		printf("\nsegment [%lX,%lX) does not fit in any memory region\n",
194
-			start, end);
195
-#if LOAD_DEBUG
196
-		printf("Memory regions(%d):\n", meminfo.map_count);
197
-		for(i = 0; i < meminfo.map_count; i++) {
198
-			unsigned long long r_start, r_end;
199
-			if (meminfo.map[i].type != E820_RAM)
200
-				continue;
201
-			r_start = meminfo.map[i].addr;
202
-			r_end = r_start + meminfo.map[i].size;
203
-			printf("[%X%X, %X%X) type %d\n", 
204
-				(unsigned long)(r_start >> 32),
205
-				(unsigned long)r_start,
206
-				(unsigned long)(r_end >> 32),
207
-				(unsigned long)r_end,
208
-				meminfo.map[i].type);
209
-		}
210
-#endif
87
+	if ( ! fit ) {
88
+		DBG ( "OSLOADER got segment [%lX,%lX) "
89
+		      "which does not fit in any memory region\n",
90
+			start, end );
211 91
 		return 0;
212 92
 	}
213
-#if LOAD_DEBUG
214
-	/* Zap the whole lot.  Do this so that if we're treading on
215
-	 * anything, it shows up now, when the debug message is
216
-	 * visible, rather than when we're partway through downloading
217
-	 * the file.
218
-	 *
219
-	 * If you see an entire screen full of exclamation marks, then
220
-	 * you've almost certainly written all over the display RAM.
221
-	 * This is likely to happen if the status of the A20 line gets
222
-	 * screwed up.  Of course, if this happens, it's a good bet
223
-	 * that you've also trashed the whole of low memory, so expect
224
-	 * interesting things to happen...
225
-	 */
226
-	memset(phys_to_virt(start), '!', mid - start);
227
-#endif
228
-	/* Zero the bss */
229
-	if (end > mid) {
230
-		memset(phys_to_virt(mid), 0, end - mid);
231
-	}
232
-	return 1;
233
-}
234
-
235
-static unsigned long find_segment(unsigned long size, unsigned long align)
236
-{
237
-	unsigned i;
238
-	/* Verify I have a power of 2 alignment */
239
-	if (align & (align - 1)) {
240
-		return ULONG_MAX;
241
-	}
242
-	for(i = 0; i < meminfo.map_count; i++) {
243
-		unsigned long r_start, r_end;
244
-		if (meminfo.map[i].type != E820_RAM)
245
-			continue;
246
-		if ((meminfo.map[i].addr + meminfo.map[i].size) > ULONG_MAX) {
247
-			continue;
248
-		}
249
-		r_start = meminfo.map[i].addr;
250
-		r_end = r_start + meminfo.map[i].size;
251
-		/* Don't allow the segment to overlap etherboot */
252
-		if ((r_end > virt_to_phys(_text)) && (r_start < virt_to_phys(_text))) {
253
-			r_end = virt_to_phys(_text);
254
-		}
255
-		if ((r_start > virt_to_phys(_text)) && (r_start < virt_to_phys(_end))) {
256
-			r_start = virt_to_phys(_end);
257
-		}
258
-		/* Don't allow the segment to overlap the heap */
259
-		if ((r_end > heap_ptr) && (r_start < heap_ptr)) {
260
-			r_end = heap_ptr;
261
-		}
262
-		if ((r_start > heap_ptr) && (r_start < heap_bot)) {
263
-			r_start = heap_ptr;
264
-		}
265
-		r_start = (r_start + align - 1) & ~(align - 1);
266
-		if ((r_end >= r_start) && ((r_end - r_start) >= size)) {
267
-			return r_start;
268
-		}
269
-	}
270
-	/* I did not find anything :( */
271
-	return ULONG_MAX;
272
-}
273 93
 
274
-/**************************************************************************
275
-PROBE_IMAGE - Detect image file type
276
-**************************************************************************/
277
-os_download_t probe_image(unsigned char *data, unsigned int len)
278
-{
279
-	os_download_t os_download = 0;
280
-
281
-#ifdef AOUT_IMAGE
282
-	if (!os_download) os_download = aout_probe(data, len);
283
-#endif
284
-#ifdef ELF_IMAGE
285
-	if (!os_download) os_download = elf32_probe(data, len);
286
-#endif
287
-#ifdef ELF64_IMAGE
288
-	if (!os_download) os_download = elf64_probe(data, len);
289
-#endif
290
-#ifdef COFF_IMAGE
291
-    if (!os_download) os_download = coff_probe(data, len);
292
-#endif
293
-#ifdef WINCE_IMAGE
294
-	if (!os_download) os_download = wince_probe(data, len);
295
-#endif
296
-#ifdef TAGGED_IMAGE
297
-	if (!os_download) os_download = tagged_probe(data, len);
298
-#endif
299
-/* PXE_IMAGE must always be last */
300
-#ifdef PXE_IMAGE
301
-	if (!os_download) os_download = pxe_probe(data, len);
302
-#endif
303
-#ifdef RAW_IMAGE
304
-	if (!os_download) os_download = raw_probe(data, len);
305
-#endif
306
-
307
-	return os_download;
308
-}
309
-
310
-/**************************************************************************
311
-LOAD_BLOCK - Try to load file
312
-**************************************************************************/
313
-int load_block(unsigned char *data, unsigned int block, unsigned int len, int eof)
314
-{
315
-	static os_download_t os_download;
316
-	static sector_t skip_sectors;
317
-	static unsigned int skip_bytes;
318
-#ifdef	SIZEINDICATOR
319
-	static int rlen = 0;
320
-
321
-	if (block == 1)
322
-	{
323
-		rlen=len;
324
-		printf("XXXX");
325
-	}
326
-	if (!(block % 4) || eof) {
327
-		int size;
328
-		size = ((block-1) * rlen + len) / 1024;
329
-
330
-		putchar('\b');
331
-		putchar('\b');
332
-		putchar('\b');
333
-		putchar('\b');
334
-
335
-		putchar('0' + (size/1000)%10);
336
-		putchar('0' + (size/100)%10);
337
-		putchar('0' + (size/10)%10);
338
-		putchar('0' + (size/1)%10);
339
-	}
340
-#else
341
-	putchar ( '.' );
342
-#endif
343
-	if (block == 1)
344
-	{
345
-		skip_sectors = 0;
346
-		skip_bytes = 0;
347
-		os_download = probe_image(data, len);
348
-		if (!os_download) {
349
-			printf("error: not a valid image\n");
350
-#if 0
351
-			printf("block: %d len: %d\n", block, len);
352
-			printf("%hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx\n",
353
-				data[0], data[1], data[2], data[3],
354
-				data[4], data[5], data[6], data[7]);
355
-#endif
356
-			return 0;
357
-		}
358
-	} /* end of block zero processing */
94
+	/* Zero the bss */
95
+	memset ( phys_to_virt ( mid ), 0, end - mid );
359 96
 
360
-	/* Either len is greater or the skip is greater */
361
-	if ((skip_sectors > (len >> 9)) ||
362
-		((skip_sectors == (len >> 9)) && (skip_bytes >= (len & 0x1ff)))) {
363
-		/* If I don't have enough bytes borrow them from skip_sectors */
364
-		if (skip_bytes < len) {
365
-			skip_sectors -= (len - skip_bytes + 511) >> 9;
366
-			skip_bytes += (len - skip_bytes + 511) & ~0x1ff;
367
-		}
368
-		skip_bytes -= len;
369
-	}
370
-	else {
371
-		len -= (skip_sectors << 9) + skip_bytes;
372
-		data += (skip_sectors << 9) + skip_bytes;
373
-	}
374
-	skip_sectors = os_download(data, len, eof);
375
-	skip_bytes = 0;
376
-	
377 97
 	return 1;
378 98
 }
379 99
 
@@ -382,5 +102,3 @@ int load_block(unsigned char *data, unsigned int block, unsigned int len, int eo
382 102
  *  c-basic-offset: 8
383 103
  * End:
384 104
  */
385
-
386
-#endif /* KEEP_IT_REAL */

Loading…
Cancel
Save