浏览代码

Cut out almost all the optional code paths, drastically simplifying the

flow of control through this code.

We now always add PCI and PnP headers even for ISA ROMs; there's no harm
in doing so.

UNDI loader is still missing.
tags/v0.9.3
Michael Brown 18 年前
父节点
当前提交
ef37f78cbe
共有 1 个文件被更改,包括 143 次插入375 次删除
  1. 143
    375
      src/arch/i386/prefix/romprefix.S

+ 143
- 375
src/arch/i386/prefix/romprefix.S 查看文件

@@ -6,412 +6,180 @@
6 6
  * table so using a noticeable amount of stack space is a no-no.
7 7
  */
8 8
 
9
-/* Define DELAYED_INT when NO_DELAYED_INT is not defined.
10
- * This allows positive tests instead of tests that contain
11
- * double negatives, and become confusing.
12
- */
13
-#ifndef NO_DELAYED_INT
14
-#define DELAYED_INT
15
-#endif
16
-
17
-/* We need some unique magic ID, if we defer startup thru the INT18H or INT19H
18
- * handler. This way, we can check if we have already been installed.
19
- */
20
-#ifndef MAGIC
21
-#define MAGIC		0xE44C
22
-#endif
23
-
24
-/* Hook into INT18H or INT19H handler */
25
-#ifdef	BOOT_INT18H
26
-#define BOOT_INT	0x18
27
-#else
28
-#define BOOT_INT	0x19
29
-#endif
30
-
31
-#define BOOT_INT_VEC	BOOT_INT*4
32
-#define SCRATCHVEC	0x300
33
-
34
-/* Prefix exit codes.  We store these on the stack so that we will
35
- * know how to return control to the BIOS when Etherboot exits.
36
- */
37
-#define EXIT_VIA_LRET  		0x0
38
-#define EXIT_VIA_INT_18		0x1
39
-#define EXIT_VIA_BOOT_INT	0x2
40
-
41 9
 	.text
42 10
 	.code16
43 11
 	.arch i386
44
-	.org 0
45 12
 	.section ".prefix", "ax", @progbits
46
-_prefix: 
47
-	.word 0xAA55			/* BIOS extension signature */
48
-size:	.byte 0				/* number of 512 byte blocks */
49
-					/* = number of 256 word blocks */
50
-					/* filled in by makerom program */
51
-	jmp	over			/* skip over checksum */
52
-	.byte 0				/* checksum */
53
-	jmp	legacyentry		/* alternate entry point +6 */
54
-					/* used by mknbi-rom */
55
-
56
-#ifdef	PCI_PNP_HEADER
57
-mfgstr:
58
-	.asciz	"Etherboot"
59 13
 	
60
-#ifdef	PXE_EXPORT
14
+	.org	0x00
15
+romheader:
16
+	.word	0xAA55			/* BIOS extension signature */
17
+	.byte	_rom_size		/* Size in 512-byte blocks */
18
+	jmp	init_vector		/* Initialisation vector */
61 19
 	.org	0x16
62
-	.word	UNDIROMID - _prefix
63
-#endif	/* PXE_EXPORT */
64
-	
20
+	.word	undiheader
65 21
 	.org	0x18
66
-	.word	PCI - _prefix
67
-	.word	PnP - _prefix
68
-
69
-PCI: 
70
-	.ascii	"PCIR"
71
-	.word 0x0000			/* vendor ID, filled in by makerom */
72
-	.word 0x0000			/* device ID, filled in by makerom */
73
-	.word 0x0000			/* pointer to vital product data */
74
-	.word 0x0018			/* PCI data structure length */
75
-	.byte 0x00			/* PCI data structure revision */
76
-	.byte 0x02			/* Device Base Type code */
77
-	.byte 0x00			/* Device Sub-Type code */
78
-	.byte 0x00			/* Device Interface Type code */
79
-	.word 0x0000			/* Image length same as offset 02h */
80
-	.word 0x0001			/* revision level of code/data */
81
-	.byte 0x00			/* code type */
82
-	.byte 0x80			/* indicator (last PCI data structure) */
83
-	.word 0x0000			/* reserved */
22
+	.word	pciheader
23
+	.org	0x1a
24
+	.word	pnpheader
25
+	.size romheader, . - romheader
26
+
27
+pciheader:
28
+	.ascii	"PCIR"			/* Signature */
29
+	.word	pci_vendor_id		/* Vendor ID */ 
30
+	.word	pci_device_id		/* Device ID */
31
+	.word	0x0000			/* pointer to vital product data */
32
+	.word	pciheader_len		/* PCI data structure length */
33
+	.byte	0x00			/* PCI data structure revision */
34
+	.byte	0x02			/* Device Base Type code */
35
+	.byte	0x00			/* Device Sub-Type code */
36
+	.byte	0x00			/* Device Interface Type code */
37
+	.word	_rom_size		/* Image length same as offset 02h */
38
+	.word	0x0001			/* revision level of code/data */
39
+	.byte	0x00			/* code type */
40
+	.byte	0x80			/* Flags (last PCI data structure) */
41
+	.word	0x0000			/* reserved */
42
+	.equ pciheader_len, . - pciheader
43
+	.size pciheader, . - pciheader
44
+
45
+pnpheader:
46
+	.ascii	"$PnP"			/* Signature */
47
+	.byte	0x01			/* Structure revision */
48
+	.byte	( pnpheader_len	/ 16 )	/* Length (in 16 byte increments) */
49
+	.word	0x0000			/* Offset of next header */
50
+	.byte	0x00			/* Reserved */
51
+	.byte	0x00			/* Checksum */
52
+	.long	0x00000000		/* Device identifier */
53
+	.word	mfgstr			/* Manufacturer string */
54
+	.word	prodstr			/* Product name */
55
+	.byte	0x02			/* Device base type code */
56
+	.byte	0x00			/* Device sub-type code */
57
+	.byte	0x00			/* Device interface type code */
58
+	.byte	0x54			/* Device indicator */
59
+	.word	0x0000			/* Boot connection vector */
60
+	.word	0x0000			/* Disconnect vector */
61
+	.word	exec_vector		/* Boot execution vector */
62
+	.word	0x0000			/* Reserved */
63
+	.word	0x0000			/* Static resource information vector*/
64
+	.equ pnpheader_len, . - pnpheader
65
+	.size pnpheader, . - pnpheader
84 66
 
85
-PnP:
86
-	.ascii	"$PnP"
87
-	.byte 0x01			/* structure revision */
88
-	.byte 0x02			/* length (in 16 byte increments) */
89
-	.word 0x0000			/* offset of next header */
90
-	.byte 0x00			/* Reserved */
91
-	.byte 0x00			/* checksum filled by makerom */
92
-	.long 0x00000000		/* Device identifier */
93
-	.word mfgstr - _prefix
94
-	.word 0x0			/* pointer to product name */
95
-					/* filled by makerom */
96
-	.byte 0x02			/* Device Base Type code */
97
-	.byte 0x00			/* Device Sub-Type code */
98
-	.byte 0x00			/* Device Interface Type code */
99
-	.byte 0x14			/* device indicator */
100
-	.word 0x0000			/* boot connection vector */
101
-	.word 0x0000			/* disconnect vector */
102
-	.word pnpentry - _prefix
103
-	.word 0x0000			/* reserved */
104
-	.word 0x0000			/* static resource information vector */
105
-#ifdef	PXE_EXPORT
106
-UNDIROMID:
107
-	.ascii	"UNDI"
108
-	.byte	UNDIROMID_end - UNDIROMID /* length of structure */
67
+mfgstr:
68
+	.asciz	"http://etherboot.org"
69
+	.size mfgstr, . - mfgstr
70
+prodstr:
71
+	.asciz	"Etherboot"
72
+	.size prodstr, . - prodstr
73
+	
74
+undiheader:
75
+	.ascii	"UNDI"			/* Signature */
76
+	.byte	undiheader_len		/* Length of structure */
109 77
 	.byte	0			/* Checksum */
110 78
 	.byte	0			/* Structure revision */
111
-	.byte	0,1,2			/* PXE version 2.1.0 */
112
-	.word	UNDILoader - _prefix	/* Offset to loader routine */
113
-	.word	_real_mode_stack_size	/* Stack segment size */
114
-	.word	_real_mode_stack_size	/* Data segment size */
115
-	.word	_pxe_stack_size		/* Code segment size */
116
-	.ascii	"PCIR"
117
-
118
-	/* The code segment contains our pxe_stack_t plus the PXE and
119
-	 * RM callback interfaces.  We don't actually use a data
120
-	 * segment, but we put a nonzero value here to avoid confusing
121
-	 * things.  16k of stack space should be enough.
122
-	 *
123
-	 * When we claim our own memory, we fill out the data segment
124
-	 * with the address and size of the real-mode stack, so that
125
-	 * NBPs will free that area of memory for us.  When the UNDI
126
-	 * loader is used to initialise us, we will never need a
127
-	 * real-mode stack because we will only ever be called via the
128
-	 * PXE API, hence our stack is already in base memory.
129
-	 */
130
-	.equ	UNDICodeSize, _pxe_stack_size
131
-	.equ	UNDIDataSize, _real_mode_stack_size
132
-	.equ	UNDIStackSize, _real_mode_stack_size
133
-UNDIROMID_end:	
134
-#endif	/* PXE_EXPORT */
135
-	
136
-#endif	/* PCI_PNP_HEADER */
137
-
138
-/*
139
- *	Explicitly specify DI is wrt ES to avoid problems with some BIOSes
140
- *	Discovered by Eric Biederman
141
- *	In addition, some BIOSes don't point DI to the string $PnP so
142
- *	we need another #define to take care of that.
79
+	.byte	0,1,2			/* PXE version: 2.1.0 */
80
+	.word	undiloader		/* Offset to loader routine */
81
+	.word	_data16_size		/* Stack segment size */
82
+	.word	_data16_size		/* Data segment size */
83
+	.word	_text16_size		/* Code segment size */
84
+	.equ undiheader_len, . - undiheader
85
+	.size undiheader, . - undiheader
86
+
87
+/* Initialisation vector
88
+ *
89
+ * Determine whether or not this is a PnP system via a signature
90
+ * check.  If it is PnP, return to the PnP BIOS indicating that we are
91
+ * a boot-capable device; the BIOS will call our boot execution vector
92
+ * if it wants to boot us.  If it is not PnP, hook INT 19.
143 93
  */
144
-over:	
145
-#ifdef	DEBUG_ROMPREFIX
146
-	call	print_bcv
147
-#endif
148
-/* Omit this test for ISA cards anyway */
149
-#ifdef	PCI_PNP_HEADER
150
-/* Accept old name too for backward compatibility */
151
-#if	!defined(BBS_BUT_NOT_PNP_COMPLIANT) && !defined(PNP_BUT_NOT_BBS_COMPLIANT)
152
-	cmpw	$'$'+'P'*256,%es:0(%di)
94
+init_vector:
95
+	pushw	%si
96
+	cmpw	$'$'+'P'*256, %es:0(%di)
153 97
 	jne	notpnp
154
-	cmpw	$'n'+'P'*256,%es:2(%di)
98
+	cmpw	$'n'+'P'*256, %es:2(%di)
155 99
 	jne	notpnp
156
-#endif	/* BBS_BUT_NOT_PNP_COMPLIANT */
157
-	movw	$0x20,%ax
158
-	lret
159
-#endif	/* PCI_PNP_HEADER */
100
+ispnp:
101
+	movw	$ispnp_message, %si
102
+	jmp	99f
160 103
 notpnp:
161
-#ifdef	DEBUG_ROMPREFIX
162
-	call	print_notpnp
163
-#endif
164
-#ifdef  DELAYED_INT
165
-	pushw	%ax
166 104
 	pushw	%ds
167
-	xorw	%ax,%ax
168
-	movw	%ax,%ds			/* access first 64kB segment */
169
-	movw	SCRATCHVEC+4, %ax	/* check if already installed */
170
-	cmpw	$MAGIC, %ax		/* check magic word */
171
-	jz	installed
172
-	movw	BOOT_INT_VEC, %ax	/* hook into INT18H or INT19H */
173
-	movw	%ax, SCRATCHVEC
174
-	movw	BOOT_INT_VEC+2, %ax
175
-	movw	%ax, SCRATCHVEC+2
176
-	movw	$start_int - _prefix, %ax
177
-	movw	%ax, BOOT_INT_VEC
178
-	movw	%cs,%ax
179
-	movw	%ax, BOOT_INT_VEC+2
180
-	movw	$MAGIC, %ax		/* set magic word */
181
-	movw	%ax, SCRATCHVEC+4
182
-#ifdef	DEBUG_ROMPREFIX
183
-	call	print_installed
184
-#endif
185
-installed:
105
+	pushw	$0
186 106
 	popw	%ds
187
-	popw	%ax
188
-	movw	$0x20,%ax
107
+	pushw	%cs
108
+	pushw	$exec_vector
109
+	popl	( 0x19 * 4 )
110
+	popw	%ds
111
+	movw	$notpnp_message, %si
112
+99:
113
+	call	print_message
114
+	movw	$0x20, %ax
115
+	popw	%si
189 116
 	lret
117
+	.size init_vector, . - init_vector
190 118
 
191
-start_int:				/* clobber magic id, so that we will */
192
-#ifdef	DEBUG_ROMPREFIX
193
-	call	print_start_int
194
-#endif
195
-	xorw	%ax,%ax			/* not inadvertendly end up in an */
196
-	movw	%ax,%ds			/* endless loop */
197
-	movw	%ax, SCRATCHVEC+4
198
-	movw	SCRATCHVEC+2, %ax	/* restore original INT19h handler */
199
-	movw	%ax, BOOT_INT_VEC+2
200
-	movw	SCRATCHVEC, %ax
201
-	movw	%ax, BOOT_INT_VEC
202
-	pushl	%eax			/* padding */
203
-	pushw	$EXIT_VIA_BOOT_INT
204
-	jmp	invoke
205
-#endif	/* DELAYED_INT */
206
-
207
-
208
-
209
-	
210
-legacyentry:
211
-#ifdef	DEBUG_ROMPREFIX
212
-	call	print_legacyentry
213
-#endif
214
-	pushw	$EXIT_VIA_LRET
215
-	jmp	invoke
119
+ispnp_message:
120
+	.asciz	"Etherboot detected PnP BIOS\r\n"
121
+	.size ispnp_message, . - ispnp_message
122
+notpnp_message:
123
+	.asciz	"Etherboot detected non-PnP BIOS\r\n"
124
+	.size notpnp_message, . - notpnp_message
216 125
 
126
+/* Boot execution vector
127
+ *
128
+ * Called by the PnP BIOS when it wants to boot us, or via the hooked
129
+ * INT 19 if we detected a non-PnP BIOS.
130
+ */	
131
+exec_vector:
132
+	/* Obtain a reasonably-sized stack */
133
+	xorw	%ax, %ax
134
+	movw	%ax, %ss
135
+	movw	$0x7c00, %sp
217 136
 	
218
-	
219
-#ifdef PCI_PNP_HEADER
220
-pnpentry:
221
-#ifdef	DEBUG_ROMPREFIX
222
-	call	print_bev
223
-#endif
224
-	pushl	%eax			/* padding */
225
-	pushw	$EXIT_VIA_INT_18
226
-	jmp	invoke
227
-#endif /* PCI_PNP_HEADER */
137
+	movw	$exec_message, %si
138
+	call	print_message
228 139
 
140
+	call	install
229 141
 
230
-invoke:
231
-	/* Store ROM segment and size on stack */
142
+	/* Jump to .text16 segment */
232 143
 	pushw	%ax
233
-	pushw   %ds
144
+	pushw	$1f
145
+	lret
146
+	.section ".text16", "awx", @progbits
147
+1:
148
+	pushl	$main
234 149
 	pushw	%cs
235
-	movzbw	%cs:(size-_prefix), %ax
236
-	shlw	$9, %ax			/* 512-byte blocks */
237
-	pushw	%ax
238
-	/* Relocate to free base memory, switch stacks */
239
-	pushw	$12			/* Preserve exit code & far ret addr */
240
-	call	prelocate
241
-	/* We are now running in RAM */
242
-	popw	%ax			/* padding */
243
-	movw	%cs, %ax
244
-	movw	%ax, %ds
245
-	popw	%ds:(_prefix_rom+2)	/* ROM size */
246
-	popw	%ds:(_prefix_rom+0)	/* ROM segment */
247
-	popw	%ds			/* Original %ds */
248
-	popw	%ax			/* Original %ax */
249
-	pushw	%ax			/* 4-byte alignment */
250
-	pushl	$8			/* Preserve exit code & far ret addr */
251
-	pushw	$0			/* Set null return address */
252
-	jmp	_start
253
-	
150
+	call	prot_call
151
+	popl	%eax /* discard */
254 152
 
255
-	.section ".text16", "ax", @progbits
256
-prefix_exit:
257
-	popw	%ax			/* padding */
258
-	popw	%ax			/* %ax = exit code */
259
-	cmpw	$EXIT_VIA_LRET, %ax
260
-	jne	1f
261
-	/* Exit via LRET */
262
-	lret
263
-1:	addw	$4, %sp			/* Strip padding */
264
-	cmpw	$EXIT_VIA_BOOT_INT, %ax
265
-	jne	2f
266
-	/* Exit via int BOOT_INT */
267
-	int	$BOOT_INT		/* Try original vector */
268
-2:	/* Exit via int $0x18 */
269
-	int	$0x18			/* As per BIOS Boot Spec, next dev */
270
-prefix_exit_end:
153
+	/* Boot next device */
154
+	int	$0x18
271 155
 	.previous
272 156
 
273
-	
274
-
275
-/* UNDI loader needs to be rewritten to use new mechanism */
276
-#if 0
277
-		
278
-#ifdef 	PXE_EXPORT
279
-
280
-#define PXENV_UNDI_LOADER		0x104d
157
+exec_message:
158
+	.asciz	"Etherboot starting boot\r\n"
159
+	.size exec_message, . - exec_message
281 160
 
282
-	.section ".prefix"
283
-UNDILoader:
284
-	/* Loader API is different to the usual PXE API; there is no
285
-	 * opcode on the stack.  We arrange the stack to look like a
286
-	 * normal PXE API call; this makes the Etherboot internals
287
-	 * cleaner and avoids adding an extra API type just for the
288
-	 * PXE loader.
289
-	 */
290
-	pushw	%bx
291
-	movw	%sp, %ax		/* Store original %ss:sp */
292
-	pushw	%ss
161
+/* UNDI loader
162
+ *
163
+ * Called by an external program to load our PXE stack.
164
+ */
165
+undiloader:
166
+	.size undiloader, . - undiloader
167
+				
168
+/* Utility function: print string
169
+ */
170
+print_message:
293 171
 	pushw	%ax
294
-	pushl	%eax			/* Space for loader structure ptr */
172
+	pushw	%bx
295 173
 	pushw	%bp
296
-	movw	%sp, %bp
297
-	movw	16(%bp), %ax		/* Copy loader structure ptr */
298
-	movw	%ax, 2(%bp)
299
-	movw	18(%bp), %ax
300
-	movw	%ax, 4(%bp)
301
-	popw	%bp
302
-	pushw	$PXENV_UNDI_LOADER	/* PXE 'opcode' */
303
-	pushl	%eax			/* dummy return address */
304
-	/* Stack now looks like a normal PXE API call */
305
-	/* Store ROM segment and size on stack */
306
-	pushw	%ax
307
-	pushw	%cs
308
-	movzbw	%cs:(size-_prefix), %ax
309
-	shlw	$9, %ax			/* 512-byte blocks */
310
-	pushw	%ax
311
-	/* Unpack Etherboot into temporarily claimed base memory */
312
-	pushw	$20			/* Dummy ret, PXE params, orig ss:sp */
313
-	call	prelocate
314
-	popw	%ax			/* discard */
315
-	popw	%cs:(_prefix_rom+2)	/* ROM size */
316
-	popw	%cs:(_prefix_rom+0)	/* ROM segment */
317
-	popw	%ax			/* Original %ax */
318
-	/* Inhibit automatic deallocation of base memory */
319
-	movl	$0, %cs:_prefix_image_basemem
320
-	/* Make PXE API call to Etherboot */
321
-	pushl	$0x201			/* PXE API version */
322
-	/* Need to USE_INTERNAL_STACK, since we will call relocate() */
323
-	pushl	$(EB_OPCODE_PXE|EB_USE_INTERNAL_STACK) /* PXE API call type */
324
-	call	_entry
325
-	addw	$18, %sp		/* discard */
326
-	popw	%bx			/* Restore original %ss:sp */
327
-	popw	%ss
328
-	movw	%bx, %sp
329
-	popw	%bx
330
-	call	deprelocate
331
-	lret	$2			/* Skip our PXE 'opcode' */
332
-#endif	/* PXE_EXPORT */
333
-
334
-#endif /* 0 */
335
-			
336
-#ifdef DEBUG_ROMPREFIX
337
-	.section ".prefix"
338
-
339
-print_bcv:
340
-	pushw	%si
341
-	movw	$1f-_prefix, %si
342
-	call	print_message
343
-	popw	%si
344
-	ret
345
-1:	.asciz	"ROM detected\r\n"
346
-
347
-print_bev:
348
-	pushw	%si
349
-	movw	$1f-_prefix, %si
350
-	call	print_message
351
-	popw	%si
352
-	ret
353
-1:	.asciz	"booting\r\n"
354
-
355
-print_notpnp:
356
-	pushw	%si
357
-	movw	$1f-_prefix, %si
358
-	call	print_message
359
-	popw	%si
360
-	ret
361
-1:	.asciz	": Non-PnP BIOS detected!\r\n"
362
-
363
-print_legacyentry:
364
-	pushw	%si
365
-	movw	$1f-_prefix, %si
366
-	call	print_message
367
-	popw	%si
368
-	ret
369
-1:	.asciz	"ROM using legacy boot mechanism\r\n"
370
-
371
-print_installed:
372
-	pushw	%si
373
-	movw	$1f-_prefix, %si
374
-	call	print_message
375
-	popw	%si
376
-	ret
377
-1:	.ascii	"hooked boot via INT"
378
-#ifdef	BOOT_INT18H
379
-	.asciz	"18\r\n"
380
-#else
381
-	.asciz	"19\r\n"
382
-#endif
383
-
384
-print_start_int:
385
-	pushw	%si
386
-	movw	$1f-_prefix, %si
387
-	call	print_message
388
-	popw	%si
389
-	ret
390
-1:	.asciz	"booting via hooked interrupt\r\n"
391
-
392
-print_message:
393
-	pushaw
394
-	pushw	%ds
395
-	pushw	%cs
396
-	popw	%ds
397
-	pushw	%si
398
-	movw	$1f-_prefix, %si
399
-	call	print_string
400
-	popw	%si
401
-	call    print_string
402
-	popw	%ds
403
-	popaw
404
-	ret
405
-1:	.asciz	"Etherboot "
406
-
407
-print_string:
408
-1:	lodsb
409
-	testb	%al,%al
174
+	movw    $0x0007, %bx
175
+1:	cs lodsb
176
+	testb	%al, %al
410 177
 	je	2f
411
-	movw    $0x0007, %bx            /* page 0, attribute 7 (normal) */
412 178
 	movb    $0x0e, %ah              /* write char, tty mode */
413 179
 	int     $0x10
414 180
 	jmp	1b
415
-2:	ret
416
-	
417
-#endif
181
+2:	popw	%bp
182
+	popw	%bx
183
+	popw	%ax
184
+	ret
185
+	.size print_message, . - print_message

正在加载...
取消
保存