diff --git a/kernel/include/gdt.h b/kernel/include/gdt.h index 134c813..b13e052 100644 --- a/kernel/include/gdt.h +++ b/kernel/include/gdt.h @@ -110,6 +110,7 @@ struct tss_pointer { uint32_t ssp; } __packed; +void tss_esp0(uint32_t esp0); int gdt_init(void); #endif diff --git a/kernel/linker.ld b/kernel/linker.ld index 481c415..0f3a45e 100644 --- a/kernel/linker.ld +++ b/kernel/linker.ld @@ -2,47 +2,34 @@ OUTPUT_FORMAT("elf32-i386") OUTPUT_ARCH("i386"); ENTRY(_start) -/* Define correct program headers */ -PHDRS { - text PT_LOAD FLAGS((1 << 0) | (1 << 2)); /* Read, Execute */ - rodata PT_LOAD FLAGS((1 << 0)); /* Read */ - data PT_LOAD FLAGS((1 << 0) | (1 << 1)); /* Read, Write */ -} - /* Define sections */ SECTIONS { - /* 1MB is a conventional place for kernels */ - . = 1M; + . = 0x00100000; + kernel_start = .; - __kernel_start = .; - .text BLOCK(4K) : ALIGN(4K) { + .boot ALIGN(4K) : { *(.multiboot) + *(.boot) + } + + . += 0xC0000000; + + .text ALIGN(4K) : AT(ADDR(.text) - 0xC0000000) { *(.text) - } : text + } - .rodata BLOCK(4K) : ALIGN(4K) { + .rodata ALIGN(4K) : AT(ADDR(.rodata) - 0xC0000000) { *(.rodata) - } : rodata + } - .data BLOCK(4K) : ALIGN(4K) { + .data ALIGN(4K) : AT(ADDR(.data) - 0xC0000000) { *(.data) - } : data + } - .bss BLOCK(4K) : ALIGN(4K) { + .bss ALIGN(4K) : AT(ADDR(.bss) - 0xC0000000) { *(COMMON) *(.bss) - } : data - - /* Stack */ - . = ALIGN(16); - __kernel_stack_bottom = .; - . += 16K; - __kernel_stack_top = .; - - __kernel_end = .; - - /DISCARD/ : { - *(.eh_frame) - *(.note*) } + + kernel_end = .; } diff --git a/kernel/src/entry.s b/kernel/src/entry.s index 17323ea..ce133cc 100644 --- a/kernel/src/entry.s +++ b/kernel/src/entry.s @@ -28,13 +28,28 @@ __kernel_stack_bottom: __kernel_stack_top: ; Entry point -section .text +section .boot global _start extern kmain -_start: +_start: + ; Temporary paging + mov edx, (init_pagedir - 0xC0000000) + mov cr3, edx + + mov ecx, cr0 + or ecx, 0x80000000 + mov cr0, ecx + + jmp $ + + jmp higher_half + +section .text +higher_half: mov esp, __kernel_stack_top - push eax - push ebx + add ebx, 0xC0000000 ; Make it a virtual address + push eax ; Magic + push ebx ; Multiboot info call kmain ; Call kernel main ; Hang if kernel returns @@ -42,3 +57,19 @@ _start: .hlt: hlt jmp .hlt +section .data +align 4096 +global init_pagedir +init_pagedir: + dd 0b10000011 ; initial 4mb identity map, unmapped later + + times 768-1 dd 0 ; padding + + ; hh kernel start, map 16 mb + dd (0 << 22) | 0b10000011 ; 0xC0000000 + dd (1 << 22) | 0b10000011 + dd (2 << 22) | 0b10000011 + dd (3 << 22) | 0b10000011 + times 256-4 dd 0 ; padding + + ; dd initial_page_dir | 11b diff --git a/kernel/src/gdt.c b/kernel/src/gdt.c index a3af72e..be24365 100644 --- a/kernel/src/gdt.c +++ b/kernel/src/gdt.c @@ -29,6 +29,8 @@ void tss_reload(void) { gdt[5].access |= 0x02; } +void tss_esp0(uint32_t esp0) { tss.esp0 = esp0; } + int gdt_init(void) { // Null descriptor (0) gdt[0] = GDT_DESC(0, 0, 0, 0); @@ -47,7 +49,7 @@ int gdt_init(void) { // TSS (40) memset(&tss, 0, sizeof(tss)); - gdt[5] = GDT_DESC(sizeof(tss) - 1, (uint32_t)&tss, 0x89, 0x00); + gdt[5] = GDT_DESC(sizeof(tss) - 1, (uint32_t)&tss, 0x89, 0x40); tss.iopb = sizeof(struct tss_pointer); tss.esp0 = __kernel_stack_top; tss.ss0 = GDT_KERNEL_DATA;