claymation / osxp

EFI boot loader for running Windows XP on Intel Macs, from the 2006 Windows On Mac hacker challenge

osxp / asmthunk.s
100644 126 lines (92 sloc) 3.098 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
.text
.global asmThunk
asmThunk:
cli # disable interrupts
 
pusha # save regs and flags
pushf
 
sgdt ProtectedGDTR # save descriptor tables
sidt ProtectedIDTR
 
movl %esp, ProtectedESP # save stack pointer
 
        lgdt RealGDTR # load real mode descriptor table
        lidt RealIDTR # load real mode interrupt vector table
 
        mov $0x18, %ax # use real mode data segment
        mov %ax, %ds
        mov %ax, %es
        mov %ax, %fs
        mov %ax, %gs
 
mov $RealStack, %ebx # %ebx = base of real mode stack
add $4096, %ebx # %ebx = top of real mode stack
        mov %ax, %ss # setup real mode stack segment
mov %ebx, %esp # and stack pointer
 
                                        # jump to set %cs
        ljmp $0x10, $_16bitProtectedMode
 
        .code16 # generate 16-bit friendly opcodes
_16bitProtectedMode:
 
        mov %cr0, %eax # get control register
        and $0xFE, %al # clear protected mode bit
        mov %eax, %cr0 # set control register
 
        ljmp $0, $_16bitRealMode # jump to set %cs
 
_16bitRealMode:
        xor %ax, %ax # clear segments
        mov %ax, %ds
        mov %ax, %es
        mov %ax, %fs
        mov %ax, %gs
        mov %ax, %ss
nop # supposedly interrupts are disabled
# for one instruction after a mov into
# %ss, so this nop lets me enable
# interrupts below.
 
        sti # enable interrupts
 
mov $0x80, %dl # the CD boot loader expects this
 
lcall $0, $0x7C00 # jump to the boot loader. good luck.
 
# in reality, we never make it back
# from the boot loader, so the rest
# of this code is dead, but here for
# completeness.
 
        cli # disable interrupts
 
        xor %ax, %ax # clear segments
        mov %ax, %ds
        mov %ax, %es
        mov %ax, %fs
        mov %ax, %gs
        mov %ax, %ss
 
lgdtl ProtectedGDTR
 
        mov %cr0, %eax # get control register
        or $0x1, %al # set protected mode bit
        mov %eax, %cr0 # set control register
 
                                        # jump to set %cs
        ljmp $0x10, $_32bitProtectedMode
 
        .code32 # generate 32-bit friendly opcodes
_32bitProtectedMode:
 
mov $0x18, %ax # restore segment registers
        mov %ax, %ds
        mov %ax, %es
        mov %ax, %fs
        mov %ax, %gs
 
mov %ax, %ss # restore stack
movl ProtectedESP, %esp
 
lidtl ProtectedIDTR # restore interrupt descriptor table
 
popf # restore flags and
popa # general purpose registers
 
sti # enable interrupts
 
ret
 
 
.global ThunkTest
.code16
ThunkTest:
mov $1, %ax
mov $2, %bx
mov $3, %cx
mov $4, %dx
int $0x10
 
mov $11, %ax
mov $12, %bx
mov $13, %cx
mov $14, %dx
int $0x13
 
mov $11, %ax
mov $12, %bx
mov $13, %cx
mov $14, %dx
int $0x16
 
lret