|
@@ -1,16 +1,9 @@
|
1
|
|
-/* Offsets of words containing ROM's CS and size (in 512 byte blocks)
|
2
|
|
- * from start of floppy boot block at 0x7c00
|
3
|
|
- * Offsets must match those in etherboot.h
|
4
|
|
- */
|
5
|
|
-#define FLOPPY_SEGMENT 0x7c0
|
6
|
|
-
|
7
|
1
|
#define PXENV_UNDI_CLEANUP 0x02
|
8
|
2
|
#define PXENV_UNDI_SHUTDOWN 0x05
|
9
|
3
|
#define PXENV_STOP_UNDI 0x15
|
10
|
4
|
#define PXENV_UNLOAD_STACK 0x70
|
11
|
5
|
#define PXENV_STOP_BASE 0x76
|
12
|
6
|
|
13
|
|
-#define PUSHA_SIZE 16
|
14
|
7
|
#define PXE_STACK_MAGIC 0x57ac /* 'STac' */
|
15
|
8
|
|
16
|
9
|
.text
|
|
@@ -22,21 +15,35 @@
|
22
|
15
|
* Entry point: set cs, ds, bp, print welcome message
|
23
|
16
|
*****************************************************************************
|
24
|
17
|
*/
|
25
|
|
-_prefix:
|
26
|
|
- jmp $FLOPPY_SEGMENT, $code_start-_prefix
|
|
18
|
+ jmp $0x7c0, $code_start
|
27
|
19
|
10: .asciz "PXE->EB "
|
28
|
20
|
code_start:
|
29
|
|
- pusha /* Preserve all registers */
|
30
|
|
- push %ds
|
31
|
|
- movw %sp, %bp /* %bp must be preserved, hence do
|
32
|
|
- * this after the pusha */
|
33
|
|
- push $PXE_STACK_MAGIC /* PXE stack magic marker */
|
34
|
|
-
|
35
|
|
- push %cs /* Set up data segment */
|
36
|
|
- pop %ds
|
37
|
|
- mov $0x40, %cx /* Set up %fs for access to 40:13 */
|
38
|
|
- mov %cx, %fs
|
39
|
|
- movw $10b-_prefix, %si /* Print welcome message */
|
|
21
|
+ /* Preserve registers for return to PXE stack */
|
|
22
|
+ pushfl
|
|
23
|
+ pushal
|
|
24
|
+ pushw %gs
|
|
25
|
+ pushw %fs
|
|
26
|
+ pushw %es
|
|
27
|
+ pushw %ds
|
|
28
|
+ pushw %ss
|
|
29
|
+ pushw %cs
|
|
30
|
+ pushw $PXE_STACK_MAGIC /* PXE stack magic marker */
|
|
31
|
+ /* Set up stack just below 0x7c00 */
|
|
32
|
+ pushw %ss
|
|
33
|
+ popw %es
|
|
34
|
+ movw %sp, %di
|
|
35
|
+ xorw %ax, %ax
|
|
36
|
+ movw %ax, %ss
|
|
37
|
+ movw $0x7c00, %sp
|
|
38
|
+ pushw %es /* Save old PXE stack pointer */
|
|
39
|
+ pushw %di
|
|
40
|
+ /* Set up our other segment registers */
|
|
41
|
+ pushw %cs
|
|
42
|
+ popw %ds
|
|
43
|
+ movw $0x40, %ax /* BIOS data segment access */
|
|
44
|
+ movw %ax, %fs
|
|
45
|
+ /* Print welcome message */
|
|
46
|
+ movw $10b, %si
|
40
|
47
|
call print_message
|
41
|
48
|
|
42
|
49
|
/*****************************************************************************
|
|
@@ -44,12 +51,12 @@ code_start:
|
44
|
51
|
*****************************************************************************
|
45
|
52
|
*/
|
46
|
53
|
detect_pxe:
|
47
|
|
- les 4+PUSHA_SIZE+2(%bp), %di /* !PXE structure */
|
|
54
|
+ les %es:54(%di), %di /* !PXE structure */
|
48
|
55
|
cmpl $0x45585021, %es:(%di) /* '!PXE' signature */
|
49
|
56
|
je detected_pxe
|
50
|
|
- mov $0x5650, %ax
|
|
57
|
+ movw $0x5650, %ax
|
51
|
58
|
int $0x1a
|
52
|
|
- cmp $0x564e, %ax
|
|
59
|
+ cmpw $0x564e, %ax
|
53
|
60
|
jne detected_nothing
|
54
|
61
|
cmpl $0x4e455850, %es:(%bx) /* 'PXEN' signature */
|
55
|
62
|
jne detected_nothing
|
|
@@ -57,49 +64,45 @@ detect_pxe:
|
57
|
64
|
je detected_pxenv
|
58
|
65
|
|
59
|
66
|
detected_nothing:
|
60
|
|
- movw $10f-_prefix, %si
|
|
67
|
+ movw $10f, %si
|
61
|
68
|
call print_message
|
62
|
69
|
jmp finished_with_error
|
63
|
70
|
10: .asciz "No PXE "
|
64
|
71
|
|
65
|
72
|
detected_pxenv: /* es:bx points to PXENV+ structure */
|
66
|
|
- push %es
|
67
|
|
- push %bx
|
68
|
|
- push %es:0x24(%bx) /* UNDI code segment */
|
69
|
|
- push %es:0x26(%bx) /* UNDI code size */
|
70
|
|
- push %es:0x20(%bx) /* UNDI data segment */
|
71
|
|
- push %es:0x22(%bx) /* UNDI data size */
|
|
73
|
+ pushw %es
|
|
74
|
+ pushw %bx
|
|
75
|
+ pushw %es:0x24(%bx) /* UNDI code segment */
|
|
76
|
+ pushw %es:0x26(%bx) /* UNDI code size */
|
|
77
|
+ pushw %es:0x20(%bx) /* UNDI data segment */
|
|
78
|
+ pushw %es:0x22(%bx) /* UNDI data size */
|
72
|
79
|
les %es:0x0a(%bx), %di /* Entry point to %es:%di */
|
73
|
|
- movw $10f-_prefix, %si
|
|
80
|
+ movw $10f, %si
|
74
|
81
|
jmp pxe_setup_done
|
75
|
82
|
10: .asciz "PXENV+ "
|
76
|
83
|
|
77
|
84
|
detected_pxe: /* es:di points to !PXE structure */
|
78
|
|
- push %es
|
79
|
|
- push %di
|
80
|
|
- push %es:0x30(%di) /* UNDI code segment */
|
81
|
|
- push %es:0x36(%di) /* UNDI code size */
|
82
|
|
- push %es:0x28(%di) /* UNDI data segment */
|
83
|
|
- push %es:0x2e(%di) /* UNDI data size */
|
|
85
|
+ pushw %es
|
|
86
|
+ pushw %di
|
|
87
|
+ pushw %es:0x30(%di) /* UNDI code segment */
|
|
88
|
+ pushw %es:0x36(%di) /* UNDI code size */
|
|
89
|
+ pushw %es:0x28(%di) /* UNDI data segment */
|
|
90
|
+ pushw %es:0x2e(%di) /* UNDI data size */
|
84
|
91
|
les %es:0x10(%di), %di /* Entry point to %es:%di */
|
85
|
|
- movw $10f-_prefix, %si
|
|
92
|
+ movw $10f, %si
|
86
|
93
|
jmp pxe_setup_done
|
87
|
94
|
10: .asciz "!PXE "
|
88
|
95
|
|
89
|
96
|
pxe_setup_done:
|
90
|
|
- mov %es, pxe_entry_segment - _prefix
|
91
|
|
- mov %di, pxe_entry_offset - _prefix
|
92
|
|
- pop %ax
|
93
|
|
- mov %ax, undi_data_size - _prefix
|
94
|
|
- pop %ax
|
95
|
|
- mov %ax, undi_data_segment - _prefix
|
96
|
|
- pop %ax
|
97
|
|
- mov %ax, undi_code_size - _prefix
|
98
|
|
- pop %ax
|
99
|
|
- mov %ax, undi_code_segment - _prefix
|
|
97
|
+ movw %es, pxe_entry_segment
|
|
98
|
+ movw %di, pxe_entry_offset
|
|
99
|
+ popw undi_data_size
|
|
100
|
+ popw undi_data_segment
|
|
101
|
+ popw undi_code_size
|
|
102
|
+ popw undi_code_segment
|
100
|
103
|
call print_message
|
101
|
|
- pop %di
|
102
|
|
- pop %es /* Exit with %es:%di containing structure address */
|
|
104
|
+ popw %di
|
|
105
|
+ popw %es /* Exit with %es:%di containing structure address */
|
103
|
106
|
|
104
|
107
|
/*****************************************************************************
|
105
|
108
|
* Print information about located structure
|
|
@@ -107,11 +110,11 @@ pxe_setup_done:
|
107
|
110
|
*/
|
108
|
111
|
print_structure_information:
|
109
|
112
|
call print_segoff /* %es:%di contains address of structure */
|
110
|
|
- les %ds:(pxe_entry_segoff - _prefix), %di
|
|
113
|
+ les pxe_entry_segoff, %di
|
111
|
114
|
call print_segoff
|
112
|
|
- les %ds:(undi_code_segoff - _prefix), %di
|
|
115
|
+ les undi_code_segoff, %di
|
113
|
116
|
call print_segoff
|
114
|
|
- les %ds:(undi_data_segoff - _prefix), %di
|
|
117
|
+ les undi_data_segoff, %di
|
115
|
118
|
call print_segoff
|
116
|
119
|
|
117
|
120
|
/*****************************************************************************
|
|
@@ -119,17 +122,17 @@ print_structure_information:
|
119
|
122
|
*****************************************************************************
|
120
|
123
|
*/
|
121
|
124
|
#ifdef PXELOADER_KEEP_ALL
|
122
|
|
- xor %ax, %ax /* Force zero flag to show success */
|
|
125
|
+ xorw %ax, %ax /* Force zero flag to show success */
|
123
|
126
|
jmp do_not_free_base_mem /* Skip the unloading */
|
124
|
127
|
#endif /* PXELOADER_KEEP_ALL */
|
125
|
128
|
|
126
|
129
|
unload_pxe:
|
127
|
|
- mov $PXENV_UNLOAD_STACK, %bx
|
|
130
|
+ movw $PXENV_UNLOAD_STACK, %bx
|
128
|
131
|
call pxe_call
|
129
|
|
- mov $PXENV_STOP_UNDI, %bx
|
|
132
|
+ movw $PXENV_STOP_UNDI, %bx
|
130
|
133
|
call pxe_call
|
131
|
134
|
pushfw /* Ignore PXENV_UNDI_CLEANUP errors */
|
132
|
|
- mov $PXENV_UNDI_CLEANUP, %bx
|
|
135
|
+ movw $PXENV_UNDI_CLEANUP, %bx
|
133
|
136
|
call pxe_call
|
134
|
137
|
popfw
|
135
|
138
|
/* On exit, zero flag is set iff all calls were successful */
|
|
@@ -141,45 +144,45 @@ unload_pxe:
|
141
|
144
|
free_base_mem:
|
142
|
145
|
jnz do_not_free_base_mem /* Using zero flag from unload_pxe */
|
143
|
146
|
|
144
|
|
- mov undi_code_segment - _prefix, %bx
|
145
|
|
- mov undi_data_segment - _prefix, %cx
|
146
|
|
- mov undi_code_size - _prefix, %ax
|
147
|
|
- cmp %bx, %cx
|
|
147
|
+ movw undi_code_segment, %bx
|
|
148
|
+ movw undi_data_segment, %cx
|
|
149
|
+ movw undi_code_size, %ax
|
|
150
|
+ cmpw %bx, %cx
|
148
|
151
|
jb 1f
|
149
|
|
- mov %cx, %bx
|
150
|
|
- mov undi_data_size - _prefix, %ax
|
151
|
|
-1: add $0x0f, %ax /* Round up to next segment */
|
152
|
|
- shr $4, %ax
|
153
|
|
- add %bx, %ax /* Highest segment address into %ax */
|
154
|
|
- add $(1024 / 16 - 1), %ax /* Round up to next kb */
|
155
|
|
- shr $6, %ax /* New free basemem size in %ax */
|
156
|
|
- mov %fs:(0x13), %bx /* Old free base memory in %bx */
|
157
|
|
- mov %ax, %fs:(0x13) /* Store new free base memory size */
|
|
152
|
+ movw %cx, %bx
|
|
153
|
+ movw undi_data_size, %ax
|
|
154
|
+1: addw $0x0f, %ax /* Round up to next segment */
|
|
155
|
+ shrw $4, %ax
|
|
156
|
+ addw %bx, %ax /* Highest segment address into %ax */
|
|
157
|
+ addw $(1024 / 16 - 1), %ax /* Round up to next kb */
|
|
158
|
+ shrw $6, %ax /* New free basemem size in %ax */
|
|
159
|
+ movw %fs:(0x13), %bx /* Old free base memory in %bx */
|
|
160
|
+ movw %ax, %fs:(0x13) /* Store new free base memory size */
|
158
|
161
|
|
159
|
162
|
/* Note that zero_mem_loop will also zero out our stack, so make
|
160
|
163
|
* sure the stack is empty at this point.
|
161
|
164
|
*/
|
162
|
|
- mov %ax, %dx
|
163
|
|
- sub %bx, %dx /* numberof kb to zero in %dx */
|
164
|
|
- shl $6, %bx /* Segment address into %bx */
|
|
165
|
+ movw %ax, %dx
|
|
166
|
+ subw %bx, %dx /* numberof kb to zero in %dx */
|
|
167
|
+ shlw $6, %bx /* Segment address into %bx */
|
165
|
168
|
zero_mem_loop:
|
166
|
|
- mov %bx, %es /* kB boundary into %es:00 */
|
167
|
|
- xor %ax, %ax
|
168
|
|
- xor %di, %di
|
169
|
|
- mov $0x400, %cx
|
|
169
|
+ movw %bx, %es /* kB boundary into %es:00 */
|
|
170
|
+ xorw %ax, %ax
|
|
171
|
+ xorw %di, %di
|
|
172
|
+ movw $0x400, %cx
|
170
|
173
|
rep stosb /* fill kB with zeroes */
|
171
|
|
- add $(1024 / 16), %bx
|
172
|
|
- dec %dx
|
|
174
|
+ addw $(1024 / 16), %bx
|
|
175
|
+ decw %dx
|
173
|
176
|
jnz zero_mem_loop
|
174
|
177
|
/* Will exit here with zero flag set, so no need to set it explicitly
|
175
|
178
|
* in order to indicate success.
|
176
|
179
|
*/
|
177
|
180
|
|
178
|
181
|
do_not_free_base_mem:
|
179
|
|
- pushf /* Save success (zero) flag status */
|
180
|
|
- mov %fs:(0x13), %ax /* Free base memory in %ax */
|
|
182
|
+ pushfw /* Save success (zero) flag status */
|
|
183
|
+ movw %fs:(0x13), %ax /* Free base memory in %ax */
|
181
|
184
|
call print_hex_word /* Print free base memory */
|
182
|
|
- popf /* Restore success (zero) flag */
|
|
185
|
+ popfw /* Restore success (zero) flag */
|
183
|
186
|
|
184
|
187
|
/*****************************************************************************
|
185
|
188
|
* Exit point
|
|
@@ -188,92 +191,16 @@ do_not_free_base_mem:
|
188
|
191
|
*****************************************************************************
|
189
|
192
|
*/
|
190
|
193
|
finished:
|
191
|
|
- movw $10f-_prefix, %si
|
|
194
|
+ movw $10f, %si
|
192
|
195
|
jz 1f
|
193
|
196
|
finished_with_error:
|
194
|
|
- movw $20f-_prefix, %si
|
|
197
|
+ movw $20f, %si
|
195
|
198
|
1:
|
196
|
199
|
call print_message
|
197
|
|
- jmp 99f
|
|
200
|
+ jmp run_etherboot
|
198
|
201
|
10: .asciz " ok\n"
|
199
|
202
|
20: .asciz " err\n"
|
200
|
203
|
|
201
|
|
-
|
202
|
|
- /* We place a stack here. It doesn't get used until after all
|
203
|
|
- * the above code is finished, so we can happily write all
|
204
|
|
- * over it. Putting the stack here ensures that it doesn't
|
205
|
|
- * accidentally go over the 512 byte threshold, which would
|
206
|
|
- * cause problems when returning via start32's prefix
|
207
|
|
- * relocation mechanism.
|
208
|
|
- */
|
209
|
|
-_estack:
|
210
|
|
-99:
|
211
|
|
-
|
212
|
|
-/*****************************************************************************
|
213
|
|
- * Run Etherboot main code
|
214
|
|
- *****************************************************************************
|
215
|
|
- */
|
216
|
|
-run_etherboot:
|
217
|
|
- /* Very temporarily switch stacks to one internal to the
|
218
|
|
- * prefix. Do this because the stack provided by the PXE ROM
|
219
|
|
- * could be absolutely anywhere, including in an area of
|
220
|
|
- * memory that the call to prelocate will vapourise...
|
221
|
|
- */
|
222
|
|
- pushw %ss /* PXE stack pointer to ES:DI */
|
223
|
|
- popw %es
|
224
|
|
- movw %sp, %di
|
225
|
|
- pushw %ds /* Set up stack in "safe" area */
|
226
|
|
- popw %ss
|
227
|
|
- movw $_estack-_prefix, %sp
|
228
|
|
- pushw %es /* Record PXE stack pointer */
|
229
|
|
- pushw %di
|
230
|
|
- /* Relocate payload and stack to claimed base memory */
|
231
|
|
- pushw $4 /* Preserve old PXE stack pointer */
|
232
|
|
- call prelocate
|
233
|
|
- popw %ax /* Remove parameter */
|
234
|
|
- pushl $4 /* Preserve old PXE stack pointer */
|
235
|
|
- pushw $0 /* Indicate prefix exit mechanism */
|
236
|
|
- jmp _start /* Run Etherboot */
|
237
|
|
-
|
238
|
|
- .section ".text16", "ax", @progbits
|
239
|
|
-prefix_exit:
|
240
|
|
- pushw %cs /* Set %ds, %bp for access to text */
|
241
|
|
- popw %ds
|
242
|
|
- call 1f
|
243
|
|
-1: popw %bp
|
244
|
|
- popw %di /* Old PXE stack to %es:di */
|
245
|
|
- popw %es
|
246
|
|
- cmpw $PXE_STACK_MAGIC, %es:0(%di) /* See if PXE stack intact */
|
247
|
|
- jne exit_via_int18
|
248
|
|
-exit_via_pxe: /* Stack OK, return to PXE */
|
249
|
|
- push %es /* Restore PXE stack pointer */
|
250
|
|
- pop %ss
|
251
|
|
- mov %di, %sp
|
252
|
|
- pop %ax /* Discard PXE_STACK_MAGIC marker */
|
253
|
|
- leaw (10f-1b)(%bp), %si
|
254
|
|
- call print_exit_message
|
255
|
|
- pop %ds /* Restore PXE's DS */
|
256
|
|
- popa /* Restore PXE's other registers */
|
257
|
|
- movw $0, %ax /* Return PXENV_STATUS_SUCCESS */
|
258
|
|
- lret /* Return control to PXE ROM */
|
259
|
|
-10: .asciz "EB->PXE\r\n"
|
260
|
|
-exit_via_int18: /* Stack damaged, do int 18 */
|
261
|
|
- leaw (10f-1b)(%bp), %si
|
262
|
|
- call print_exit_message
|
263
|
|
- int $0x18
|
264
|
|
-10: .asciz "EB->BIOS\r\n"
|
265
|
|
-print_exit_message:
|
266
|
|
- movw $0x0007, %bx /* page 0, attribute 7 (normal) */
|
267
|
|
- movb $0x0e, %ah /* write char, tty mode */
|
268
|
|
-1: lodsb
|
269
|
|
- testb %al, %al
|
270
|
|
- je 2f
|
271
|
|
- int $0x10
|
272
|
|
- jmp 1b
|
273
|
|
-2: ret
|
274
|
|
-prefix_exit_end:
|
275
|
|
- .previous
|
276
|
|
-
|
277
|
204
|
/*****************************************************************************
|
278
|
205
|
* Subroutine: print character in %al (with LF -> LF,CR translation)
|
279
|
206
|
*****************************************************************************
|
|
@@ -305,17 +232,17 @@ print_message:
|
305
|
232
|
*****************************************************************************
|
306
|
233
|
*/
|
307
|
234
|
print_hex_word:
|
308
|
|
- mov $4, %cx
|
|
235
|
+ movw $4, %cx
|
309
|
236
|
1:
|
310
|
|
- push %ax
|
311
|
|
- shr $12, %ax
|
|
237
|
+ pushw %ax
|
|
238
|
+ shrw $12, %ax
|
312
|
239
|
/* Courtesy of Norbert Juffa <norbert.juffa@amd.com> */
|
313
|
|
- cmp $10, %al
|
314
|
|
- sbb $0x69, %al
|
|
240
|
+ cmpb $10, %al
|
|
241
|
+ sbbb $0x69, %al
|
315
|
242
|
das
|
316
|
243
|
call print_character
|
317
|
|
- pop %ax
|
318
|
|
- shl $4, %ax
|
|
244
|
+ popw %ax
|
|
245
|
+ shlw $4, %ax
|
319
|
246
|
loop 1b
|
320
|
247
|
ret
|
321
|
248
|
|
|
@@ -324,15 +251,15 @@ print_hex_word:
|
324
|
251
|
*****************************************************************************
|
325
|
252
|
*/
|
326
|
253
|
print_segoff:
|
327
|
|
- push %di
|
328
|
|
- push %es
|
329
|
|
- pop %ax
|
|
254
|
+ pushw %di
|
|
255
|
+ pushw %es
|
|
256
|
+ popw %ax
|
330
|
257
|
call print_hex_word
|
331
|
258
|
movb $0x3a,%al /* ':' */
|
332
|
259
|
call print_character
|
333
|
|
- pop %ax
|
|
260
|
+ popw %ax
|
334
|
261
|
call print_hex_word
|
335
|
|
- mov $0x20, %al /* ' ' */
|
|
262
|
+ movb $0x20, %al /* ' ' */
|
336
|
263
|
call print_character
|
337
|
264
|
ret
|
338
|
265
|
|
|
@@ -346,24 +273,24 @@ print_segoff:
|
346
|
273
|
*/
|
347
|
274
|
pxe_call:
|
348
|
275
|
/* Set up registers for PXENV+ API. %bx already set up */
|
349
|
|
- push %ds
|
350
|
|
- pop %es
|
351
|
|
- mov $pxe_parameter_structure - _prefix, %di
|
|
276
|
+ pushw %ds
|
|
277
|
+ popw %es
|
|
278
|
+ movw $pxe_parameter_structure, %di
|
352
|
279
|
/* Set up stack for !PXE API */
|
353
|
280
|
pushw %cs
|
354
|
281
|
pushw %di
|
355
|
282
|
pushw %bx
|
356
|
283
|
/* Make the API call */
|
357
|
|
- lcall *(pxe_entry_segoff - _prefix)
|
|
284
|
+ lcall *pxe_entry_segoff
|
358
|
285
|
/* Reset the stack */
|
359
|
|
- add $6, %sp
|
360
|
|
- mov pxe_parameter_structure - _prefix, %ax
|
361
|
|
- push %ax
|
|
286
|
+ addw $6, %sp
|
|
287
|
+ movw pxe_parameter_structure, %ax
|
|
288
|
+ pushw %ax
|
362
|
289
|
call print_hex_word
|
363
|
|
- mov $0x20, %ax /* ' ' */
|
|
290
|
+ movw $0x20, %ax /* ' ' */
|
364
|
291
|
call print_character
|
365
|
|
- pop %bx
|
366
|
|
- or %bx, pxe_overall_status - _prefix
|
|
292
|
+ popw %bx
|
|
293
|
+ orw %bx, pxe_overall_status
|
367
|
294
|
ret
|
368
|
295
|
|
369
|
296
|
/*****************************************************************************
|
|
@@ -389,7 +316,73 @@ pxe_parameter_structure:
|
389
|
316
|
.word 0
|
390
|
317
|
.word 0,0,0,0,0
|
391
|
318
|
|
392
|
|
-end_of_pxeloader:
|
|
319
|
+/*****************************************************************************
|
|
320
|
+ * Run Etherboot main code
|
|
321
|
+ *****************************************************************************
|
|
322
|
+ */
|
|
323
|
+run_etherboot:
|
|
324
|
+ /* Install Etherboot */
|
|
325
|
+ call install
|
|
326
|
+
|
|
327
|
+ /* Jump to .text16 segment with %ds pointing to .data16*/
|
|
328
|
+ movw %bx, %ds
|
|
329
|
+ pushw %ax
|
|
330
|
+ pushw $1f
|
|
331
|
+ lret
|
|
332
|
+ .section ".text16", "ax", @progbits
|
|
333
|
+1:
|
|
334
|
+ /* Original PXE stack pointer to es:di. We must hold it in
|
|
335
|
+ * registers, because our current stack may be vapourised by
|
|
336
|
+ * the time main() returns. (main() will still be able to
|
|
337
|
+ * return, because prot_call() transfers the return address to
|
|
338
|
+ * the internal stack and back again).
|
|
339
|
+ */
|
|
340
|
+ popw %di
|
|
341
|
+ popw %es
|
|
342
|
+
|
|
343
|
+ /* Run main program */
|
|
344
|
+ pushl $main
|
|
345
|
+ pushw %cs
|
|
346
|
+ call prot_call
|
|
347
|
+ popl %eax /* discard */
|
|
348
|
+
|
|
349
|
+ /* If original PXE stack is intact, return via PXE, else via INT 18 */
|
|
350
|
+ cmpw $PXE_STACK_MAGIC, %es:0(%di)
|
|
351
|
+ jne exit_via_int18
|
|
352
|
+exit_via_pxe: /* Stack OK, return to PXE */
|
|
353
|
+ movw $exit_via_pxe_message, %si
|
|
354
|
+ call print_exit_message
|
|
355
|
+ pushw %es /* Restore original PXE stack */
|
|
356
|
+ popw %ss
|
|
357
|
+ movw %di, %sp
|
|
358
|
+ popw %ax /* discard PXE_STACK_MAGIC */
|
|
359
|
+ popw %ax /* discard %cs */
|
|
360
|
+ popw %ax /* discard %ss */
|
|
361
|
+ popw %ds
|
|
362
|
+ popw %es
|
|
363
|
+ popw %fs
|
|
364
|
+ popw %gs
|
|
365
|
+ popal
|
|
366
|
+ popfl
|
|
367
|
+ xorw %ax, %ax /* Return PXENV_STATUS_SUCCESS */
|
|
368
|
+ lret
|
|
369
|
+exit_via_int18: /* Stack damaged, do int 18 */
|
|
370
|
+ movw $exit_via_int18_message, %si
|
|
371
|
+ call print_exit_message
|
|
372
|
+ int $0x18
|
|
373
|
+
|
|
374
|
+print_exit_message:
|
|
375
|
+ movw $0x0007, %bx /* page 0, attribute 7 (normal) */
|
|
376
|
+ movb $0x0e, %ah /* write char, tty mode */
|
|
377
|
+1: lodsb
|
|
378
|
+ testb %al, %al
|
|
379
|
+ je 2f
|
|
380
|
+ int $0x10
|
|
381
|
+ jmp 1b
|
|
382
|
+2: ret
|
393
|
383
|
|
394
|
|
- .balign 16, 0
|
395
|
|
-payload:
|
|
384
|
+ .section ".data16", "aw", @progbits
|
|
385
|
+exit_via_pxe_message:
|
|
386
|
+ .asciz "EB->PXE\r\n"
|
|
387
|
+exit_via_int18_message:
|
|
388
|
+ .asciz "EB->BIOS\r\n"
|