diff --git a/kernel/init.asm b/kernel/init.asm index 44acdbd..1a8635c 100644 --- a/kernel/init.asm +++ b/kernel/init.asm @@ -34,7 +34,7 @@ _start: mov edx, 0 .fill_table: mov ecx, edx - or ecx, 3 + or ecx, 7 mov [boot_page_tab-0xC0000000+eax*4], ecx add edx, 0x1000 inc eax @@ -43,7 +43,7 @@ _start: mov ecx, boot_page_tab sub ecx, 0xC0000000 - or ecx, 3 + or ecx, 7 mov [boot_page_dir-0xC0000000], ecx mov [boot_page_dir-0xC0000000+768*4], ecx @@ -59,6 +59,11 @@ _start: section .text higher_half: + ; Un-identity-map kernel + mov dword [boot_page_dir], 2 + ; Add KERNEL_VMA to the address of the multiboot info struct + add ebx, 0xC0000000 + ; Load GDT lgdt [gdtp] ; Offset to kernel data descriptor diff --git a/kernel/kernel.c b/kernel/kernel.c index b607b74..995ef8d 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -37,11 +37,13 @@ typedef struct { uint32_t cr3; } task_t; +#define KERNEL_VMA 0xC0000000 + void kernel(multiboot_info_t *info) { if (!CHECK_FLAG(info->flags, 3)) goto halt; // Modules if (!CHECK_FLAG(info->flags, 6)) goto halt; // Memory map if (!CHECK_FLAG(info->flags, 12)) goto halt; // VBE data - ctx.multi_mmap = (multi_mmap_t *)info->memmapaddress; + ctx.multi_mmap = (multi_mmap_t *)(info->memmapaddress + KERNEL_VMA); ctx.multi_mmap_size = info->memmaplength; if (serial_port_init(COM1)) ctx.log_method = LOG_COM1; @@ -60,7 +62,6 @@ void kernel(multiboot_info_t *info) { asm volatile ("lidt %0" :: "m"(idtr)); pic_remap(PIC_1_START, PIC_2_START); - /* asm volatile ("sti" ::); ctx.ticks = 0; @@ -76,11 +77,12 @@ void kernel(multiboot_info_t *info) { gdt[5].granularity |= 0x40; gdt[5].access = 0x89; tss.ss0 = GDT_SEGMENT_SELECTOR(2, RING0); - tss.esp0 = 0; + uint32_t esp0 = 0; + asm volatile ("mov %%esp, %0" : "=r" (esp0)); + tss.esp0 = esp0; tss.cs = GDT_SEGMENT_SELECTOR(3, RING3); tss.ss = tss.ds = tss.es = tss.fs = tss.gs = GDT_SEGMENT_SELECTOR(4, RING3); flush_tss(GDT_SEGMENT_SELECTOR(5, RING3)); - */ #define PAGE_PRESENT (1<<0) #define PAGE_RW (1<<1) @@ -91,10 +93,10 @@ void kernel(multiboot_info_t *info) { #define PAGE_OFFSET(x) ((x) & 0xFFF) uint32_t stack = (uint32_t)mmap_find_first_free_block(); - multi_mod_t *init = (multi_mod_t *)info->moduleaddress; - LOG("Switching to ring 3... EIP: 0x%08X ESP: 0x%08X\n", init->mod_start, stack+0x1000); + multi_mod_t *init = (multi_mod_t *)(info->moduleaddress + KERNEL_VMA); + LOG("Switching to ring 3... EIP: 0x%08X ESP: 0x%08X\n", init->mod_start+KERNEL_VMA, stack+0x1000); - //jmp_user_mode(stack+0x1000, init->mod_start); + jmp_user_mode(stack+0x1000, init->mod_start+KERNEL_VMA); halt: for (;;) {} diff --git a/kernel/mem.c b/kernel/mem.c index 9d8cb5d..f5d61b5 100644 --- a/kernel/mem.c +++ b/kernel/mem.c @@ -13,8 +13,13 @@ void *mmap_block_to_physical(int block) { uint32_t len = (uint32_t)(entry.len); uint32_t addr = (uint32_t)(entry.addr); - if (len > offset) - return (void *)(addr + offset); + if (len > offset) { + uint32_t phys = (addr + offset); + if (phys < 0x00400000) { + return (void *)(phys + 0xC0000000); + } + return (void *)phys; + } } return 0; @@ -67,7 +72,10 @@ uint8_t mmap_init(void) { // Create map struct multiboot_mmap_entry entry = ctx.multi_mmap[index]; //uint32_t addr = (uint32_t)(entry.addr_low | entry.addr_high); - ctx.mmap = (uint32_t *)(uint32_t)(entry.addr & 0xffffffff); + if ((uint32_t)(entry.addr & UINT32_MAX) < 0x00400000) + ctx.mmap = (uint32_t *)((uint32_t)(entry.addr & UINT32_MAX) + 0xC0000000); + else + ctx.mmap = (uint32_t *)(uint32_t)(entry.addr & 0xffffffff); // Zero the map memset(ctx.mmap, 0, ctx.mmap_size); // Reserve the blocks that hold the memory map + 1