From b6d7e5d5c40c8b0183323045e2d4ccd3fe1c1311 Mon Sep 17 00:00:00 2001 From: Sam Tebbs Date: Fri, 19 Apr 2019 20:58:32 +0100 Subject: [PATCH 1/4] Add multiboot setup code --- src/kernel/kmain.zig | 88 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 80 insertions(+), 8 deletions(-) diff --git a/src/kernel/kmain.zig b/src/kernel/kmain.zig index fdeeee1..da37c23 100644 --- a/src/kernel/kmain.zig +++ b/src/kernel/kmain.zig @@ -1,6 +1,6 @@ // // kmain -// Zig version: +// Zig version: // Author: DrDeano // Date: 2019-03-30 // @@ -17,17 +17,89 @@ const MEMINFO = 1 << 1; const MAGIC = 0x1BADB002; const FLAGS = ALIGN | MEMINFO; -export var multiboot align(4) linksection(".multiboot") = MultiBoot { +export var multiboot align(4) linksection(".rodata.boot") = MultiBoot{ .magic = MAGIC, .flags = FLAGS, .checksum = -(MAGIC + FLAGS), }; -export var stack_bytes: [16 * 1024]u8 align(16) linksection(".bss") = undefined; -const stack_bytes_slice = stack_bytes[0..]; +const KERNEL_ADDR_OFFSET = 0xC0000000; +const KERNEL_PAGE_NUMBER = KERNEL_ADDR_OFFSET >> 22; +// The number of pages occupied by the kernel, will need to be increased as we add a heap etc. +const KERNEL_NUM_PAGES = 1; -export nakedcc fn _start() noreturn { - @newStackCall(stack_bytes_slice, kmain); +// The initial page directory used for booting into the higher half. Should be overwritten later +export var boot_page_directory: [1024]u32 align(4096) linksection(".rodata.boot") = init: { + // Temp value + var dir: [1024]u32 = undefined; + + // Page for 0 -> 4 MiB. Gets unmapped later + dir[0] = 0x00000083; + + var i = 0; + var idx = 1; + + // Fill preceding pages with zeroes. May not be unecessary but incurs no runtime cost + while (i < KERNEL_PAGE_NUMBER - 1) { + dir[idx] = 0; + i += 1; + idx += 1; + } + + // Map the kernel's higher half pages increasing by 4 MiB every time + i = 0; + while (i < KERNEL_NUM_PAGES) { + dir[idx] = 0x00000083 | (i << 22); + i += 1; + idx += 1; + } + // Increase max number of branches done by comptime evaluator + @setEvalBranchQuota(1024); + // Fill suceeding pages with zeroes. May not be unecessary but incurs no runtime cost + i = 0; + while (i < 1024 - KERNEL_PAGE_NUMBER - KERNEL_NUM_PAGES) { + dir[idx] = 0; + i += 1; + idx += 1; + } + break :init dir; +}; + +export var kernel_stack: [16 * 1024]u8 align(16) linksection(".bss.stack") = undefined; + +export nakedcc fn _start() align(16) linksection(".text.boot") noreturn { + // Seth the page directory to the boot directory + asm volatile ( + \\.extern boot_page_directory + \\mov $boot_page_directory, %%ecx + \\mov %%ecx, %%cr3 + ); + // Enable 4 MiB pages + asm volatile ( + \\mov %%cr4, %%ecx + \\or $0x00000010, %%ecx + \\mov %%ecx, %%cr4 + ); + // Enable paging + asm volatile ( + \\mov %%cr0, %%ecx + \\or $0x80000000, %%ecx + \\mov %%ecx, %%cr0 + ); + asm volatile ("jmp start_higher_half"); + while (true) {} +} + +export nakedcc fn start_higher_half() noreturn { + // Invalidate the page for the first 4MiB as it's no longer needed + asm volatile ("invlpg (0)"); + // Setup the stack + asm volatile ( + \\.extern KERNEL_STACK_END + \\mov $KERNEL_STACK_END, %%esp + \\mov %%esp, %%ebp + ); + kmain(); while (true) {} } @@ -79,7 +151,7 @@ const terminal = struct { var column = usize(0); var colour = vga_entry_colour(VGA_COLOUR.VGA_COLOUR_LIGHT_GREY, VGA_COLOUR.VGA_COLOUR_BLACK); - const buffer = @intToPtr([*]volatile u16, 0xB8000); + const buffer = @intToPtr([*]volatile u16, 0xC00B8000); fn initialize() void { var y = usize(0); @@ -115,4 +187,4 @@ const terminal = struct { for (data) |c| putChar(c); } -}; \ No newline at end of file +}; From a7f28c50e1c8f13de365359022336c04195ef4c5 Mon Sep 17 00:00:00 2001 From: Sam Tebbs Date: Fri, 19 Apr 2019 21:10:27 +0100 Subject: [PATCH 2/4] Add higher half support in linker script --- link.ld | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/link.ld b/link.ld index 85aca9f..026236d 100644 --- a/link.ld +++ b/link.ld @@ -1,23 +1,45 @@ ENTRY(_start) +KERNEL_ADDR_OFFSET = 0xC0000000; + SECTIONS { . = 1M; + KERNEL_PHYSADDR_START = .; - .text : ALIGN(4K) { - KEEP(*(.multiboot)) + .rodata.boot : { + *(.rodata.boot) + } + + .text.boot : { + *(.text.boot) + } + + . = KERNEL_ADDR_OFFSET; + KERNEL_VADDR_START = .; + + .text ALIGN(4K) : AT (ADDR(.text) - KERNEL_ADDR_OFFSET) { *(.text) } - .rodata : ALIGN(4K) { + .rodata ALIGN(4K) : AT (ADDR(.rodata) - KERNEL_ADDR_OFFSET) { *(.rodata) } - .data : ALIGN(4K) { + .data ALIGN(4K) : AT (ADDR(.data) - KERNEL_ADDR_OFFSET) { *(.data) } - .bss : ALIGN(4K) { + .bss ALIGN(4K) : AT (ADDR(.bss) - KERNEL_ADDR_OFFSET) { *(COMMON) *(.bss) } -} \ No newline at end of file + + .bss.stack ALIGN(4K) : AT (ADDR(.bss.stack) - KERNEL_ADDR_OFFSET) { + *(.bss.stack) + KERNEL_STACK_END = .; + } + + KERNEL_VADDR_END = .; + KERNEL_PHYSADDR_END = . - KERNEL_ADDR_OFFSET; + +} From 80b88c7d037777a5962e38e4248c51331a9313df Mon Sep 17 00:00:00 2001 From: Sam Tebbs Date: Tue, 23 Apr 2019 18:50:58 +0100 Subject: [PATCH 3/4] Move branch quota change to top of boot_page_directory init --- src/kernel/kmain.zig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/kernel/kmain.zig b/src/kernel/kmain.zig index da37c23..5a5b0c6 100644 --- a/src/kernel/kmain.zig +++ b/src/kernel/kmain.zig @@ -30,6 +30,8 @@ const KERNEL_NUM_PAGES = 1; // The initial page directory used for booting into the higher half. Should be overwritten later export var boot_page_directory: [1024]u32 align(4096) linksection(".rodata.boot") = init: { + // Increase max number of branches done by comptime evaluator + @setEvalBranchQuota(1024); // Temp value var dir: [1024]u32 = undefined; From 24249a5f4073051b69e3e5c9e4f14c8d8336776d Mon Sep 17 00:00:00 2001 From: Sam Tebbs Date: Tue, 23 Apr 2019 18:51:44 +0100 Subject: [PATCH 4/4] Move boot_page_directory while increment --- src/kernel/kmain.zig | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/kernel/kmain.zig b/src/kernel/kmain.zig index 5a5b0c6..261e608 100644 --- a/src/kernel/kmain.zig +++ b/src/kernel/kmain.zig @@ -41,28 +41,29 @@ export var boot_page_directory: [1024]u32 align(4096) linksection(".rodata.boot" var i = 0; var idx = 1; - // Fill preceding pages with zeroes. May not be unecessary but incurs no runtime cost - while (i < KERNEL_PAGE_NUMBER - 1) { - dir[idx] = 0; + // Fill preceding pages with zeroes. May be unecessary but incurs no runtime cost + while (i < KERNEL_PAGE_NUMBER - 1) : ({ i += 1; idx += 1; + }) { + dir[idx] = 0; } // Map the kernel's higher half pages increasing by 4 MiB every time i = 0; - while (i < KERNEL_NUM_PAGES) { + while (i < KERNEL_NUM_PAGES) : ({ + i += 1; + idx += 1; + }) { dir[idx] = 0x00000083 | (i << 22); - i += 1; - idx += 1; } - // Increase max number of branches done by comptime evaluator - @setEvalBranchQuota(1024); - // Fill suceeding pages with zeroes. May not be unecessary but incurs no runtime cost + // Fill suceeding pages with zeroes. May be unecessary but incurs no runtime cost i = 0; - while (i < 1024 - KERNEL_PAGE_NUMBER - KERNEL_NUM_PAGES) { - dir[idx] = 0; + while (i < 1024 - KERNEL_PAGE_NUMBER - KERNEL_NUM_PAGES) : ({ i += 1; idx += 1; + }) { + dir[idx] = 0; } break :init dir; };