mirror of
https://github.com/RGBCube/serenity
synced 2025-10-26 12:42:38 +00:00
229 lines
4.6 KiB
ArmAsm
229 lines
4.6 KiB
ArmAsm
.set MULTIBOOT_MAGIC, 0x1badb002
|
|
.set MULTIBOOT_PAGE_ALIGN, 0x1
|
|
.set MULTIBOOT_MEMORY_INFO, 0x2
|
|
.set multiboot_flags, MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO
|
|
.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 */
|
|
|
|
.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_pd0_pt0
|
|
boot_pd0_pt0:
|
|
.skip 4096 * 4
|
|
.global boot_pd3_pts
|
|
boot_pd3_pts:
|
|
.skip 4096 * 4
|
|
.global boot_pd3_pt1023
|
|
boot_pd3_pt1023:
|
|
.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: boot_pd0_pt0 (0-2MB) (id 512 4KB pages)
|
|
|
|
boot_pd3 : 512 pde's
|
|
|
|
0: boot_pd3_pts[0] (3072-3074MB) (pseudo 512 4KB pages)
|
|
1: boot_pd3_pts[1] (3074-3076MB) (pseudo 512 4KB pages)
|
|
2: boot_pd3_pts[2] (3076-3078MB) (pseudo 512 4KB pages)
|
|
3: boot_pd3_pts[3] (3078-3080MB) (pseudo 512 4KB pages)
|
|
4: boot_pd3_pt1023 (4094-4096MB) (for page table mappings)
|
|
|
|
the 9 page tables each contain 512 pte's that map individual 4KB pages
|
|
|
|
*/
|
|
|
|
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
|
|
|
|
/* clear pd3 */
|
|
movl $(boot_pd3 - 0xc0000000), %edi
|
|
movl $1024, %ecx
|
|
xorl %eax, %eax
|
|
rep stosl
|
|
|
|
/* clear pd0's pt's */
|
|
movl $(boot_pd0_pt0 - 0xc0000000), %edi
|
|
movl $(1024 * 4), %ecx
|
|
xorl %eax, %eax
|
|
rep stosl
|
|
|
|
/* clear pd3's pt's */
|
|
movl $(boot_pd3_pts - 0xc0000000), %edi
|
|
movl $(1024 * 5), %ecx
|
|
xorl %eax, %eax
|
|
rep stosl
|
|
|
|
/* add boot_pd0_pt0 to boot_pd0 */
|
|
movl $(boot_pd0 - 0xc0000000), %edi
|
|
movl $(boot_pd0_pt0 - 0xc0000000), %eax
|
|
movl %eax, 0(%edi)
|
|
/* R/W + Present */
|
|
orl $0x3, 0(%edi)
|
|
|
|
/* add boot_pd3_pts to boot_pd3 */
|
|
movl $4, %ecx
|
|
movl $(boot_pd3 - 0xc0000000), %edi
|
|
movl $(boot_pd3_pts - 0xc0000000), %eax
|
|
|
|
1:
|
|
movl %eax, 0(%edi)
|
|
/* R/W + Present */
|
|
orl $0x3, 0(%edi)
|
|
addl $8, %edi
|
|
addl $4096, %eax
|
|
loop 1b
|
|
|
|
/* identity map the 0 to 2MB range */
|
|
movl $512, %ecx
|
|
movl $(boot_pd0_pt0 - 0xc0000000), %edi
|
|
xorl %eax, %eax
|
|
|
|
1:
|
|
movl %eax, 0(%edi)
|
|
/* R/W + Present */
|
|
orl $0x3, 0(%edi)
|
|
addl $8, %edi
|
|
addl $4096, %eax
|
|
loop 1b
|
|
|
|
/* pseudo identity map the 3072-3080MB range */
|
|
movl $(512 * 4), %ecx
|
|
movl $(boot_pd3_pts - 0xc0000000), %edi
|
|
xorl %eax, %eax
|
|
|
|
1:
|
|
movl %eax, 0(%edi)
|
|
/* R/W + Present */
|
|
orl $0x3, 0(%edi)
|
|
addl $8, %edi
|
|
addl $4096, %eax
|
|
loop 1b
|
|
|
|
/* create an empty page table for the top 2MB at the 4GB mark */
|
|
movl $(boot_pd3 - 0xc0000000), %edi
|
|
movl $(boot_pd3_pt1023 - 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
|
|
|
|
/* unmap the 0-1MB range, which isn't used after jmp-ing up here */
|
|
movl $256, %ecx
|
|
movl $(boot_pd0_pt0 - 0xc0000000), %edi
|
|
xorl %eax, %eax
|
|
|
|
1:
|
|
movl %eax, 0(%edi)
|
|
addl $8, %edi
|
|
loop 1b
|
|
|
|
/* 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."
|