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