|
@@ -3,8 +3,6 @@
|
3
|
3
|
#define PXENV_STOP_UNDI 0x0015
|
4
|
4
|
#define PXENV_UNLOAD_STACK 0x0070
|
5
|
5
|
|
6
|
|
-#define PXE_STACK_MAGIC 0x57ac /* 'STac' */
|
7
|
|
-
|
8
|
6
|
.text
|
9
|
7
|
.arch i386
|
10
|
8
|
.org 0
|
|
@@ -17,31 +15,22 @@
|
17
|
15
|
*****************************************************************************
|
18
|
16
|
*/
|
19
|
17
|
.section ".prefix"
|
|
18
|
+ /* Set up our non-stack segment registers */
|
20
|
19
|
jmp $0x7c0, $1f
|
21
|
|
-1: /* 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 */
|
|
20
|
+1: movw %cs, %ax
|
|
21
|
+ movw %ax, %ds
|
|
22
|
+ movw $0x40, %ax /* BIOS data segment access */
|
|
23
|
+ movw %ax, %fs
|
|
24
|
+ /* Record PXENV+ and !PXE nominal addresses */
|
|
25
|
+ movw %es, %ax /* PXENV+ address */
|
|
26
|
+ movw %ax, pxenv_segment
|
|
27
|
+ movw %bx, pxenv_offset
|
|
28
|
+ popl %eax /* Discard return address */
|
|
29
|
+ popl ppxe_segoff /* !PXE address */
|
31
|
30
|
/* Set up stack just below 0x7c00 */
|
32
|
|
- pushw %ss
|
33
|
|
- popw %gs
|
34
|
|
- movw %sp, %bp /* %gs:%bp points to old PXE stack */
|
35
|
31
|
xorw %ax, %ax
|
36
|
32
|
movw %ax, %ss
|
37
|
33
|
movw $0x7c00, %sp
|
38
|
|
- pushw %gs /* Save old PXE stack pointer */
|
39
|
|
- pushw %bp
|
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
|
34
|
/* Clear direction flag, for the sake of sanity */
|
46
|
35
|
cld
|
47
|
36
|
/* Print welcome message */
|
|
@@ -57,21 +46,19 @@
|
57
|
46
|
*/
|
58
|
47
|
detect_pxenv:
|
59
|
48
|
/* Signature check */
|
60
|
|
- cmpl $0x4e455850, %es:(%bx) /* 'PXEN' signature */
|
|
49
|
+ les pxenv_segoff, %di
|
|
50
|
+ cmpl $0x4e455850, %es:(%di) /* 'PXEN' signature */
|
61
|
51
|
jne 99f
|
62
|
|
- cmpw $0x2b56, %es:4(%bx) /* 'V+' signature */
|
|
52
|
+ cmpw $0x2b56, %es:4(%di) /* 'V+' signature */
|
63
|
53
|
jne 99f
|
64
|
|
- /* Record structure address, entry point, and UNDI segments */
|
65
|
|
- pushw %es
|
66
|
|
- popw pxenv_segment
|
67
|
|
- movw %bx, pxenv_offset
|
68
|
|
- pushl %es:0x0a(%bx) /* Entry point */
|
|
54
|
+ /* Record entry point and UNDI segments */
|
|
55
|
+ pushl %es:0x0a(%di) /* Entry point */
|
69
|
56
|
popl entry_segoff
|
70
|
|
- pushw %es:0x24(%bx) /* UNDI code segment */
|
71
|
|
- pushw %es:0x26(%bx) /* UNDI code size */
|
|
57
|
+ pushw %es:0x24(%di) /* UNDI code segment */
|
|
58
|
+ pushw %es:0x26(%di) /* UNDI code size */
|
72
|
59
|
popl undi_code_segoff
|
73
|
|
- pushw %es:0x20(%bx) /* UNDI data segment */
|
74
|
|
- pushw %es:0x22(%bx) /* UNDI data size */
|
|
60
|
+ pushw %es:0x20(%di) /* UNDI data segment */
|
|
61
|
+ pushw %es:0x22(%di) /* UNDI data size */
|
75
|
62
|
popl undi_data_segoff
|
76
|
63
|
/* Print "PXENV+ at <address>" */
|
77
|
64
|
movw $10f, %si
|
|
@@ -91,7 +78,7 @@ detect_pxenv:
|
91
|
78
|
*/
|
92
|
79
|
detect_ppxe:
|
93
|
80
|
/* Signature check */
|
94
|
|
- les %gs:54(%bp), %di /* !PXE structure */
|
|
81
|
+ les ppxe_segoff, %di
|
95
|
82
|
cmpl $0x45585021, %es:(%di) /* '!PXE' signature */
|
96
|
83
|
jne 99f
|
97
|
84
|
/* Record structure address, entry point, and UNDI segments */
|
|
@@ -700,65 +687,19 @@ run_etherboot:
|
700
|
687
|
rep movsb
|
701
|
688
|
#endif
|
702
|
689
|
|
703
|
|
- /* Jump to .text16 segment with %ds pointing to .data16*/
|
|
690
|
+ /* Jump to .text16 segment with %ds pointing to .data16 */
|
704
|
691
|
movw %bx, %ds
|
705
|
692
|
pushw %ax
|
706
|
693
|
pushw $1f
|
707
|
694
|
lret
|
708
|
695
|
.section ".text16", "ax", @progbits
|
709
|
696
|
1:
|
710
|
|
- /* Original PXE stack pointer to es:di. We must hold it in
|
711
|
|
- * registers, because our current stack may be vapourised by
|
712
|
|
- * the time main() returns. (main() will still be able to
|
713
|
|
- * return, because prot_call() transfers the return address to
|
714
|
|
- * the internal stack and back again).
|
715
|
|
- */
|
716
|
|
- popw %di
|
717
|
|
- popw %es
|
718
|
|
-
|
719
|
697
|
/* Run main program */
|
720
|
698
|
pushl $main
|
721
|
699
|
pushw %cs
|
722
|
700
|
call prot_call
|
723
|
701
|
popl %eax /* discard */
|
724
|
702
|
|
725
|
|
- /* If original PXE stack is intact, return via PXE, else via INT 18 */
|
726
|
|
- cmpw $PXE_STACK_MAGIC, %es:0(%di)
|
727
|
|
- jne exit_via_int18
|
728
|
|
-exit_via_pxe: /* Stack OK, return to PXE */
|
729
|
|
- movw $exit_via_pxe_message, %si
|
730
|
|
- call print_exit_message
|
731
|
|
- pushw %es /* Restore original PXE stack */
|
732
|
|
- popw %ss
|
733
|
|
- movw %di, %sp
|
734
|
|
- popw %ax /* discard PXE_STACK_MAGIC */
|
735
|
|
- popw %ax /* discard %cs */
|
736
|
|
- popw %ax /* discard %ss */
|
737
|
|
- popw %ds
|
738
|
|
- popw %es
|
739
|
|
- popw %fs
|
740
|
|
- popw %gs
|
741
|
|
- popal
|
742
|
|
- popfl
|
743
|
|
- xorw %ax, %ax /* Return PXENV_STATUS_SUCCESS */
|
744
|
|
- lret
|
745
|
|
-exit_via_int18: /* Stack damaged, do int 18 */
|
746
|
|
- movw $exit_via_int18_message, %si
|
747
|
|
- call print_exit_message
|
|
703
|
+ /* Boot next device */
|
748
|
704
|
int $0x18
|
749
|
|
-
|
750
|
|
-print_exit_message:
|
751
|
|
- movw $0x0007, %bx /* page 0, attribute 7 (normal) */
|
752
|
|
- movb $0x0e, %ah /* write char, tty mode */
|
753
|
|
-1: lodsb
|
754
|
|
- testb %al, %al
|
755
|
|
- je 2f
|
756
|
|
- int $0x10
|
757
|
|
- jmp 1b
|
758
|
|
-2: ret
|
759
|
|
-
|
760
|
|
- .section ".data16", "aw", @progbits
|
761
|
|
-exit_via_pxe_message:
|
762
|
|
- .asciz "EB->PXE\r\n"
|
763
|
|
-exit_via_int18_message:
|
764
|
|
- .asciz "EB->BIOS\r\n"
|
|
705
|
+ .previous
|