[FREELDR] Introduce a MSVC "linker script" file that centralizes the commands for...
[reactos.git] / boot / freeldr / freeldr / arch / amd64 / entry.S
1
2 #include <asm.inc>
3 #include <arch/pc/x86common.h>
4
5 EXTERN BootMain:PROC
6 // EXTERN cmdline:DWORD
7
8 #ifdef _USE_ML
9 EXTERN __bss_start__:FWORD
10 EXTERN __bss_end__:FWORD
11 #endif
12
13 .code64
14
15 PUBLIC RealEntryPoint
16 RealEntryPoint:
17 /* Setup segment selectors */
18 mov ax, LMODE_DS
19 mov ds, ax
20 mov es, ax
21 mov fs, ax
22 mov gs, ax
23 // mov ss, ax
24
25 //mov word ptr [HEX(b8000)], HEX(0e00) + '1'
26
27 /* Setup long mode stack */
28 mov rsp, qword ptr [stack64]
29
30 /* Continue execution */
31 jmp qword ptr [ContinueAddress]
32
33 ContinueAddress:
34 .quad offset FrldrStartup
35
36 FrldrStartup:
37
38 /* Store BootDrive and BootPartition */
39 mov al, byte ptr [BSS_BootDrive]
40 mov byte ptr [FrldrBootDrive], al
41 xor eax, eax
42 mov al, byte ptr [BSS_BootPartition]
43 mov dword ptr [FrldrBootPartition], eax
44
45 /* Patch long jump with real mode entry point */
46 mov eax, dword ptr [BSS_RealModeEntry]
47 mov dword ptr [AddressOfRealModeEntryPoint], eax
48
49 /* Clean out BSS */
50 xor rax, rax
51 mov rdi, offset __bss_start__
52 mov rcx, offset __bss_end__ + 7
53 sub rcx, rdi
54 shr rcx, 3
55 rep stosq
56
57 /* Pass the command line to BootMain */
58 // mov rcx, offset cmdline
59 xor rcx, rcx
60
61 /* GO! */
62 call BootMain
63
64 /* We should never get here */
65 stop:
66 jmp short stop
67 nop
68 nop
69
70
71 PUBLIC Reboot
72 Reboot:
73 /* Set the function ID */
74 mov bx, FNID_Reboot
75
76 /* Switch to real mode (We don't return) */
77 jmp SwitchToReal
78
79
80 /* Internal function for realmode calls
81 * bx must be set to the ID of the realmode function to call. */
82 PUBLIC CallRealMode
83 CallRealMode:
84 /* Save current stack pointer */
85 mov qword ptr [stack64], rsp
86
87 /* Set continue address and switch to real mode */
88 lea rax, [CallRealMode_return]
89 mov qword ptr [ContinueAddress], rax
90
91 SwitchToReal:
92 /* Set sane segments */
93 mov ax, LMODE_DS
94 mov ds, ax
95 mov es, ax
96 mov fs, ax
97 mov gs, ax
98 //mov ss, ax
99
100 //mov word ptr [HEX(0b8008)], HEX(0e00) + '4'
101
102 /* Save 64-bit stack pointer */
103 mov qword ptr [stack64], rsp
104
105 /* Step 1 - jump to compatibility segment */
106 jmp fword ptr [jumpvector]
107
108 jumpvector:
109 .long offset SwitchToRealCompSegment
110 .word CMODE_CS
111
112 SwitchToRealCompSegment:
113 /* Note: In fact the CPU is in 32 bit mode here. But it will interprete
114 the generated instructions accordingly. rax will become eax */
115
116 /* Step 2 - deactivate long mode, by disabling paging */
117 mov rax, cr0
118 and eax, HEX(7fffffff) //~0x80000000, upper bits cleared
119 mov cr0, rax
120
121 // mov word ptr [HEX(0b800a)], HEX(0e00) + '5'
122
123 /* Step 3 - jump to 16-bit segment to set the limit correctly */
124 .byte HEX(0EA) // 32bit long jmp
125 AddressOfRealModeEntryPoint:
126 .long 0 // receives address of RealModeEntryPoint
127 .word HEX(20)//RMODE_CS
128 nop
129
130 CallRealMode_return:
131 /* restore stack pointer */
132 mov rsp, qword ptr [stack64]
133 ret
134
135 /////////////////////////////////////////
136
137
138 /* 64-bit stack pointer */
139 stack64:
140 .quad STACKADDR
141
142 PUBLIC FrldrBootDrive
143 FrldrBootDrive:
144 .byte 0
145
146 PUBLIC FrldrBootPartition
147 FrldrBootPartition:
148 .long 0
149
150 PUBLIC PxeCallApi
151 PxeCallApi:
152 xor eax, eax
153 ret
154
155 //void __lgdt(void *Source);
156 PUBLIC __lgdt
157 __lgdt:
158 lgdt fword ptr [rcx]
159 ret
160
161 //void __ltr(unsigned short Source);
162 PUBLIC __ltr
163 __ltr:
164 ltr cx
165 ret
166
167
168 END