|
@@ -1,377 +0,0 @@
|
1
|
|
-/* bootinfo */
|
2
|
|
-#define BOOTINFO_VERSION 1
|
3
|
|
-#define NODEV (-1) /* non-existent device */
|
4
|
|
-#define PAGE_SHIFT 12 /* LOG2(PAGE_SIZE) */
|
5
|
|
-#define PAGE_SIZE (1<<PAGE_SHIFT) /* bytes/page */
|
6
|
|
-#define PAGE_MASK (PAGE_SIZE-1)
|
7
|
|
-#define N_BIOS_GEOM 8
|
8
|
|
-
|
9
|
|
-struct bootinfo {
|
10
|
|
- unsigned int bi_version;
|
11
|
|
- const unsigned char *bi_kernelname;
|
12
|
|
- struct nfs_diskless *bi_nfs_diskless;
|
13
|
|
- /* End of fields that are always present. */
|
14
|
|
-#define bi_endcommon bi_n_bios_used
|
15
|
|
- unsigned int bi_n_bios_used;
|
16
|
|
- unsigned long bi_bios_geom[N_BIOS_GEOM];
|
17
|
|
- unsigned int bi_size;
|
18
|
|
- unsigned char bi_memsizes_valid;
|
19
|
|
- unsigned char bi_pad[3];
|
20
|
|
- unsigned long bi_basemem;
|
21
|
|
- unsigned long bi_extmem;
|
22
|
|
- unsigned long bi_symtab;
|
23
|
|
- unsigned long bi_esymtab;
|
24
|
|
- /* Note that these are in the FreeBSD headers but were not here... */
|
25
|
|
- unsigned long bi_kernend; /* end of kernel space */
|
26
|
|
- unsigned long bi_envp; /* environment */
|
27
|
|
- unsigned long bi_modulep; /* preloaded modules */
|
28
|
|
-};
|
29
|
|
-
|
30
|
|
-static struct bootinfo bsdinfo;
|
31
|
|
-
|
32
|
|
-#ifdef ELF_IMAGE
|
33
|
|
-static Elf32_Shdr *shdr; /* To support the FreeBSD kludge! */
|
34
|
|
-static Address symtab_load;
|
35
|
|
-static Address symstr_load;
|
36
|
|
-static int symtabindex;
|
37
|
|
-static int symstrindex;
|
38
|
|
-#endif
|
39
|
|
-
|
40
|
|
-static enum {
|
41
|
|
- Unknown, Tagged, Aout, Elf, Aout_FreeBSD, Elf_FreeBSD,
|
42
|
|
-} image_type = Unknown;
|
43
|
|
-
|
44
|
|
-static unsigned int off;
|
45
|
|
-
|
46
|
|
-
|
47
|
|
-#ifdef ELF_IMAGE
|
48
|
|
-static void elf_freebsd_probe(void)
|
49
|
|
-{
|
50
|
|
- image_type = Elf;
|
51
|
|
- if ( (estate.e.elf32.e_entry & 0xf0000000) &&
|
52
|
|
- (estate.e.elf32.e_type == ET_EXEC))
|
53
|
|
- {
|
54
|
|
- image_type = Elf_FreeBSD;
|
55
|
|
- printf("/FreeBSD");
|
56
|
|
- off = -(estate.e.elf32.e_entry & 0xff000000);
|
57
|
|
- estate.e.elf32.e_entry += off;
|
58
|
|
- }
|
59
|
|
- /* Make sure we have a null to start with... */
|
60
|
|
- shdr = 0;
|
61
|
|
-
|
62
|
|
- /* Clear the symbol index values... */
|
63
|
|
- symtabindex = -1;
|
64
|
|
- symstrindex = -1;
|
65
|
|
-
|
66
|
|
- /* ...and the load addresses of the symbols */
|
67
|
|
- symtab_load = 0;
|
68
|
|
- symstr_load = 0;
|
69
|
|
-}
|
70
|
|
-
|
71
|
|
-static void elf_freebsd_fixup_segment(void)
|
72
|
|
-{
|
73
|
|
- if (image_type == Elf_FreeBSD) {
|
74
|
|
- estate.p.phdr32[estate.segment].p_paddr += off;
|
75
|
|
- }
|
76
|
|
-}
|
77
|
|
-
|
78
|
|
-static void elf_freebsd_find_segment_end(void)
|
79
|
|
-{
|
80
|
|
- /* Count the bytes read even for the last block
|
81
|
|
- * as we will need to know where the last block
|
82
|
|
- * ends in order to load the symbols correctly.
|
83
|
|
- * (plus it could be useful elsewhere...)
|
84
|
|
- * Note that we need to count the actual size,
|
85
|
|
- * not just the end of the disk image size.
|
86
|
|
- */
|
87
|
|
- estate.curaddr +=
|
88
|
|
- (estate.p.phdr32[estate.segment].p_memsz -
|
89
|
|
- estate.p.phdr32[estate.segment].p_filesz);
|
90
|
|
-}
|
91
|
|
-
|
92
|
|
-static int elf_freebsd_debug_loader(unsigned int offset)
|
93
|
|
-{
|
94
|
|
- /* No more segments to be loaded - time to start the
|
95
|
|
- * nasty state machine to support the loading of
|
96
|
|
- * FreeBSD debug symbols due to the fact that FreeBSD
|
97
|
|
- * uses/exports the kernel's debug symbols in order
|
98
|
|
- * to make much of the system work! Amazing (arg!)
|
99
|
|
- *
|
100
|
|
- * We depend on the fact that for the FreeBSD kernel,
|
101
|
|
- * there is only one section of debug symbols and that
|
102
|
|
- * the section is after all of the loaded sections in
|
103
|
|
- * the file. This assumes a lot but is somewhat required
|
104
|
|
- * to make this code not be too annoying. (Where do you
|
105
|
|
- * load symbols when the code has not loaded yet?)
|
106
|
|
- * Since this function is actually just a callback from
|
107
|
|
- * the network data transfer code, we need to be able to
|
108
|
|
- * work with the data as it comes in. There is no chance
|
109
|
|
- * for doing a seek other than forwards.
|
110
|
|
- *
|
111
|
|
- * The process we use is to first load the section
|
112
|
|
- * headers. Once they are loaded (shdr != 0) we then
|
113
|
|
- * look for where the symbol table and symbol table
|
114
|
|
- * strings are and setup some state that we found
|
115
|
|
- * them and fall into processing the first one (which
|
116
|
|
- * is the symbol table) and after that has been loaded,
|
117
|
|
- * we try the symbol strings. Note that the order is
|
118
|
|
- * actually required as the memory image depends on
|
119
|
|
- * the symbol strings being loaded starting at the
|
120
|
|
- * end of the symbol table. The kernel assumes this
|
121
|
|
- * layout of the image.
|
122
|
|
- *
|
123
|
|
- * At any point, if we get to the end of the load file
|
124
|
|
- * or the section requested is earlier in the file than
|
125
|
|
- * the current file pointer, we just end up falling
|
126
|
|
- * out of this and booting the kernel without this
|
127
|
|
- * information.
|
128
|
|
- */
|
129
|
|
-
|
130
|
|
- /* Make sure that the next address is long aligned... */
|
131
|
|
- /* Assumes size of long is a power of 2... */
|
132
|
|
- estate.curaddr = (estate.curaddr + sizeof(long) - 1) & ~(sizeof(long) - 1);
|
133
|
|
-
|
134
|
|
- /* If we have not yet gotten the shdr loaded, try that */
|
135
|
|
- if (shdr == 0)
|
136
|
|
- {
|
137
|
|
- estate.toread = estate.e.elf32.e_shnum * estate.e.elf32.e_shentsize;
|
138
|
|
- estate.skip = estate.e.elf32.e_shoff - (estate.loc + offset);
|
139
|
|
- if (estate.toread)
|
140
|
|
- {
|
141
|
|
-#if ELF_DEBUG
|
142
|
|
- printf("shdr *, size %lX, curaddr %lX\n",
|
143
|
|
- estate.toread, estate.curaddr);
|
144
|
|
-#endif
|
145
|
|
-
|
146
|
|
- /* Start reading at the curaddr and make that the shdr */
|
147
|
|
- shdr = (Elf32_Shdr *)phys_to_virt(estate.curaddr);
|
148
|
|
-
|
149
|
|
- /* Start to read... */
|
150
|
|
- return 1;
|
151
|
|
- }
|
152
|
|
- }
|
153
|
|
- else
|
154
|
|
- {
|
155
|
|
- /* We have the shdr loaded, check if we have found
|
156
|
|
- * the indexs where the symbols are supposed to be */
|
157
|
|
- if ((symtabindex == -1) && (symstrindex == -1))
|
158
|
|
- {
|
159
|
|
- int i;
|
160
|
|
- /* Make sure that the address is page aligned... */
|
161
|
|
- /* Symbols need to start in their own page(s)... */
|
162
|
|
- estate.curaddr = (estate.curaddr + 4095) & ~4095;
|
163
|
|
-
|
164
|
|
- /* Need to make new indexes... */
|
165
|
|
- for (i=0; i < estate.e.elf32.e_shnum; i++)
|
166
|
|
- {
|
167
|
|
- if (shdr[i].sh_type == SHT_SYMTAB)
|
168
|
|
- {
|
169
|
|
- int j;
|
170
|
|
- for (j=0; j < estate.e.elf32.e_phnum; j++)
|
171
|
|
- {
|
172
|
|
- /* Check only for loaded sections */
|
173
|
|
- if ((estate.p.phdr32[j].p_type | 0x80) == (PT_LOAD | 0x80))
|
174
|
|
- {
|
175
|
|
- /* Only the extra symbols */
|
176
|
|
- if ((shdr[i].sh_offset >= estate.p.phdr32[j].p_offset) &&
|
177
|
|
- ((shdr[i].sh_offset + shdr[i].sh_size) <=
|
178
|
|
- (estate.p.phdr32[j].p_offset + estate.p.phdr32[j].p_filesz)))
|
179
|
|
- {
|
180
|
|
- shdr[i].sh_offset=0;
|
181
|
|
- shdr[i].sh_size=0;
|
182
|
|
- break;
|
183
|
|
- }
|
184
|
|
- }
|
185
|
|
- }
|
186
|
|
- if ((shdr[i].sh_offset != 0) && (shdr[i].sh_size != 0))
|
187
|
|
- {
|
188
|
|
- symtabindex = i;
|
189
|
|
- symstrindex = shdr[i].sh_link;
|
190
|
|
- }
|
191
|
|
- }
|
192
|
|
- }
|
193
|
|
- }
|
194
|
|
-
|
195
|
|
- /* Check if we have a symbol table index and have not loaded it */
|
196
|
|
- if ((symtab_load == 0) && (symtabindex >= 0))
|
197
|
|
- {
|
198
|
|
- /* No symbol table yet? Load it first... */
|
199
|
|
-
|
200
|
|
- /* This happens to work out in a strange way.
|
201
|
|
- * If we are past the point in the file already,
|
202
|
|
- * we will skip a *large* number of bytes which
|
203
|
|
- * ends up bringing us to the end of the file and
|
204
|
|
- * an old (default) boot. Less code and lets
|
205
|
|
- * the state machine work in a cleaner way but this
|
206
|
|
- * is a nasty side-effect trick... */
|
207
|
|
- estate.skip = shdr[symtabindex].sh_offset - (estate.loc + offset);
|
208
|
|
-
|
209
|
|
- /* And we need to read this many bytes... */
|
210
|
|
- estate.toread = shdr[symtabindex].sh_size;
|
211
|
|
-
|
212
|
|
- if (estate.toread)
|
213
|
|
- {
|
214
|
|
-#if ELF_DEBUG
|
215
|
|
- printf("db sym, size %lX, curaddr %lX\n",
|
216
|
|
- estate.toread, estate.curaddr);
|
217
|
|
-#endif
|
218
|
|
- /* Save where we are loading this... */
|
219
|
|
- symtab_load = estate.curaddr;
|
220
|
|
-
|
221
|
|
- *((long *)phys_to_virt(estate.curaddr)) = estate.toread;
|
222
|
|
- estate.curaddr += sizeof(long);
|
223
|
|
-
|
224
|
|
- /* Start to read... */
|
225
|
|
- return 1;
|
226
|
|
- }
|
227
|
|
- }
|
228
|
|
- else if ((symstr_load == 0) && (symstrindex >= 0))
|
229
|
|
- {
|
230
|
|
- /* We have already loaded the symbol table, so
|
231
|
|
- * now on to the symbol strings... */
|
232
|
|
-
|
233
|
|
-
|
234
|
|
- /* Same nasty trick as above... */
|
235
|
|
- estate.skip = shdr[symstrindex].sh_offset - (estate.loc + offset);
|
236
|
|
-
|
237
|
|
- /* And we need to read this many bytes... */
|
238
|
|
- estate.toread = shdr[symstrindex].sh_size;
|
239
|
|
-
|
240
|
|
- if (estate.toread)
|
241
|
|
- {
|
242
|
|
-#if ELF_DEBUG
|
243
|
|
- printf("db str, size %lX, curaddr %lX\n",
|
244
|
|
- estate.toread, estate.curaddr);
|
245
|
|
-#endif
|
246
|
|
- /* Save where we are loading this... */
|
247
|
|
- symstr_load = estate.curaddr;
|
248
|
|
-
|
249
|
|
- *((long *)phys_to_virt(estate.curaddr)) = estate.toread;
|
250
|
|
- estate.curaddr += sizeof(long);
|
251
|
|
-
|
252
|
|
- /* Start to read... */
|
253
|
|
- return 1;
|
254
|
|
- }
|
255
|
|
- }
|
256
|
|
- }
|
257
|
|
- /* all done */
|
258
|
|
- return 0;
|
259
|
|
-}
|
260
|
|
-
|
261
|
|
-static void elf_freebsd_boot(unsigned long entry)
|
262
|
|
-{
|
263
|
|
- if (image_type != Elf_FreeBSD)
|
264
|
|
- return;
|
265
|
|
-
|
266
|
|
- memset(&bsdinfo, 0, sizeof(bsdinfo));
|
267
|
|
- bsdinfo.bi_basemem = meminfo.basememsize;
|
268
|
|
- bsdinfo.bi_extmem = meminfo.memsize;
|
269
|
|
- bsdinfo.bi_memsizes_valid = 1;
|
270
|
|
- bsdinfo.bi_version = BOOTINFO_VERSION;
|
271
|
|
- bsdinfo.bi_kernelname = virt_to_phys(KERNEL_BUF);
|
272
|
|
- bsdinfo.bi_nfs_diskless = NULL;
|
273
|
|
- bsdinfo.bi_size = sizeof(bsdinfo);
|
274
|
|
-#define RB_BOOTINFO 0x80000000 /* have `struct bootinfo *' arg */
|
275
|
|
- if(freebsd_kernel_env[0] != '\0'){
|
276
|
|
- freebsd_howto |= RB_BOOTINFO;
|
277
|
|
- bsdinfo.bi_envp = (unsigned long)freebsd_kernel_env;
|
278
|
|
- }
|
279
|
|
-
|
280
|
|
- /* Check if we have symbols loaded, and if so,
|
281
|
|
- * made the meta_data needed to pass those to
|
282
|
|
- * the kernel. */
|
283
|
|
- if ((symtab_load !=0) && (symstr_load != 0))
|
284
|
|
- {
|
285
|
|
- unsigned long *t;
|
286
|
|
-
|
287
|
|
- bsdinfo.bi_symtab = symtab_load;
|
288
|
|
-
|
289
|
|
- /* End of symbols (long aligned...) */
|
290
|
|
- /* Assumes size of long is a power of 2... */
|
291
|
|
- bsdinfo.bi_esymtab = (symstr_load +
|
292
|
|
- sizeof(long) +
|
293
|
|
- *((long *)phys_to_virt(symstr_load)) +
|
294
|
|
- sizeof(long) - 1) & ~(sizeof(long) - 1);
|
295
|
|
-
|
296
|
|
- /* Where we will build the meta data... */
|
297
|
|
- t = phys_to_virt(bsdinfo.bi_esymtab);
|
298
|
|
-
|
299
|
|
-#if ELF_DEBUG
|
300
|
|
- printf("Metadata at %lX\n",t);
|
301
|
|
-#endif
|
302
|
|
-
|
303
|
|
- /* Set up the pointer to the memory... */
|
304
|
|
- bsdinfo.bi_modulep = virt_to_phys(t);
|
305
|
|
-
|
306
|
|
- /* The metadata structure is an array of 32-bit
|
307
|
|
- * words where we store some information about the
|
308
|
|
- * system. This is critical, as FreeBSD now looks
|
309
|
|
- * only for the metadata for the extended symbol
|
310
|
|
- * information rather than in the bootinfo.
|
311
|
|
- */
|
312
|
|
- /* First, do the kernel name and the kernel type */
|
313
|
|
- /* Note that this assumed x86 byte order... */
|
314
|
|
-
|
315
|
|
- /* 'kernel\0\0' */
|
316
|
|
- *t++=MODINFO_NAME; *t++= 7; *t++=0x6E72656B; *t++=0x00006C65;
|
317
|
|
-
|
318
|
|
- /* 'elf kernel\0\0' */
|
319
|
|
- *t++=MODINFO_TYPE; *t++=11; *t++=0x20666C65; *t++=0x6E72656B; *t++ = 0x00006C65;
|
320
|
|
-
|
321
|
|
- /* Now the symbol start/end - note that they are
|
322
|
|
- * here in local/physical address - the Kernel
|
323
|
|
- * boot process will relocate the addresses. */
|
324
|
|
- *t++=MODINFOMD_SSYM | MODINFO_METADATA; *t++=sizeof(*t); *t++=bsdinfo.bi_symtab;
|
325
|
|
- *t++=MODINFOMD_ESYM | MODINFO_METADATA; *t++=sizeof(*t); *t++=bsdinfo.bi_esymtab;
|
326
|
|
-
|
327
|
|
- *t++=MODINFO_END; *t++=0; /* end of metadata */
|
328
|
|
-
|
329
|
|
- /* Since we have symbols we need to make
|
330
|
|
- * sure that the kernel knows its own end
|
331
|
|
- * of memory... It is not _end but after
|
332
|
|
- * the symbols and the metadata... */
|
333
|
|
- bsdinfo.bi_kernend = virt_to_phys(t);
|
334
|
|
-
|
335
|
|
- /* Signal locore.s that we have a valid bootinfo
|
336
|
|
- * structure that was completely filled in. */
|
337
|
|
- freebsd_howto |= 0x80000000;
|
338
|
|
- }
|
339
|
|
-
|
340
|
|
- xstart32(entry, freebsd_howto, NODEV, 0, 0, 0,
|
341
|
|
- virt_to_phys(&bsdinfo), 0, 0, 0);
|
342
|
|
- longjmp(restart_etherboot, -2);
|
343
|
|
-}
|
344
|
|
-#endif
|
345
|
|
-
|
346
|
|
-#ifdef AOUT_IMAGE
|
347
|
|
-static void aout_freebsd_probe(void)
|
348
|
|
-{
|
349
|
|
- image_type = Aout;
|
350
|
|
- if (((astate.head.a_midmag >> 16) & 0xffff) == 0) {
|
351
|
|
- /* Some other a.out variants have a different
|
352
|
|
- * value, and use other alignments (e.g. 1K),
|
353
|
|
- * not the 4K used by FreeBSD. */
|
354
|
|
- image_type = Aout_FreeBSD;
|
355
|
|
- printf("/FreeBSD");
|
356
|
|
- off = -(astate.head.a_entry & 0xff000000);
|
357
|
|
- astate.head.a_entry += off;
|
358
|
|
- }
|
359
|
|
-}
|
360
|
|
-
|
361
|
|
-static void aout_freebsd_boot(void)
|
362
|
|
-{
|
363
|
|
- if (image_type == Aout_FreeBSD) {
|
364
|
|
- memset(&bsdinfo, 0, sizeof(bsdinfo));
|
365
|
|
- bsdinfo.bi_basemem = meminfo.basememsize;
|
366
|
|
- bsdinfo.bi_extmem = meminfo.memsize;
|
367
|
|
- bsdinfo.bi_memsizes_valid = 1;
|
368
|
|
- bsdinfo.bi_version = BOOTINFO_VERSION;
|
369
|
|
- bsdinfo.bi_kernelname = virt_to_phys(KERNEL_BUF);
|
370
|
|
- bsdinfo.bi_nfs_diskless = NULL;
|
371
|
|
- bsdinfo.bi_size = sizeof(bsdinfo);
|
372
|
|
- xstart32(astate.head.a_entry, freebsd_howto, NODEV, 0, 0, 0,
|
373
|
|
- virt_to_phys(&bsdinfo), 0, 0, 0);
|
374
|
|
- longjmp(restart_etherboot, -2);
|
375
|
|
- }
|
376
|
|
-}
|
377
|
|
-#endif
|