From 82e9f02aef1ea1a6588234ee58e3625e3561005f Mon Sep 17 00:00:00 2001 From: Aleksa Vuckovic Date: Thu, 8 Sep 2022 14:37:47 +0200 Subject: higher half in x86_64 kernel is now located at -2GB heap blocks are aligned on block size paging will allocate new page tables on heap --- kernel/src/boot/boot.S | 158 +++++++++++++------------------------------ kernel/src/boot/boot64.S | 25 ++++--- kernel/src/boot/multiboot2.c | 3 +- 3 files changed, 64 insertions(+), 122 deletions(-) (limited to 'kernel/src/boot') diff --git a/kernel/src/boot/boot.S b/kernel/src/boot/boot.S index a96be00..704acbf 100644 --- a/kernel/src/boot/boot.S +++ b/kernel/src/boot/boot.S @@ -1,99 +1,60 @@ .code32 .extern begin_long_mode -.set KERNEL_VMA, 0xc0000000 +.section .boot32.text, "a" -.section .boot.text, "a" .global _start _start: cli - mov $stack_top - KERNEL_VMA, %esp + mov $stack_top, %esp pushl $0 pushl %eax pushl $0 pushl %ebx - call check_multiboot - call check_cpuid - call check_long_mode - call setup_page_tables call enable_paging - addl $KERNEL_VMA, %esp - mov $4f, %ecx - jmp *%ecx - -check_multiboot: - cmp $0x36d76289, %eax - jne no_multiboot - - ret - -check_cpuid: - pushfl - pop %eax - mov %eax, %ecx - xor $1<<21, %eax - push %eax - popfl - pushfl - pop %eax - push %ecx - popfl - cmp %eax, %ecx - je no_cpuid - - ret - -check_long_mode: - mov $0x80000000, %eax - cpuid - cmp $0x80000001, %eax - jb no_long_mode - - mov $0x80000001, %eax - cpuid - test $1<<29, %edx - jz no_long_mode - - ret + lgdt gdtp + ljmp $0x08, $begin_long_mode setup_page_tables: - mov $pt_lvl3 - KERNEL_VMA, %eax - or $0x3, %eax - mov %eax, pt_lvl4 - KERNEL_VMA - - // 0x00000000 - 0x00200000 : 0x00000000 - 0x00200000 - mov $pt_lvl2 - KERNEL_VMA, %eax +// first 2mb + mov $pt_lvl3, %eax or $0x3, %eax - mov %eax, pt_lvl3 - KERNEL_VMA + mov %eax, pt_lvl4 - // 0xc0000000 - 0xc0200000 : 0xc0000000 - 0xc0200000 - mov $pt_lvl2_hh - KERNEL_VMA, %eax + mov $pt_lvl2, %eax or $0x3, %eax - mov %eax, pt_lvl3 + 24 - KERNEL_VMA + mov %eax, pt_lvl3 -// first 2mb xor %ecx, %ecx 1: movl $0x00200000, %eax mul %ecx or $0b10000011, %eax - movl $pt_lvl2 - KERNEL_VMA, %edx + movl $pt_lvl2, %edx leal (%edx, %ecx, 8), %edx movl %eax, (%edx) inc %ecx cmp $1, %ecx jne 1b -// first 2mb in higher_half +// first 2mb in hh + mov $pt_lvl3_hh, %eax + or $0x3, %eax + mov %eax, pt_lvl4 + 4096 - 8 + + mov $pt_lvl2_hh, %eax + or $0x3, %eax + mov %eax, pt_lvl3_hh + 4096 - 16 + xor %ecx, %ecx 2: movl $0x00200000, %eax mul %ecx or $0b10000011, %eax - movl $pt_lvl2_hh - KERNEL_VMA, %edx + movl $pt_lvl2_hh, %edx leal (%edx, %ecx, 8), %edx movl %eax, (%edx) inc %ecx @@ -115,7 +76,7 @@ enable_paging: wrmsr // pt_lvl4 - mov $pt_lvl4 - KERNEL_VMA, %eax + mov $pt_lvl4, %eax mov %eax, %cr3 // enable paging (+ protected mode if not already enabled) @@ -125,70 +86,43 @@ enable_paging: ret -no_multiboot: - hlt -no_cpuid: - hlt +.section .boot32.rodata -no_long_mode: - hlt - -.section .text -4: - lgdt gdtp - ljmp $0x08, $begin_long_mode +gdt: +gdt_null = . - gdt + .quad 0 +gdt_code = . - gdt + .long 0xFFFF + .byte 0 + .byte 0x9A + .byte 0xAF + .byte 0 +gdt_data = . - gdt + .long 0xFFFF + .byte 0 + .byte 0xA2 + .byte 0xAF + .byte 0 +gdtp: + .word . - gdt - 1 + .quad gdt -.section .bss +.section .boot32.bss .align 4096 -// stack -stack_bottom: - .skip 4096*16 -stack_top: - - -// page tables pt_lvl4: .skip 4096 pt_lvl3: .skip 4096 +pt_lvl3_hh: + .skip 4096 pt_lvl2: .skip 4096 pt_lvl2_hh: .skip 4096 - -// Access bits -.section .rodata -.set PRESENT, 1 << 7 -.set NOT_SYS, 1 << 4 -.set EXEC, 1 << 3 -.set DC, 1 << 2 -.set RW, 1 << 1 -.set ACCESSED, 1 << 0 - -// Flags bits -.set GRAN_4K, 1 << 7 -.set SZ_32, 1 << 6 -.set LONG_MODE, 1 << 5 - -gdt: -gdt_null = . - gdt - .quad 0 -gdt_code = . - gdt - .long 0xFFFF // Limit & Base (low, bits 0-15) - .byte 0 // Base (mid, bits 16-23) - .byte PRESENT | NOT_SYS | EXEC | RW // Access - .byte GRAN_4K | LONG_MODE | 0xF // Flags & Limit (high, bits 16-19) - .byte 0 // Base (high, bits 24-31) -gdt_data = . - gdt - .long 0xFFFF - .byte 0 - .byte PRESENT | NOT_SYS | RW - .byte GRAN_4K | SZ_32 | 0xF - .byte 0 -gdtp: - .word . - gdt - 1 - .quad gdt +stack_bottom: + .skip 4096*4 +stack_top: diff --git a/kernel/src/boot/boot64.S b/kernel/src/boot/boot64.S index cc79c36..e95f55b 100644 --- a/kernel/src/boot/boot64.S +++ b/kernel/src/boot/boot64.S @@ -1,16 +1,25 @@ -.section .text .code64 +.set KERNEL_VMA, 0xffffffff80000000 + +.section .boot64.text, "a" + .global begin_long_mode begin_long_mode: - // reload segment registers - mov $0x10, %ax - mov %ax, %ds - mov %ax, %es - mov %ax, %ss - mov %ax, %fs - mov %ax, %gs +// xchgw %bx, %bx +// mov $0x10, %ax +// mov %ax, %ds +// mov %ax, %es +// mov %ax, %ss +// mov %ax, %fs +// mov %ax, %gs + add $KERNEL_VMA, %rsp + movabs $jump_main, %rax + jmp *%rax + +.section .text +jump_main: popq %rdi popq %rsi call kernel_main diff --git a/kernel/src/boot/multiboot2.c b/kernel/src/boot/multiboot2.c index 1bb9aac..12f3c38 100644 --- a/kernel/src/boot/multiboot2.c +++ b/kernel/src/boot/multiboot2.c @@ -8,8 +8,7 @@ #include #include #include - -#define KERNEL_VMA 0xc0000000 +#include /* https://www.gnu.org/software/grub/manual/multiboot2/html_node/Boot-information-format.html */ -- cgit v1.2.3