diff --git a/kernel/boot/boot.S b/kernel/boot/boot.S index 9359c8e..5559b3f 100644 --- a/kernel/boot/boot.S +++ b/kernel/boot/boot.S @@ -4,18 +4,38 @@ .set MAGIC, 0x1BADB002 /* 'magic number' lets bootloader find the header */ .set CHECKSUM, -(MAGIC + FLAGS) /* checksum of above, to prove we are multiboot */ -.section .multiboot +.section .multiboot, "a" .align 4 .long MAGIC .long FLAGS .long CHECKSUM -.section .bss -.align 4096 -boot_page_directory: - .skip 4096 -boot_page_table1: - .skip 4096 +.section .text +.global _start +_start: + cli + + mov $(page_directory - 0xC0000000), %ecx + + mov %cr4, %edx + or $0x00000010, %edx + mov %edx, %cr4 + + mov %ecx, %cr3 + + mov %cr0, %edx + or $0x80000000, %edx + mov %edx, %cr0 + + lea higher, %ecx + jmp *%ecx +higher: + mov $stack_top, %esp + push %ebx + push %eax + call kmain +loop: + jmp loop .section .bss .align 16 @@ -23,13 +43,11 @@ stack_bottom: .skip 16384 # 16 KiB stack_top: -.section .text -.global _start -_start: - cli - mov $stack_top, %esp - push %ebx - push %eax - call kmain -loop: - jmp loop +.section .data, "a" +.align 4096 +.global page_directory +page_directory: + .long 0x00000083 + .skip 3068 + .long 0x00000083 + .skip 1020 \ No newline at end of file diff --git a/kernel/kmain.c b/kernel/kmain.c index 3555342..5cf5f3d 100644 --- a/kernel/kmain.c +++ b/kernel/kmain.c @@ -18,6 +18,9 @@ extern void enable_interrupts(); void* page = NULL; +extern char __kernel_start; +extern char __kernel_end; + void kmain(uint32_t magic, multiboot_info* mbi) { extern print_stream_t vga_print_stream; extern print_stream_t* kout; @@ -49,16 +52,19 @@ void kmain(uint32_t magic, multiboot_info* mbi) { return; } - init_mm((void*)mbi->mmap_addr, mbi->mmap_length); + init_pmm((void*)mbi->mmap_addr, mbi->mmap_length); uint32_t mem_size = total_free_memory(); kprintf("Total available memory: %d MB\n", mem_size / 1024 / 1024); + + kprintf("__kernel_start: 0x%x\n", &__kernel_start); + kprintf("__kernel_end: 0x%x\n", &__kernel_end); + extern uint32_t page_directory[1024]; + kprintf("page directory: 0x%x\n", &page_directory); + uint32_t size = (&__kernel_end - &__kernel_start) / 1024; + kprintf("kernel size: %dKB\n", size); - init_paging(); - enable_paging(); - kprintf("Paging enabled\n"); - - // enable_interrupts(); - // kprintf("Interrupts enabled\n"); + init_page_tables(); + kprintf("Page tables reloaded"); while(1); } diff --git a/kernel/linker.ld b/kernel/linker.ld index b3bef26..d1565a2 100644 --- a/kernel/linker.ld +++ b/kernel/linker.ld @@ -1,30 +1,35 @@ ENTRY(_start) +KERNEL_VMA = 0xC0000000; +KERNEL_LMA = 0x00200000; + SECTIONS { - . = 0xC0100000; + . = KERNEL_VMA + KERNEL_LMA; __kernel_start = .; + .text : AT(ADDR(.text) - KERNEL_VMA) + { + *(.multiboot) + *(.text*) + } - .text BLOCK(4K) : ALIGN(4K) - { - *(.multiboot) - *(.text) - } + .rodata : AT(ADDR(.rodata) - KERNEL_VMA) + { + *(.rodata*) + } - .rodata BLOCK(4K) : ALIGN(4K) - { - *(.rodata) - } + .data : AT(ADDR(.data) - KERNEL_VMA) + { + *(.data*) + } - .data BLOCK(4K) : ALIGN(4K) - { - *(.data) - } + .bss : AT(ADDR(.bss) - KERNEL_VMA) + { + __bss_start = .; + *(.bss*) + *(COMMON) + __bss_end = .; + } - .bss BLOCK(4K) : ALIGN(4K) - { - *(COMMON) - *(.bss) - } - __kernel_end = .; + __kernel_end = .; } \ No newline at end of file diff --git a/kernel/memory/mm.c b/kernel/memory/mm.c index 71ba835..73f2232 100644 --- a/kernel/memory/mm.c +++ b/kernel/memory/mm.c @@ -13,8 +13,6 @@ static uint32_t max_address = 0; static uint32_t total_available_memory = 0; static uint8_t memory_bitmap[BITMAP_SIZE]; -uint32_t* page_directory; - static void mark_free(uint32_t addr) { uint32_t page_index = addr / PAGE_SIZE; uint32_t byte_index = page_index / 8; @@ -56,8 +54,10 @@ static void parse_multiboot_mmap(void* base, uint32_t limit) { continue; } + uint32_t kernel_phys_start = (uint32_t)&__kernel_start - 0xC0000000; + uint32_t kernel_phys_end = (uint32_t)&__kernel_end - 0xC0000000; for (uint32_t addr = usable_start; addr < usable_end; addr += 4096) { - if (addr <= (uint32_t)&__kernel_end && addr >= (uint32_t)&__kernel_start) { + if (addr <= (uint32_t)&kernel_phys_end && addr >= (uint32_t)&kernel_phys_start) { continue; } @@ -78,7 +78,7 @@ static void parse_multiboot_mmap(void* base, uint32_t limit) { } } -void init_mm(void* mmap_base, uint32_t mmap_limit) { +void init_pmm(void* mmap_base, uint32_t mmap_limit) { for (int i = 0; i < BITMAP_SIZE; i++) { memory_bitmap[i] = 0xFF; } @@ -92,7 +92,8 @@ uint32_t total_free_memory() { return total_available_memory; } -void* alloc_page() { +// this returns the virtual address of the physical page allocated +void* alloc_phys_page() { for (uint32_t i = 0; i < BITMAP_SIZE; i++) { uint8_t b = memory_bitmap[i]; if (b == 0xFF) { @@ -103,7 +104,7 @@ void* alloc_page() { if ((b & (1 << bit)) == 0) { uint32_t page_addr = (i * 8 + bit) * PAGE_SIZE; mark_used(page_addr); - return (void*)page_addr; + return (void*)(page_addr + 0xC0000000); } } } @@ -111,22 +112,19 @@ void* alloc_page() { return 0; } -void free_page(void* addr) { +void free_phys_page(void* addr) { mark_free((uint32_t)addr); } -void init_paging() { - page_directory = alloc_page(); +extern uint32_t page_directory[1024]; +extern void flush_tlb(); +extern void disable_pae(); +void init_page_tables() { + uint32_t* kernel_table = alloc_phys_page(); for (int i = 0; i < 1024; i++) { - page_directory[i] = 0x0; + kernel_table[i] = (i * PAGE_SIZE) | 0x3; } - - uint32_t* page_table = alloc_page(); - page_directory[0] = (uint32_t)(page_table) | 0x3; - for (int i = 0; i < 1024; i++) { - page_table[i] = (i * PAGE_SIZE) | 0x3; - } - - extern void load_page_directory(uint32_t* pd); - load_page_directory(page_directory); + uint32_t* phys_table = kernel_table - 0xC000000; + page_directory[768] = (uint32_t)(phys_table) | 0x3; + flush_tlb(); } \ No newline at end of file diff --git a/kernel/memory/mm.h b/kernel/memory/mm.h index 2eb6646..7db3939 100644 --- a/kernel/memory/mm.h +++ b/kernel/memory/mm.h @@ -7,13 +7,12 @@ typedef struct __attribute__((packed)) { uint32_t addr; } mem_page_t; -void init_mm(void* mmap_base, uint32_t mmap_limit); +void init_pmm(void* mmap_base, uint32_t mmap_limit); uint32_t total_free_memory(); void* alloc_page(); void free_page(void* addr); -void init_paging(); -void enable_paging(); +void init_page_tables(); #endif diff --git a/kernel/memory/mm_stubs.S b/kernel/memory/mm_stubs.S index 2016675..9500ca5 100644 --- a/kernel/memory/mm_stubs.S +++ b/kernel/memory/mm_stubs.S @@ -1,21 +1,11 @@ -.code32 -.global load_page_directory -load_page_directory: - push %ebp - mov %esp, %ebp - - mov 8(%ebp), %eax +.code32 +.global flush_tlb +flush_tlb: + mov %cr3, %eax mov %eax, %cr3 - - leave ret - -.global enable_paging -enable_paging: - mov %eax, %cr0 - orl $0x80000000, %eax - mov %cr0, %eax - jmp 1f -1: + +.global disable_pae +disable_pae: ret - \ No newline at end of file + \ No newline at end of file diff --git a/makefile b/makefile index ea41bdf..414375c 100644 --- a/makefile +++ b/makefile @@ -16,7 +16,7 @@ LDFLAGS := -T kernel/linker.ld all: $(OSNAME).iso -$(OSNAME).bin: $(OBJECTS) +$(OSNAME).bin: $(OBJECTS) kernel/linker.ld $(LD) $(LDFLAGS) -o $@ $(OBJECTS) $(OSNAME).iso: $(OSNAME).bin grub.cfg