mirror of
https://github.com/RGBCube/serenity
synced 2025-05-24 03:15:07 +00:00

The kernel and its static data structures are no longer identity-mapped in the bottom 8MB of the address space, but instead move above 3GB. The first 8MB above 3GB are pseudo-identity-mapped to the bottom 8MB of the physical address space. But things don't have to stay this way! Thanks to Jesse who made an earlier attempt at this, it was really easy to get device drivers working once the page tables were in place! :^) Fixes #734.
189 lines
3.8 KiB
ArmAsm
189 lines
3.8 KiB
ArmAsm
.set MULTIBOOT_MAGIC, 0x1badb002
|
|
.set MULTIBOOT_PAGE_ALIGN, 0x1
|
|
.set MULTIBOOT_MEMORY_INFO, 0x2
|
|
.set MULTIBOOT_VIDEO_MODE, 0x4
|
|
.set multiboot_flags, MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO | MULTIBOOT_VIDEO_MODE
|
|
.set multiboot_checksum, -(MULTIBOOT_MAGIC + multiboot_flags)
|
|
|
|
.section .multiboot
|
|
.align 4
|
|
|
|
.long MULTIBOOT_MAGIC
|
|
.long multiboot_flags
|
|
.long multiboot_checksum
|
|
|
|
|
|
/* for MULTIBOOT_MEMORY_INFO */
|
|
.long 0x00000000 /* header_addr */
|
|
.long 0x00000000 /* load_addr */
|
|
.long 0x00000000 /* load_end_addr */
|
|
.long 0x00000000 /* bss_end_addr */
|
|
.long 0x00000000 /* entry_addr */
|
|
|
|
/* for MULTIBOOT_VIDEO_MODE */
|
|
.long 0x00000000 /* mode_type */
|
|
.long 1280 /* width */
|
|
.long 1024 /* height */
|
|
.long 32 /* depth */
|
|
|
|
.section .stack, "aw", @nobits
|
|
stack_bottom:
|
|
.skip 32768
|
|
stack_top:
|
|
|
|
.section .page_tables, "aw", @nobits
|
|
.align 4096
|
|
.global boot_pdpt
|
|
boot_pdpt:
|
|
.skip 4096
|
|
.global boot_pd0
|
|
boot_pd0:
|
|
.skip 4096
|
|
.global boot_pd3
|
|
boot_pd3:
|
|
.skip 4096
|
|
.global boot_pd3_pde1023_pt
|
|
boot_pd3_pde1023_pt:
|
|
.skip 4096
|
|
|
|
.section .text
|
|
|
|
.global start
|
|
.type start, @function
|
|
|
|
.extern init
|
|
.type init, @function
|
|
|
|
.extern multiboot_info_ptr
|
|
.type multiboot_info_ptr, @object
|
|
|
|
/*
|
|
construct the following (32-bit PAE) page table layout:
|
|
|
|
pdpt
|
|
|
|
0: boot_pd0 (0-1GB)
|
|
1: n/a (1-2GB)
|
|
2: n/a (2-3GB)
|
|
3: boot_pd3 (3-4GB)
|
|
|
|
boot_pd0 : 512 pde's
|
|
|
|
0: (0-2MB) (id 2MB page)
|
|
1: (2-4MB) (id 2MB page)
|
|
2: (4-6MB) (id 2MB page)
|
|
3: (6-8MB) (id 2MB page)
|
|
|
|
boot_pd3 : 512 pde's
|
|
|
|
0: boot_pd3_pde0 (3072-3074MB) (pseudo)
|
|
1: boot_pd3_pde1 (3074-3076MB) (pseudo)
|
|
2: boot_pd3_pde2 (3076-3078MB) (pseudo)
|
|
3: boot_pd3_pde3 (3078-3080MB) (pseudo)
|
|
4: boot_pd3_pde1023_pt (4094-4096MB) (for page table mappings)
|
|
*/
|
|
|
|
start:
|
|
cli
|
|
cld
|
|
|
|
/* clear pdpt */
|
|
movl $(boot_pdpt - 0xc0000000), %edi
|
|
movl $1024, %ecx
|
|
xorl %eax, %eax
|
|
rep stosl
|
|
|
|
/* set up pdpt[0] and pdpt[3] */
|
|
movl $(boot_pdpt - 0xc0000000), %edi
|
|
movl $((boot_pd0 - 0xc0000000) + 1), 0(%edi)
|
|
movl $((boot_pd3 - 0xc0000000) + 1), 24(%edi)
|
|
|
|
/* clear pd0 */
|
|
movl $(boot_pd0 - 0xc0000000), %edi
|
|
movl $1024, %ecx
|
|
xorl %eax, %eax
|
|
rep stosl
|
|
|
|
/* identity map bottom 8MB using 2MB pages (only PDE, no PTE) */
|
|
movl $4, %ecx
|
|
xorl %eax, %eax
|
|
movl $(boot_pd0 - 0xc0000000), %edi
|
|
1:
|
|
movl %eax, 0(%edi)
|
|
/* PS(2MB) + R/W + Present */
|
|
orl $0x83, 0(%edi)
|
|
|
|
addl $8, %edi
|
|
addl $(1048576 * 2), %eax
|
|
loop 1b
|
|
|
|
/* clear pd3 */
|
|
movl $(boot_pd3 - 0xc0000000), %edi
|
|
movl $1024, %ecx
|
|
xorl %eax, %eax
|
|
rep stosl
|
|
|
|
/* pseudo-identity map first 8MB above 3GB mark using 2MB pages again */
|
|
movl $4, %ecx
|
|
xorl %eax, %eax
|
|
movl $(boot_pd3 - 0xc0000000), %edi
|
|
1:
|
|
movl %eax, 0(%edi)
|
|
/* PS(2MB) + R/W + Present */
|
|
orl $0x83, 0(%edi)
|
|
|
|
addl $8, %edi
|
|
addl $(1048576 * 2), %eax
|
|
loop 1b
|
|
|
|
/* create an empty page table for the top 2MB at the 4GB mark */
|
|
movl $(boot_pd3 - 0xc0000000), %edi
|
|
movl $(boot_pd3_pde1023_pt - 0xc0000000), 4088(%edi)
|
|
orl $0x3, 4088(%edi)
|
|
movl $0, 4092(%edi)
|
|
|
|
/* point CR3 to PDPT */
|
|
movl $(boot_pdpt - 0xc0000000), %eax
|
|
movl %eax, %cr3
|
|
|
|
/* enable PAE + PSE */
|
|
movl %cr4, %eax
|
|
orl $0x60, %eax
|
|
movl %eax, %cr4
|
|
|
|
/* enable PG */
|
|
movl %cr0, %eax
|
|
orl $0x80000000, %eax
|
|
movl %eax, %cr0
|
|
|
|
/* jmp to an address above the 3GB mark */
|
|
push %cs
|
|
push $1f
|
|
retf
|
|
1:
|
|
|
|
movl %cr3, %eax
|
|
movl %eax, %cr3
|
|
|
|
/* set up initial stack and jump into C++ land */
|
|
mov $stack_top, %esp
|
|
and $-16, %esp
|
|
|
|
addl $0xc0000000, %ebx
|
|
movl %ebx, multiboot_info_ptr
|
|
|
|
call init
|
|
add $4, %esp
|
|
|
|
pushl $exit_message
|
|
call kprintf
|
|
add $4, %esp
|
|
|
|
cli
|
|
|
|
loop:
|
|
hlt
|
|
jmp loop
|
|
|
|
exit_message:
|
|
.asciz "Kernel exited."
|