Kaynağa Gözat

[pxeprefix] Search for the PXE entry points through all methods

Search for the PXE entry points (via the !PXE or PXENV+ structures)
through all known combinations of search methods.  Furthermore, if we
find a PXENV+ structure, attempt to use it to find the !PXE structure
if at all possible.
tags/v0.9.7
H. Peter Anvin 15 yıl önce
ebeveyn
işleme
6a3f5d6db7
1 değiştirilmiş dosya ile 105 ekleme ve 42 silme
  1. 105
    42
      src/arch/i386/prefix/pxeprefix.S

+ 105
- 42
src/arch/i386/prefix/pxeprefix.S Dosyayı Görüntüle

@@ -31,18 +31,10 @@
31 31
 	pushl	$STACK_MAGIC
32 32
 	movw	%ss, %cs:pxe_ss
33 33
 	movl	%esp, %cs:pxe_esp
34
-	movw	%sp, %bp
35
-	movl	(10*4+4*2+4)(%bp),%ebp	/* !PXE address */
36 34
 
37
-	/* Set up %ds */
35
+	/* Set up segments */
38 36
 	movw	%cs, %ax
39 37
 	movw	%ax, %ds
40
-	/* Record PXENV+ and !PXE nominal addresses */
41
-	movw	%es, pxenv_segment	/* PXENV+ address */
42
-	movw	%bx, pxenv_offset
43
-	movl	%ebp, ppxe_segoff	/* !PXE address */
44
-	/* Set up %es and %fs */
45
-	movw	%ax, %es
46 38
 	movw	$0x40, %ax		/* BIOS data segment access */
47 39
 	movw	%ax, %fs
48 40
 	/* Set up stack just below 0x7c00 */
@@ -60,16 +52,57 @@
60 52
 	.previous
61 53
 
62 54
 /*****************************************************************************
63
- * Verify PXENV+ structure and record parameters of interest
55
+ * Find us a usable !PXE or PXENV+ entry point
64 56
  *****************************************************************************
65 57
  */
66
-detect_pxenv:
67
-	/* Signature check */
68
-	les	pxenv_segoff, %bx
69
-	cmpl	$0x4e455850, %es:(%bx)	/* 'PXEN' signature */
70
-	jne	no_pxenv
71
-	cmpw	$0x2b56, %es:4(%bx)	/* 'V+' signature */
72
-	jne	no_pxenv
58
+detect_pxe:
59
+	/* Plan A: !PXE pointer from the stack */
60
+	lgsl	pxe_esp, %ebp		/* %gs:%bp -> original stack */
61
+	lesw	%gs:52(%bp), %bx
62
+	call	is_valid_ppxe
63
+	je	have_ppxe
64
+
65
+	/* Plan B: PXENV+ pointer from initial ES:BX */
66
+	movw	%gs:32(%bp),%bx
67
+	movw	%gs:8(%bp),%es
68
+	call	is_valid_pxenv
69
+	je	have_pxenv
70
+
71
+	/* Plan C: PXENV+ structure via INT 1Ah */
72
+	movw	$0x5650, %ax
73
+	int	$0x1a
74
+	jc	1f
75
+	cmpw	$0x564e, %ax
76
+	jne	1f
77
+	call	is_valid_pxenv
78
+	je	have_pxenv
79
+1:
80
+	/* Plan D: scan base memory for !PXE */
81
+	call	memory_scan_ppxe
82
+	je	have_ppxe
83
+
84
+	/* Plan E: scan base memory for PXENV+ */
85
+	call	memory_scan_pxenv
86
+	jne	stack_not_found
87
+	
88
+have_pxenv:
89
+	movw	%bx, pxenv_offset
90
+	movw	%es, pxenv_segment
91
+
92
+	cmpw	$0x201, %es:6(%bx)	/* API version >= 2.01 */
93
+	jb	1f
94
+	cmpb	$0x2c, %es:8(%bx)	/* ... and structure long enough */
95
+	jb	2f
96
+
97
+	lesw	%es:0x28(%bx), %bx	/* Find !PXE from PXENV+ */
98
+	call	is_valid_ppxe
99
+	je	have_ppxe
100
+2:
101
+	call	memory_scan_ppxe	/* We are *supposed* to have !PXE... */
102
+	je	have_ppxe
103
+1:
104
+	lesw	pxenv_segoff, %bx	/* Nope, we're stuck with PXENV+ */
105
+
73 106
 	/* Record entry point and UNDI segments */
74 107
 	pushl	%es:0x0a(%bx)		/* Entry point */
75 108
 	popl	entry_segoff
@@ -79,36 +112,22 @@ detect_pxenv:
79 112
 	pushw	%es:0x20(%bx)		/* UNDI data segment */
80 113
 	pushw	%es:0x22(%bx)		/* UNDI data size */
81 114
 	popl	undi_data_segoff
115
+
82 116
 	/* Print "PXENV+ at <address>" */
83 117
 	movw	$10f, %si
84 118
 	call	print_message
85 119
 	call	print_segoff
86 120
 	movb	$( ',' ), %al
87 121
 	call	print_character
88
-	jmp	99f
122
+	jmp	check_have_stack
89 123
 	.section ".prefix.data", "aw", @progbits
90 124
 10:	.asciz	" PXENV+ at "
91 125
 	.previous
92 126
 
93
-no_pxenv:
94
-	xorl	%eax, %eax
95
-	movl	%eax, pxenv_segoff
96
-	
97
-99:
98
-	
99
-/*****************************************************************************
100
- * Verify !PXE structure and record parameters of interest
101
- *****************************************************************************
102
- */
103
-detect_ppxe:
104
-	/* Signature check */
105
-	les	ppxe_segoff, %bx
106
-	cmpl	$0x45585021, %es:(%bx)	/* '!PXE' signature */
107
-	jne	no_ppxe
108
-	/* Record structure address, entry point, and UNDI segments */
109
-	pushw	%es
110
-	popw	ppxe_segment
127
+have_ppxe:
111 128
 	movw	%bx, ppxe_offset
129
+	movw	%es, ppxe_segment
130
+	
112 131
 	pushl	%es:0x10(%bx)		/* Entry point */
113 132
 	popl	entry_segoff
114 133
 	pushw	%es:0x30(%bx)		/* UNDI code segment */
@@ -123,17 +142,60 @@ detect_ppxe:
123 142
 	call	print_segoff
124 143
 	movb	$( ',' ), %al
125 144
 	call	print_character
126
-	jmp	99f
145
+	jmp	check_have_stack
127 146
 	.section ".prefix.data", "aw", @progbits
128 147
 10:	.asciz	" !PXE at "
129 148
 	.previous
130 149
 
131
-no_ppxe:
132
-	xorl	%eax, %eax
133
-	movl	%eax, ppxe_segoff
150
+is_valid_ppxe:
151
+	cmpl	$0x45585021, %es:(%bx)
152
+	jne	1f
153
+	movzbw	%es:4(%bx), %cx
154
+	cmpw	$0x58, %cx
155
+	jae	is_valid_checksum
156
+1:
157
+	ret
158
+	
159
+is_valid_pxenv:
160
+	cmpl	$0x4e455850, %es:(%bx)
161
+	jne	1b
162
+	cmpw	$0x2b56, %es:4(%bx)
163
+	jne	1b
164
+	movzbw	%es:8(%bx), %cx
165
+	cmpw	$0x28, %cx
166
+	jb	1b
167
+	
168
+is_valid_checksum:
169
+	pushw	%ax
170
+	movw	%bx, %si
171
+	xorw	%ax, %ax
172
+2:
173
+	es lodsb
174
+	addb	%al, %ah
175
+	loopw	2b
176
+	popw	%ax
177
+	ret
178
+
179
+memory_scan_ppxe:
180
+	movw	$is_valid_ppxe, %dx
181
+	jmp	memory_scan_common
134 182
 
135
-99:
183
+memory_scan_pxenv:
184
+	movw	$is_valid_pxenv, %dx
136 185
 
186
+memory_scan_common:
187
+	movw	%fs:(0x13), %ax
188
+	shlw	$6, %ax
189
+	decw	%ax
190
+1:	incw	%ax
191
+	cmpw	$( 0xa000 - 1 ), %ax
192
+	ja	2f
193
+	movw	%ax, %es
194
+	xorw	%bx, %bx
195
+	call	*%dx
196
+	jne	1b
197
+2:	ret
198
+	
137 199
 /*****************************************************************************
138 200
  * Sanity check: we must have an entry point
139 201
  *****************************************************************************
@@ -144,6 +206,7 @@ check_have_stack:
144 206
 	testl	%eax, %eax
145 207
 	jnz	99f
146 208
 	/* No entry point: print message and skip everything else */
209
+stack_not_found:
147 210
 	movw	$10f, %si
148 211
 	call	print_message
149 212
 	jmp	finished
@@ -529,8 +592,8 @@ print_pxe_error:
529 592
  */
530 593
 	.section ".prefix.data"
531 594
 
532
-pxe_ss:			.word 0
533 595
 pxe_esp:		.long 0
596
+pxe_ss:			.word 0
534 597
 
535 598
 pxe_parameter_structure: .fill 20
536 599
 

Loading…
İptal
Kaydet