diff options
| author | Aleksa Vuckovic <aleksav013@gmail.com> | 2022-08-08 19:50:11 +0200 |
|---|---|---|
| committer | Aleksa Vuckovic <aleksav013@gmail.com> | 2022-08-08 19:50:11 +0200 |
| commit | 0162997df4ae7769bd4fc055b2c03b473846d1f5 (patch) | |
| tree | f6c40a64cbb15cf3fd102e5e8f15b48030e96f4e /kernel/src | |
| parent | 71396c5cd460890c52e348687e6e7c864e2dfeed (diff) | |
higher half
Diffstat (limited to 'kernel/src')
| -rw-r--r-- | kernel/src/boot/boot.S | 58 | ||||
| -rw-r--r-- | kernel/src/boot/multiboot2.c | 7 | ||||
| -rw-r--r-- | kernel/src/kernel.ld | 19 | ||||
| -rw-r--r-- | kernel/src/mem/paging.c | 19 | ||||
| -rw-r--r-- | kernel/src/mem/paging_asm.S | 6 |
5 files changed, 77 insertions, 32 deletions
diff --git a/kernel/src/boot/boot.S b/kernel/src/boot/boot.S index bf5251b..81584ce 100644 --- a/kernel/src/boot/boot.S +++ b/kernel/src/boot/boot.S @@ -1,12 +1,13 @@ +.code32 .global _start .extern begin_long_mode -.section .text -.code32 +.set KERNEL_VMA, 0xc0000000 +.section .boot.text, "a" _start: cli - mov $stack_top, %esp + mov $stack_top - KERNEL_VMA, %esp pushl $0 pushl %eax pushl $0 @@ -19,9 +20,9 @@ _start: call setup_page_tables call enable_paging - lgdt gdt_pointer - ljmp $0x08, $begin_long_mode - + addl $KERNEL_VMA, %esp + mov $4f, %ecx + jmp *%ecx check_multiboot: cmp $0x36d76289, %eax @@ -59,27 +60,46 @@ check_long_mode: ret setup_page_tables: - mov $pt_lvl3, %eax + mov $pt_lvl3 - KERNEL_VMA, %eax or $0x3, %eax - mov %eax, pt_lvl4 + mov %eax, pt_lvl4 - KERNEL_VMA - // 0x00000000 - 0x00200000 : 0x00000000 - mov $pt_lvl2, %eax + // 0x00000000 - 0x00200000 : 0x00000000 - 0x00200000 + mov $pt_lvl2 - KERNEL_VMA, %eax or $0x3, %eax - mov %eax, pt_lvl3 + mov %eax, pt_lvl3 - KERNEL_VMA - movl $0, %ecx + // 0xc0000000 - 0xc0200000 : 0xc0000000 - 0xc0200000 + mov $pt_lvl2_hh - KERNEL_VMA, %eax + or $0x3, %eax + mov %eax, pt_lvl3 + 24 - KERNEL_VMA + +// first 2mb + xor %ecx, %ecx 1: movl $0x00200000, %eax mul %ecx or $0b10000011, %eax - movl $pt_lvl2, %edx + movl $pt_lvl2 - KERNEL_VMA, %edx leal (%edx, %ecx, 8), %edx movl %eax, (%edx) inc %ecx cmp $1, %ecx jne 1b +// first 2mb in higher_half + xor %ecx, %ecx +2: + movl $0x00200000, %eax + mul %ecx + or $0b10000011, %eax + movl $pt_lvl2_hh - KERNEL_VMA, %edx + leal (%edx, %ecx, 8), %edx + movl %eax, (%edx) + inc %ecx + cmp $1, %ecx + jne 2b + ret enable_paging: @@ -95,7 +115,7 @@ enable_paging: wrmsr // pt_lvl4 - mov $pt_lvl4, %eax + mov $pt_lvl4 - KERNEL_VMA, %eax mov %eax, %cr3 // enable paging (+ protected mode if not already enabled) @@ -114,6 +134,11 @@ no_cpuid: no_long_mode: hlt +.section .text +4: + lgdt gdt_pointer + ljmp $0x08, $begin_long_mode + .section .bss .align 4096 @@ -123,14 +148,17 @@ stack_bottom: .skip 4096*4 stack_top: + // page tables pt_lvl4: .skip 4096 pt_lvl3: .skip 4096 -// map first 4GB pt_lvl2: .skip 4096 +pt_lvl2_hh: + .skip 4096 + // Access bits .section .rodata diff --git a/kernel/src/boot/multiboot2.c b/kernel/src/boot/multiboot2.c index 2badae9..fd8a652 100644 --- a/kernel/src/boot/multiboot2.c +++ b/kernel/src/boot/multiboot2.c @@ -2,6 +2,10 @@ #include <multiboot2.h> #include <graphics.h> +#include <debug.h> + + +#define KERNEL_VMA 0xc0000000 fb_t fb; @@ -18,7 +22,8 @@ void init_fb(mb2_tag_header* multiboot_bootinfo, uint32_t multiboot_magic) static mb2_tag_fb* tag_fb; // skip first 8 bytes (total_size + reserved) - mb2_tag_header* tag_header = multiboot_bootinfo + 1; + mb2_tag_header* tag_header = (mb2_tag_header*)((char*)multiboot_bootinfo + 8 + KERNEL_VMA); + bochs_breakpoint(); while (tag_header->type != MB2_TAG_END) { // process tag_type diff --git a/kernel/src/kernel.ld b/kernel/src/kernel.ld index da5c87c..56b5647 100644 --- a/kernel/src/kernel.ld +++ b/kernel/src/kernel.ld @@ -1,30 +1,36 @@ ENTRY(_start) +KERNEL_PMA = 0x00100000; +KERNEL_VMA = 0xc0000000; + SECTIONS { - . = 1M; + . = KERNEL_PMA; .boot BLOCK(4K) : ALIGN(4K) { KEEP(*(.multiboot_header)) + *(.boot.text) } - .text BLOCK(4K) : ALIGN(4K) + . += KERNEL_VMA; + + .text ALIGN(4K) : AT (ADDR (.text) - KERNEL_VMA) { *(.text) } - .rodata BLOCK(4K) : ALIGN(4K) + .rodata ALIGN(4K) : AT (ADDR (.rodata) - KERNEL_VMA) { *(.rodata) } - .data BLOCK(4K) : ALIGN(4K) + .data ALIGN(4K) : AT (ADDR (.data) - KERNEL_VMA) { *(.data) } - .bss BLOCK(4K) : ALIGN(4K) + .bss ALIGN(4K) : AT (ADDR (.bss) - KERNEL_VMA) { *(COMMON) *(.bss) @@ -32,8 +38,7 @@ SECTIONS /DISCARD/ : { - *(.comment.*) + *(.comment) *(.note.*) - *(.eh_frame) } } diff --git a/kernel/src/mem/paging.c b/kernel/src/mem/paging.c index 3f9e2f5..f0181cd 100644 --- a/kernel/src/mem/paging.c +++ b/kernel/src/mem/paging.c @@ -6,30 +6,31 @@ void load_pt_lvl4(uint64_t*); __attribute__((aligned(4096))) uint64_t page_table_lvl4[512]; __attribute__((aligned(4096))) uint64_t page_table_lvl3[512]; -__attribute__((aligned(4096))) uint64_t page_table_lvl2_kernel[512]; -__attribute__((aligned(4096))) uint64_t page_table_lvl2_fb[512]; +__attribute__((aligned(4096))) uint64_t page_table_lvl2_hh[512]; #define PAGE_SIZE 0x00200000 #define FLAG_PRESENT 0x1 #define FLAG_WRITABLE 0x2 #define FLAG_HUGE 0x80 +#define KERNEL_VMA 0xc0000000 void init_paging(void) { - page_table_lvl4[0] = (uint64_t)page_table_lvl3 + FLAG_PRESENT + FLAG_WRITABLE; - page_table_lvl3[0] = (uint64_t)page_table_lvl2_kernel + FLAG_PRESENT + FLAG_WRITABLE; - page_table_lvl3[3] = (uint64_t)page_table_lvl2_fb + FLAG_PRESENT + FLAG_WRITABLE; + page_table_lvl4[0] = (uint64_t)page_table_lvl3 + FLAG_PRESENT + FLAG_WRITABLE - KERNEL_VMA; + page_table_lvl3[3] = (uint64_t)page_table_lvl2_hh + FLAG_PRESENT + FLAG_WRITABLE - KERNEL_VMA; - // 0x00000000 - 0x00400000 : 0x00000000 - 0x00400000 + // higher half kernel + // 0xc0000000 - 0xc0400000 : 0xc0000000 - 0xc0400000 for (uint64_t i = 0; i < 2; i++) { - page_table_lvl2_kernel[i] = i * PAGE_SIZE + FLAG_PRESENT + FLAG_WRITABLE + FLAG_HUGE; + page_table_lvl2_hh[i] = i * PAGE_SIZE + FLAG_PRESENT + FLAG_WRITABLE + FLAG_HUGE; } // TODO: remove initial mapping for fb and instead page on demand + // identity paged for fb // 0xe0000000 - 0xffffffff : 0xe0000000 - 0xffffffff - for (uint64_t i = 0; i < 512; i++) { - page_table_lvl2_fb[i] = i * PAGE_SIZE + 0xc0000000 + FLAG_PRESENT + FLAG_WRITABLE + FLAG_HUGE; + for (uint64_t i = 2; i < 512; i++) { + page_table_lvl2_hh[i] = i * PAGE_SIZE + 0xc0000000 + FLAG_PRESENT + FLAG_WRITABLE + FLAG_HUGE; } load_pt_lvl4(page_table_lvl4); diff --git a/kernel/src/mem/paging_asm.S b/kernel/src/mem/paging_asm.S index 508930f..c7e11f3 100644 --- a/kernel/src/mem/paging_asm.S +++ b/kernel/src/mem/paging_asm.S @@ -1,11 +1,17 @@ .section .text +.set KERNEL_VMA, 0xc0000000 + .global load_pt_lvl4 load_pt_lvl4: push %rbp mov %rsp, %rbp + push %r12 + mov $KERNEL_VMA, %r12 + sub %r12, %rdi mov %rdi, %cr3 + pop %r12 mov %rbp, %rsp pop %rbp |
