Parcourir la source

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 il y a 18 ans
Parent
révision
ef37f78cbe
1 fichiers modifiés avec 143 ajouts et 375 suppressions
  1. 143
    375
      src/arch/i386/prefix/romprefix.S

+ 143
- 375
src/arch/i386/prefix/romprefix.S Voir le fichier

@@ -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

Chargement…
Annuler
Enregistrer