From b2b1fc59b7a4d0fc18a2ca13ec0d6bdbb8e74332 Mon Sep 17 00:00:00 2001 From: rami Date: Thu, 4 Jul 2024 22:03:10 -0400 Subject: [PATCH] higher half kernel --- bochsrc | 2 +- kernel/init.asm | 43 +++++++++++++++++++++++++++++++++++++---- kernel/kernel.c | 25 +----------------------- kernel/kernel.ld | 50 ++++++++++++++++-------------------------------- 4 files changed, 58 insertions(+), 62 deletions(-) diff --git a/bochsrc b/bochsrc index f5de00b..387e109 100644 --- a/bochsrc +++ b/bochsrc @@ -2,4 +2,4 @@ ata0-slave: type=cdrom, path=./build/Hazel.iso, status=inserted magic_break: enabled=1 boot: cdrom -display_library: sdl2 +display_library: x diff --git a/kernel/init.asm b/kernel/init.asm index 1d7a3d0..44acdbd 100644 --- a/kernel/init.asm +++ b/kernel/init.asm @@ -4,7 +4,7 @@ %define VID 1<<2 %define FLAGS (ALIGN | MMAP | VID) -section .multiboot +section .multiboot.data dd MAGIC dd FLAGS dd -(MAGIC + FLAGS) @@ -19,7 +19,7 @@ dd 80 ; width dd 25 ; height dd 0 ; depth -section .text +section .multiboot.text global _start _start: cli @@ -28,9 +28,40 @@ _start: cmp eax, 0x2BADB002 jne halt + ; Setup table + ; Identity page 0-4 mib + mov eax, 0 + mov edx, 0 +.fill_table: + mov ecx, edx + or ecx, 3 + mov [boot_page_tab-0xC0000000+eax*4], ecx + add edx, 0x1000 + inc eax + cmp eax, 1024 + jne .fill_table + + mov ecx, boot_page_tab + sub ecx, 0xC0000000 + or ecx, 3 + mov [boot_page_dir-0xC0000000], ecx + mov [boot_page_dir-0xC0000000+768*4], ecx + + ; Enable paging + mov eax, boot_page_dir + sub eax, 0xC0000000 + mov cr3, eax + mov eax, cr0 + or eax, (1<<31) + mov cr0, eax + + jmp higher_half + +section .text +higher_half: ; Load GDT lgdt [gdtp] - ; Offset to kernel data descriptor + ; Offset to kernel data descriptor mov ax, 0x10 mov es, ax mov ds, ax @@ -52,7 +83,6 @@ halt: global pit_isr pit_isr: - cli extern pit_handler call pit_handler iret @@ -187,6 +217,11 @@ gdtp: dw gdt_end - gdt - 1 dd gdt +align 0x1000 +boot_page_dir: times 1024 dd 0 +align 0x1000 +boot_page_tab: times 1024 dd 0 + section .bss align 16 stack_top: diff --git a/kernel/kernel.c b/kernel/kernel.c index 63b51dc..b607b74 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -37,9 +37,6 @@ typedef struct { uint32_t cr3; } task_t; -__attribute__((aligned(4096))) uint32_t page_dir[1024]; -__attribute__((aligned(4096))) uint32_t page_tab[1024]; - 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 @@ -93,31 +90,11 @@ void kernel(multiboot_info_t *info) { #define PAGE_TAB_INDEX(x) (((x) >> 12) & 0x3FF) #define PAGE_OFFSET(x) ((x) & 0xFFF) - for (int i = 0; i < 1024; i++) { - page_tab[i] = (i * 0x1000) | PAGE_PRESENT | PAGE_RW | PAGE_USER; - } - - for (int i = 0; i < 1024; i++) { - page_dir[i] = ((uint32_t)page_tab) | PAGE_PRESENT | PAGE_RW | PAGE_USER; - } - - //enable_paging(page_dir); - asm volatile("mov %0, %%cr3" :: "r" (page_dir)); - - asm volatile( - "mov %%cr0, %%eax;" - "or $0x80000000, %%eax;" - "mov %%eax, %%cr0;" - : - : - : "%eax" - ); - 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); - jmp_user_mode(stack+0x1000, init->mod_start); + //jmp_user_mode(stack+0x1000, init->mod_start); halt: for (;;) {} diff --git a/kernel/kernel.ld b/kernel/kernel.ld index 525e0d3..c1c48d8 100644 --- a/kernel/kernel.ld +++ b/kernel/kernel.ld @@ -1,52 +1,36 @@ -/* The bootloader will look at this image and start execution at the symbol - designated as the entry point. */ ENTRY(_start) -/* Tell where the various sections of the object files will be put in the final - kernel image. */ SECTIONS { - /* It used to be universally recommended to use 1M as a start offset, - as it was effectively guaranteed to be available under BIOS systems. - However, UEFI has made things more complicated, and experimental data - strongly suggests that 2M is a safer place to load. In 2016, a new - feature was introduced to the multiboot2 spec to inform bootloaders - that a kernel can be loaded anywhere within a range of addresses and - will be able to relocate itself to run from such a loader-selected - address, in order to give the loader freedom in selecting a span of - memory which is verified to be available by the firmware, in order to - work around this issue. This does not use that feature, so 2M was - chosen as a safer option than the traditional 1M. */ . = 1M; - - /* First put the multiboot header, as it is required to be put very early - in the image or the bootloader won't recognize the file format. - Next we'll put the .text section. */ - .text BLOCK(4K) : ALIGN(4K) - { - *(.multiboot) - *(.text) + _kernel_start = .; + .multiboot.data : { + *(.multiboot.data) + } + .multiboot.text : { + *(.multiboot.text) } - /* Read-only data. */ - .rodata BLOCK(4K) : ALIGN(4K) + . += 0xC0000000; + + .text ALIGN (4K) : AT (ADDR (.text) - 0xC0000000) + { + *(.text) + } + .rodata ALIGN (4K) : AT (ADDR (.rodata) - 0xC0000000) { *(.rodata) } - - /* Read-write data (initialized) */ - .data BLOCK(4K) : ALIGN(4K) + .data ALIGN (4K) : AT (ADDR (.data) - 0xC0000000) { *(.data) } - - /* Read-write data (uninitialized) and stack */ - .bss BLOCK(4K) : ALIGN(4K) + .bss ALIGN (4K) : AT (ADDR (.bss) - 0xC0000000) { *(COMMON) *(.bss) + *(.bootstrap_stack) } - /* The compiler may produce other sections, by default it will put them in - a segment with the same name. Simply add stuff here as needed. */ + _kernel_end = .; }