3 * Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
4 * Copyright (C) 2005 Alex Ionescu <alex@relsoft.net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 /* Page Directory and Tables for non-PAE Systems */
28 extern PAGE_DIRECTORY_X86 startup_pagedirectory
;
29 extern PAGE_DIRECTORY_X86 lowmem_pagetable
;
30 extern PAGE_DIRECTORY_X86 kernel_pagetable
;
31 extern PAGE_DIRECTORY_X86 hyperspace_pagetable
;
32 extern PAGE_DIRECTORY_X86 apic_pagetable
;
33 extern PAGE_DIRECTORY_X86 kpcr_pagetable
;
34 extern PAGE_DIRECTORY_X86 kuser_pagetable
;
35 extern ULONG_PTR KernelBase
;
36 extern ROS_KERNEL_ENTRY_POINT KernelEntryPoint
;
37 /* FUNCTIONS *****************************************************************/
43 * Prepares the system for loading the Kernel.
46 * Magic - Multiboot Magic
57 FrLdrStartup(ULONG Magic
)
61 /* Disable Interrupts */
64 /* Re-initalize EFLAGS */
67 /* Initialize the page directory */
68 FrLdrSetupPageDirectory();
70 /* Initialize Paging, Write-Protection and Load NTOSKRNL */
79 * Configures PAE on a MP System, and sets the PDBR if it's supported, or if
83 * Magic - Multiboot Magic
94 FrLdrSetupPae(ULONG Magic
)
97 ULONG_PTR PageDirectoryBaseAddress
= (ULONG_PTR
)&startup_pagedirectory
;
100 __writecr3(PageDirectoryBaseAddress
);
102 /* Enable Paging and Write Protect*/
103 __writecr0(__readcr0() | X86_CR0_PG
| X86_CR0_WP
);
106 (*KernelEntryPoint
)(Magic
, &LoaderBlock
);
111 * FrLdrSetupPageDirectory
114 * Sets up the ReactOS Startup Page Directory.
123 * We are setting PDEs, but using the equvivalent (for our purpose) PTE structure.
124 * As such, please note that PageFrameNumber == PageEntryNumber.
129 FrLdrSetupPageDirectory(VOID
)
132 PPAGE_DIRECTORY_X86 PageDir
;
133 ULONG KernelPageTableIndex
;
136 /* Get the Kernel Table Index */
137 KernelPageTableIndex
= KernelBase
>> PDE_SHIFT
;
139 /* Get the Startup Page Directory */
140 PageDir
= (PPAGE_DIRECTORY_X86
)&startup_pagedirectory
;
142 /* Set up the Low Memory PDE */
143 PageDir
->Pde
[LowMemPageTableIndex
].Valid
= 1;
144 PageDir
->Pde
[LowMemPageTableIndex
].Write
= 1;
145 PageDir
->Pde
[LowMemPageTableIndex
].PageFrameNumber
= PaPtrToPfn(lowmem_pagetable
);
147 /* Set up the Kernel PDEs */
148 PageDir
->Pde
[KernelPageTableIndex
].Valid
= 1;
149 PageDir
->Pde
[KernelPageTableIndex
].Write
= 1;
150 PageDir
->Pde
[KernelPageTableIndex
].PageFrameNumber
= PaPtrToPfn(kernel_pagetable
);
151 PageDir
->Pde
[KernelPageTableIndex
+ 1].Valid
= 1;
152 PageDir
->Pde
[KernelPageTableIndex
+ 1].Write
= 1;
153 PageDir
->Pde
[KernelPageTableIndex
+ 1].PageFrameNumber
= PaPtrToPfn(kernel_pagetable
+ 4096);
155 /* Set up the Startup PDE */
156 PageDir
->Pde
[StartupPageTableIndex
].Valid
= 1;
157 PageDir
->Pde
[StartupPageTableIndex
].Write
= 1;
158 PageDir
->Pde
[StartupPageTableIndex
].PageFrameNumber
= PaPtrToPfn(startup_pagedirectory
);
160 /* Set up the Hyperspace PDE */
161 PageDir
->Pde
[HyperspacePageTableIndex
].Valid
= 1;
162 PageDir
->Pde
[HyperspacePageTableIndex
].Write
= 1;
163 PageDir
->Pde
[HyperspacePageTableIndex
].PageFrameNumber
= PaPtrToPfn(hyperspace_pagetable
);
165 /* Set up the HAL PDE */
166 PageDir
->Pde
[HalPageTableIndex
].Valid
= 1;
167 PageDir
->Pde
[HalPageTableIndex
].Write
= 1;
168 PageDir
->Pde
[HalPageTableIndex
].PageFrameNumber
= PaPtrToPfn(apic_pagetable
);
170 /* Set up Low Memory PTEs */
171 PageDir
= (PPAGE_DIRECTORY_X86
)&lowmem_pagetable
;
172 for (i
=0; i
<1024; i
++)
174 PageDir
->Pde
[i
].Valid
= 1;
175 PageDir
->Pde
[i
].Write
= 1;
176 PageDir
->Pde
[i
].Owner
= 1;
177 PageDir
->Pde
[i
].PageFrameNumber
= PaToPfn(i
* PAGE_SIZE
);
180 /* Set up Kernel PTEs */
181 PageDir
= (PPAGE_DIRECTORY_X86
)&kernel_pagetable
;
182 for (i
=0; i
<1536; i
++)
184 PageDir
->Pde
[i
].Valid
= 1;
185 PageDir
->Pde
[i
].Write
= 1;
186 PageDir
->Pde
[i
].PageFrameNumber
= PaToPfn(KERNEL_BASE_PHYS
+ i
* PAGE_SIZE
);
189 /* Setup APIC Base */
190 PageDir
= (PPAGE_DIRECTORY_X86
)&apic_pagetable
;
191 PageDir
->Pde
[0].Valid
= 1;
192 PageDir
->Pde
[0].Write
= 1;
193 PageDir
->Pde
[0].CacheDisable
= 1;
194 PageDir
->Pde
[0].WriteThrough
= 1;
195 PageDir
->Pde
[0].PageFrameNumber
= PaToPfn(HAL_BASE
);
196 PageDir
->Pde
[0x200].Valid
= 1;
197 PageDir
->Pde
[0x200].Write
= 1;
198 PageDir
->Pde
[0x200].CacheDisable
= 1;
199 PageDir
->Pde
[0x200].WriteThrough
= 1;
200 PageDir
->Pde
[0x200].PageFrameNumber
= PaToPfn(HAL_BASE
+ KERNEL_BASE_PHYS
);
202 /* Setup KUSER_SHARED_DATA Base */
203 PageDir
->Pde
[0x1F0].Valid
= 1;
204 PageDir
->Pde
[0x1F0].Write
= 1;
205 PageDir
->Pde
[0x1F0].PageFrameNumber
= 2;
208 PageDir
->Pde
[0x1FF].Valid
= 1;
209 PageDir
->Pde
[0x1FF].Write
= 1;
210 PageDir
->Pde
[0x1FF].PageFrameNumber
= 1;
212 /* Zero shared data */
213 RtlZeroMemory((PVOID
)(2 << MM_PAGE_SHIFT
), PAGE_SIZE
);