fixing up paging issues

This commit is contained in:
2026-06-15 18:09:04 -04:00
parent ac4b510221
commit 25da0f6a71
7 changed files with 101 additions and 85 deletions

View File

@@ -4,18 +4,38 @@
.set MAGIC, 0x1BADB002 /* 'magic number' lets bootloader find the header */ .set MAGIC, 0x1BADB002 /* 'magic number' lets bootloader find the header */
.set CHECKSUM, -(MAGIC + FLAGS) /* checksum of above, to prove we are multiboot */ .set CHECKSUM, -(MAGIC + FLAGS) /* checksum of above, to prove we are multiboot */
.section .multiboot .section .multiboot, "a"
.align 4 .align 4
.long MAGIC .long MAGIC
.long FLAGS .long FLAGS
.long CHECKSUM .long CHECKSUM
.section .bss .section .text
.align 4096 .global _start
boot_page_directory: _start:
.skip 4096 cli
boot_page_table1:
.skip 4096 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 .section .bss
.align 16 .align 16
@@ -23,13 +43,11 @@ stack_bottom:
.skip 16384 # 16 KiB .skip 16384 # 16 KiB
stack_top: stack_top:
.section .text .section .data, "a"
.global _start .align 4096
_start: .global page_directory
cli page_directory:
mov $stack_top, %esp .long 0x00000083
push %ebx .skip 3068
push %eax .long 0x00000083
call kmain .skip 1020
loop:
jmp loop

View File

@@ -18,6 +18,9 @@ extern void enable_interrupts();
void* page = NULL; void* page = NULL;
extern char __kernel_start;
extern char __kernel_end;
void kmain(uint32_t magic, multiboot_info* mbi) { void kmain(uint32_t magic, multiboot_info* mbi) {
extern print_stream_t vga_print_stream; extern print_stream_t vga_print_stream;
extern print_stream_t* kout; extern print_stream_t* kout;
@@ -49,16 +52,19 @@ void kmain(uint32_t magic, multiboot_info* mbi) {
return; 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(); uint32_t mem_size = total_free_memory();
kprintf("Total available memory: %d MB\n", mem_size / 1024 / 1024); kprintf("Total available memory: %d MB\n", mem_size / 1024 / 1024);
init_paging(); kprintf("__kernel_start: 0x%x\n", &__kernel_start);
enable_paging(); kprintf("__kernel_end: 0x%x\n", &__kernel_end);
kprintf("Paging enabled\n"); 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);
// enable_interrupts(); init_page_tables();
// kprintf("Interrupts enabled\n"); kprintf("Page tables reloaded");
while(1); while(1);
} }

View File

@@ -1,30 +1,35 @@
ENTRY(_start) ENTRY(_start)
KERNEL_VMA = 0xC0000000;
KERNEL_LMA = 0x00200000;
SECTIONS SECTIONS
{ {
. = 0xC0100000; . = KERNEL_VMA + KERNEL_LMA;
__kernel_start = .; __kernel_start = .;
.text : AT(ADDR(.text) - KERNEL_VMA)
{
*(.multiboot)
*(.text*)
}
.text BLOCK(4K) : ALIGN(4K) .rodata : AT(ADDR(.rodata) - KERNEL_VMA)
{ {
*(.multiboot) *(.rodata*)
*(.text) }
}
.rodata BLOCK(4K) : ALIGN(4K) .data : AT(ADDR(.data) - KERNEL_VMA)
{ {
*(.rodata) *(.data*)
} }
.data BLOCK(4K) : ALIGN(4K) .bss : AT(ADDR(.bss) - KERNEL_VMA)
{ {
*(.data) __bss_start = .;
} *(.bss*)
*(COMMON)
__bss_end = .;
}
.bss BLOCK(4K) : ALIGN(4K) __kernel_end = .;
{
*(COMMON)
*(.bss)
}
__kernel_end = .;
} }

View File

@@ -13,8 +13,6 @@ static uint32_t max_address = 0;
static uint32_t total_available_memory = 0; static uint32_t total_available_memory = 0;
static uint8_t memory_bitmap[BITMAP_SIZE]; static uint8_t memory_bitmap[BITMAP_SIZE];
uint32_t* page_directory;
static void mark_free(uint32_t addr) { static void mark_free(uint32_t addr) {
uint32_t page_index = addr / PAGE_SIZE; uint32_t page_index = addr / PAGE_SIZE;
uint32_t byte_index = page_index / 8; uint32_t byte_index = page_index / 8;
@@ -56,8 +54,10 @@ static void parse_multiboot_mmap(void* base, uint32_t limit) {
continue; 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) { 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; 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++) { for (int i = 0; i < BITMAP_SIZE; i++) {
memory_bitmap[i] = 0xFF; memory_bitmap[i] = 0xFF;
} }
@@ -92,7 +92,8 @@ uint32_t total_free_memory() {
return total_available_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++) { for (uint32_t i = 0; i < BITMAP_SIZE; i++) {
uint8_t b = memory_bitmap[i]; uint8_t b = memory_bitmap[i];
if (b == 0xFF) { if (b == 0xFF) {
@@ -103,7 +104,7 @@ void* alloc_page() {
if ((b & (1 << bit)) == 0) { if ((b & (1 << bit)) == 0) {
uint32_t page_addr = (i * 8 + bit) * PAGE_SIZE; uint32_t page_addr = (i * 8 + bit) * PAGE_SIZE;
mark_used(page_addr); mark_used(page_addr);
return (void*)page_addr; return (void*)(page_addr + 0xC0000000);
} }
} }
} }
@@ -111,22 +112,19 @@ void* alloc_page() {
return 0; return 0;
} }
void free_page(void* addr) { void free_phys_page(void* addr) {
mark_free((uint32_t)addr); mark_free((uint32_t)addr);
} }
void init_paging() { extern uint32_t page_directory[1024];
page_directory = alloc_page(); 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++) { for (int i = 0; i < 1024; i++) {
page_directory[i] = 0x0; kernel_table[i] = (i * PAGE_SIZE) | 0x3;
} }
uint32_t* phys_table = kernel_table - 0xC000000;
uint32_t* page_table = alloc_page(); page_directory[768] = (uint32_t)(phys_table) | 0x3;
page_directory[0] = (uint32_t)(page_table) | 0x3; flush_tlb();
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);
} }

View File

@@ -7,13 +7,12 @@ typedef struct __attribute__((packed)) {
uint32_t addr; uint32_t addr;
} mem_page_t; } 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(); uint32_t total_free_memory();
void* alloc_page(); void* alloc_page();
void free_page(void* addr); void free_page(void* addr);
void init_paging(); void init_page_tables();
void enable_paging();
#endif #endif

View File

@@ -1,21 +1,11 @@
.code32 .code32
.global load_page_directory .global flush_tlb
load_page_directory: flush_tlb:
push %ebp mov %cr3, %eax
mov %esp, %ebp
mov 8(%ebp), %eax
mov %eax, %cr3 mov %eax, %cr3
leave
ret ret
.global enable_paging .global disable_pae
enable_paging: disable_pae:
mov %eax, %cr0
orl $0x80000000, %eax
mov %cr0, %eax
jmp 1f
1:
ret ret

View File

@@ -16,7 +16,7 @@ LDFLAGS := -T kernel/linker.ld
all: $(OSNAME).iso all: $(OSNAME).iso
$(OSNAME).bin: $(OBJECTS) $(OSNAME).bin: $(OBJECTS) kernel/linker.ld
$(LD) $(LDFLAGS) -o $@ $(OBJECTS) $(LD) $(LDFLAGS) -o $@ $(OBJECTS)
$(OSNAME).iso: $(OSNAME).bin grub.cfg $(OSNAME).iso: $(OSNAME).bin grub.cfg