2 #include <internal/ntoskrnl.h>
3 #include <internal/i386/segment.h>
4 #include <internal/ps.h>
6 #define KERNEL_BASE (0xc0000000)
8 #define MULTIBOOT_HEADER_MAGIC (0x1BADB002)
10 #define MULTIBOOT_HEADER_FLAGS (0x00010003)
12 #define V2P(x) (x - 0xc0000000 + 0x200000)
16 #define AP_MAGIC (0x12481020)
20 .globl _NtProcessStartup
23 .globl _init_stack_top
25 .globl _trap_stack_top
32 * This is called by the realmode loader, with protected mode
33 * enabled, paging disabled and the segment registers pointing
34 * a 4Gb, 32-bit segment starting at zero.
36 * EAX = Multiboot magic or application processor magic
38 * EBX = Points to a structure in lowmem with data from the
46 /* Align 32 bits boundary */
49 /* Multiboot header */
52 .long MULTIBOOT_HEADER_MAGIC
54 .long MULTIBOOT_HEADER_FLAGS
56 .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
58 .long (0x200000 + multiboot_header - KERNEL_BASE)
62 .long (__bss_start__ + 0x200000 - KERNEL_BASE)
64 .long (__bss_end__ + 0x200000 - KERNEL_BASE)
66 .long (0x200000 + _start - KERNEL_BASE)
70 * This must be PIC because we haven't set up paging yet
74 * Gcc expects this at all times
81 * Save the multiboot or application processor magic
95 movl $__bss_end__, %ecx
96 subl $__bss_start__, %ecx
98 movl $__bss_start__, %edi
99 subl $0xc0000000, %edi
105 * Initialize the page directory
107 movl $V2P(startup_pagedirectory), %esi
108 movl $(V2P(lowmem_pagetable) + 0x7), 0x0(%esi)
109 movl $(V2P(kernel_pagetable) + 0x7), 0xC00(%esi)
110 movl $(V2P(kernel_pagetable+4096) + 0x7), 0xC04(%esi)
111 movl $(V2P(kernel_pagetable+2*4096) + 0x7), 0xC08(%esi)
112 movl $(V2P(kernel_pagetable+3*4096) + 0x7), 0xC0c(%esi)
113 movl $(V2P(kernel_pagetable+4*4096) + 0x7), 0xC10(%esi)
114 movl $(V2P(kernel_pagetable+5*4096) + 0x7), 0xC14(%esi)
115 movl $(V2P(kernel_pagetable+6*4096) + 0x7), 0xC18(%esi)
116 movl $(V2P(kernel_pagetable+7*4096) + 0x7), 0xC1c(%esi)
117 movl $(V2P(kernel_pagetable+8*4096) + 0x7), 0xC20(%esi)
118 movl $(V2P(kernel_pagetable+9*4096) + 0x7), 0xC24(%esi)
119 movl $(V2P(kernel_pagetable+10*4096) + 0x7), 0xC28(%esi)
120 movl $(V2P(kernel_pagetable+11*4096) + 0x7), 0xC2c(%esi)
121 movl $(V2P(kernel_pagetable+12*4096) + 0x7), 0xC30(%esi)
122 movl $(V2P(kernel_pagetable+13*4096) + 0x7), 0xC34(%esi)
123 movl $(V2P(kernel_pagetable+14*4096) + 0x7), 0xC38(%esi)
124 movl $(V2P(kernel_pagetable+15*4096) + 0x7), 0xC3c(%esi)
125 movl $(V2P(kernel_pagetable+16*4096) + 0x7), 0xC40(%esi)
126 movl $(V2P(kernel_pagetable+17*4096) + 0x7), 0xC44(%esi)
127 movl $(V2P(kernel_pagetable+18*4096) + 0x7), 0xC48(%esi)
128 movl $(V2P(kernel_pagetable+19*4096) + 0x7), 0xC4c(%esi)
129 movl $(V2P(kernel_pagetable+20*4096) + 0x7), 0xC50(%esi)
130 movl $(V2P(kernel_pagetable+21*4096) + 0x7), 0xC54(%esi)
131 movl $(V2P(kernel_pagetable+22*4096) + 0x7), 0xC58(%esi)
132 movl $(V2P(kernel_pagetable+23*4096) + 0x7), 0xC5c(%esi)
133 movl $(V2P(kernel_pagetable+24*4096) + 0x7), 0xC60(%esi)
134 movl $(V2P(kernel_pagetable+25*4096) + 0x7), 0xC64(%esi)
135 movl $(V2P(kernel_pagetable+26*4096) + 0x7), 0xC68(%esi)
136 movl $(V2P(kernel_pagetable+27*4096) + 0x7), 0xC6c(%esi)
137 movl $(V2P(kernel_pagetable+28*4096) + 0x7), 0xC70(%esi)
138 movl $(V2P(kernel_pagetable+29*4096) + 0x7), 0xC74(%esi)
139 movl $(V2P(kernel_pagetable+30*4096) + 0x7), 0xC78(%esi)
140 movl $(V2P(kernel_pagetable+31*4096) + 0x7), 0xC7c(%esi)
142 movl $(V2P(lowmem_pagetable) + 0x7), 0xD00(%esi)
143 movl $(V2P(startup_pagedirectory) + 0x7), 0xF00(%esi)
145 movl $(V2P(apic_pagetable) + 0x7), 0xFEC(%esi)
147 movl $(V2P(kpcr_pagetable) + 0x7), 0xFF0(%esi)
150 * Initialize the page table that maps low memory
152 movl $V2P(lowmem_pagetable), %esi
156 movl %eax, (%esi, %edi)
163 * Initialize the page table that maps kernel memory
165 movl $V2P(kernel_pagetable), %esi
169 movl %eax, (%esi, %edi)
178 * Initialize the page table that maps the APIC register address space
182 * FIXME: APIC register address space can be non-standard so do the
185 movl $V2P(apic_pagetable), %esi
187 movl $0xFEC0001B, %eax
188 movl %eax, (%esi, %edi)
190 movl $0xFEE0001B, %eax
191 movl %eax, (%esi, %edi)
196 * Initialize the page table that maps the initial KPCR (at FF000000)
198 movl $V2P(kpcr_pagetable), %esi
201 movl %eax, (%esi, %edi)
212 movl $(V2P(startup_pagedirectory)), %eax
216 * Enable paging and set write protect
219 orl $0x80010000, %eax
223 * Do an absolute jump because we now want to execute above 0xc0000000
230 * Load the GDTR and IDTR with new tables located above
234 /* FIXME: Application processors should have their own GDT/IDT */
235 lgdt _KiGdtDescriptor
236 lidt _KiIdtDescriptor
239 * Reload the data segment registers
241 movl $KERNEL_DS, %eax
255 * This is an application processor executing
265 * Call the application processor initialization code
270 pushl $_KiSystemStartup
274 * Catch illegal returns from KiSystemStartup
290 * Load the PCR selector
292 movl $PCR_SELECTOR, %eax
296 * Load the initial kernel stack
298 movl $_init_stack_top, %esp
307 * Call the main kernel initialization
318 * Catch illegal returns from main, try bug checking the system,
319 * if that fails then loop forever.
332 * This needs to be page aligned so put it at the beginning of the bss
336 startup_pagedirectory: