diff --git a/bootloader/Cargo.toml b/bootloader/Cargo.toml index aedf457e..a67f7c9e 100644 --- a/bootloader/Cargo.toml +++ b/bootloader/Cargo.toml @@ -10,3 +10,4 @@ edition = "2021" [dependencies] bios = {workspace = true} +mem = {workspace = true} diff --git a/bootloader/src/lib.rs b/bootloader/src/lib.rs index 00ee45ba..ec5ea753 100644 --- a/bootloader/src/lib.rs +++ b/bootloader/src/lib.rs @@ -29,6 +29,13 @@ use bios::{ memory::MemoryEntry, video::{VesaMode, VesaModeId}, }; +use mem::phys::PhysMemoryMap; + +/// Amount of regions contained in the inital phys memory map. +pub const MEMORY_REGIONS: usize = 64; + +/// Kernel fn ptr +pub type KernelEntryFn = fn(u64) -> !; /// # Max Memory Map Entries /// This is the max number of entries that can fit in the Stage-to-Stage info block. @@ -59,3 +66,10 @@ pub struct Stage32toStage64 { pub memory_map: [MemoryEntry; MAX_MEMORY_MAP_ENTRIES], pub video_mode: (VesaModeId, VesaMode), } + +/// # `Stage64` to `Kernel` Info Block +#[repr(C)] +pub struct KernelBootHeader { + pub phys_mem_map: &'static PhysMemoryMap, + pub video_mode: (VesaModeId, VesaMode), +} diff --git a/bootloader/stage-64bit/src/main.rs b/bootloader/stage-64bit/src/main.rs index 765f4d02..618968d3 100644 --- a/bootloader/stage-64bit/src/main.rs +++ b/bootloader/stage-64bit/src/main.rs @@ -27,8 +27,8 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #![no_std] #![feature(sync_unsafe_cell)] -use bootloader::Stage32toStage64; -use core::cell::SyncUnsafeCell; +use bootloader::{KernelBootHeader, KernelEntryFn, MEMORY_REGIONS, Stage32toStage64}; +use core::{arch::asm, cell::SyncUnsafeCell}; use elf::{ Elf, tables::{ArchKind, SegmentKind}, @@ -48,8 +48,9 @@ mod panic; make_debug! { "Serial": Option = Serial::probe_first(SerialBaud::Baud115200); } - -static MEMORY_MAP: SyncUnsafeCell> = SyncUnsafeCell::new(PhysMemoryMap::new()); +static MEMORY_MAP: SyncUnsafeCell> = + SyncUnsafeCell::new(PhysMemoryMap::new()); +static KERNEL_INFO: SyncUnsafeCell> = SyncUnsafeCell::new(None); #[unsafe(no_mangle)] #[unsafe(link_section = ".start")] @@ -106,6 +107,39 @@ fn main(stage_to_stage: &Stage32toStage64) { let kernel_exe_slice = virt_info.exe_slice(); logln!("{}", (&kernel_exe_slice[..1024]).hexdump()); + + unsafe { + let mm = &mut *MEMORY_MAP.get(); + let s2k = &mut *KERNEL_INFO.get(); + + s2k.replace(KernelBootHeader { + phys_mem_map: mm, + video_mode: stage_to_stage.video_mode, + }); + + jmp_to_kernel( + virt_info.exe_start_virt as *const KernelEntryFn, + virt_info.stack_start_virt, + s2k.as_ref().unwrap(), + ); + } +} + +unsafe fn jmp_to_kernel( + fn_ptr: *const KernelEntryFn, + kernel_stack_ptr: u64, + s2k: &'static KernelBootHeader, +) -> ! { + unsafe { + asm!( + "mov rsp, {stack}", + "jmp {kern:r}", + in("rdi") &raw const s2k, + kern = in(reg) fn_ptr, + stack = in(reg) kernel_stack_ptr + ); + } + unreachable!("Kernel should never return back to the bootloader!"); } fn build_memory_map(s2s: &Stage32toStage64, kernel_exe_len: usize) -> paging::PageTableConfig { diff --git a/kernel/src/main.rs b/kernel/src/main.rs index 3b69dbba..4ca5acab 100644 --- a/kernel/src/main.rs +++ b/kernel/src/main.rs @@ -28,7 +28,7 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA mod panic; -use bootloader::Stage32toStage64; +use bootloader::KernelBootHeader; use lldebug::{debug_ready, logln, make_debug}; use serial::{Serial, baud::SerialBaud}; @@ -39,11 +39,12 @@ make_debug! { #[unsafe(no_mangle)] #[unsafe(link_section = ".start")] extern "C" fn _start(stage_to_stage: u64) { - main(unsafe { &(*(stage_to_stage as *const Stage32toStage64)) }); + main(unsafe { &(*(stage_to_stage as *const KernelBootHeader)) }); panic!("Main should not return"); } #[debug_ready] -fn main(_stage_to_stage: &Stage32toStage64) { +fn main(_stage_to_stage: &KernelBootHeader) { logln!("Kernel!"); + loop {} }