Skip to content

Commit

Permalink
refactor(arch): extract enter_kernel
Browse files Browse the repository at this point in the history
Signed-off-by: Martin Kröning <[email protected]>
  • Loading branch information
mkroening committed Apr 12, 2024
1 parent f6e8c80 commit 60e0688
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 104 deletions.
44 changes: 20 additions & 24 deletions src/arch/aarch64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,6 @@ pub unsafe fn boot_kernel(kernel_info: LoadedKernel) -> ! {
);
}

let current_stack_address = load_info.kernel_image_addr_range.start - KERNEL_STACK_SIZE as u64;

take_static::take_static! {
static RAW_BOOT_INFO: Option<RawBootInfo> = None;
}
Expand Down Expand Up @@ -228,38 +226,36 @@ pub unsafe fn boot_kernel(kernel_info: LoadedKernel) -> ! {
};

info!("boot_info = {boot_info:#?}");
let stack = boot_info.load_info.kernel_image_addr_range.start as usize - KERNEL_STACK_SIZE;
let stack = sptr::from_exposed_addr_mut(stack);
let entry = sptr::from_exposed_addr(entry_point.try_into().unwrap());
let boot_info_ptr = raw_boot_info.insert(RawBootInfo::from(boot_info));
info!("boot_info at {boot_info_ptr:p}");

// Jump to the kernel entry point and provide the Multiboot information to it.
info!(
"Jumping to HermitCore Application Entry Point at {:#x}",
entry_point
);
unsafe { enter_kernel(stack, entry, boot_info_ptr) }
}

unsafe fn enter_kernel(stack: *mut u8, entry: *const (), raw_boot_info: &'static RawBootInfo) -> ! {
// Check expected signature of entry function
let entry: Entry = {
let entry: unsafe extern "C" fn(raw_boot_info: &'static RawBootInfo, cpu_id: u32) -> ! =
unsafe { core::mem::transmute(entry) };
entry
};

/* Memory barrier */
info!("Entering kernel at {entry:p}, stack at {stack:p}, raw_boot_info at {raw_boot_info:p}");

// Memory barrier
unsafe {
asm!("dsb sy", options(nostack));
}

#[allow(dead_code)]
const ENTRY_TYPE_CHECK: Entry = {
unsafe extern "C" fn entry_signature(
_raw_boot_info: &'static RawBootInfo,
_cpu_id: u32,
) -> ! {
unimplemented!()
}
entry_signature
};

unsafe {
asm!(
"mov sp, {stack_address}",
"mov sp, {stack}",
"br {entry}",
stack_address = in(reg) current_stack_address,
entry = in(reg) entry_point,
in("x0") boot_info_ptr,
stack = in(reg) stack,
entry = in(reg) entry,
in("x0") raw_boot_info,
in("x1") 0,
options(noreturn)
)
Expand Down
25 changes: 17 additions & 8 deletions src/arch/riscv64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,6 @@ pub unsafe fn boot_kernel(kernel_info: LoadedKernel) -> ! {

let fdt = start::get_fdt();

info!("hart_id = {}", start::get_hart_id());

take_static::take_static! {
static RAW_BOOT_INFO: Option<RawBootInfo> = None;
}
Expand Down Expand Up @@ -135,26 +133,37 @@ pub unsafe fn boot_kernel(kernel_info: LoadedKernel) -> ! {
};

info!("boot_info = {boot_info:#?}");
let stack = start::get_stack_ptr();
let entry = sptr::from_exposed_addr(entry_point.try_into().unwrap());
let hart_id = start::get_hart_id();
let boot_info_ptr = raw_boot_info.insert(RawBootInfo::from(boot_info));
info!("boot_info at {boot_info_ptr:p}");

unsafe { enter_kernel(stack, entry, hart_id, boot_info_ptr) }
}

unsafe fn enter_kernel(
stack: *mut u8,
entry: *const (),
hart_id: usize,
raw_boot_info: &'static RawBootInfo,
) -> ! {
// Check expected signature of entry function
let entry: Entry = {
let entry: unsafe extern "C" fn(hart_id: usize, boot_info: &'static RawBootInfo) -> ! =
unsafe { core::mem::transmute(entry_point) };
unsafe { core::mem::transmute(entry) };
entry
};

info!("Jumping into kernel at {entry:p}");
info!("Entering kernel at {entry:p}, stack at {stack:p}, raw_boot_info at {raw_boot_info:p}");

unsafe {
asm!(
"mv sp, {stack}",
"jr {entry}",
entry = in(reg) entry,
stack = in(reg) start::get_stack_ptr(),
in("a0") start::get_hart_id(),
in("a1") boot_info_ptr,
stack = in(reg) stack,
in("a0") hart_id,
in("a1") raw_boot_info,
options(noreturn)
)
}
Expand Down
41 changes: 3 additions & 38 deletions src/arch/x86_64/firecracker.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use core::arch::asm;
use core::ptr::write_bytes;
use core::{ptr, slice};

Expand All @@ -10,7 +9,6 @@ use hermit_entry::fc::{
E820_TABLE_OFFSET, HDR_MAGIC_OFFSET, LINUX_KERNEL_BOOT_FLAG_MAGIC, LINUX_KERNEL_HRD_MAGIC,
LINUX_SETUP_HEADER_OFFSET, RAMDISK_IMAGE_OFFSET, RAMDISK_SIZE_OFFSET,
};
use hermit_entry::Entry;
use log::info;
use sptr::Strict;
use x86_64::structures::paging::{PageSize, PageTableFlags, Size2MiB, Size4KiB};
Expand Down Expand Up @@ -151,13 +149,6 @@ pub unsafe fn boot_kernel(kernel_info: LoadedKernel) -> ! {
None
};

let current_stack_address = new_stack as u64;
info!(
"Use kernel stack: [{:#x} - {:#x}]",
current_stack_address,
current_stack_address + KERNEL_STACK_SIZE
);

// map stack in the address space
paging::map::<Size4KiB>(
new_stack,
Expand Down Expand Up @@ -240,35 +231,9 @@ pub unsafe fn boot_kernel(kernel_info: LoadedKernel) -> ! {
};

info!("boot_info = {boot_info:#?}");
let stack = sptr::from_exposed_addr_mut(new_stack);
let entry = sptr::from_exposed_addr(entry_point.try_into().unwrap());
let boot_info_ptr = raw_boot_info.insert(RawBootInfo::from(boot_info));
info!("boot_info at {boot_info_ptr:p}");

// Jump to the kernel entry point and provide the Multiboot information to it.
info!(
"Jumping to HermitCore Application Entry Point at {:#x}",
entry_point
);

#[allow(dead_code)]
const ENTRY_TYPE_CHECK: Entry = {
unsafe extern "C" fn entry_signature(
_raw_boot_info: &'static RawBootInfo,
_cpu_id: u32,
) -> ! {
unimplemented!()
}
entry_signature
};

unsafe {
asm!(
"mov rsp, {stack_address}",
"jmp {entry}",
stack_address = in(reg) current_stack_address,
entry = in(reg) entry_point,
in("rdi") boot_info_ptr,
in("rsi") 0,
options(noreturn)
)
}
unsafe { super::enter_kernel(stack, entry, boot_info_ptr) }
}
34 changes: 34 additions & 0 deletions src/arch/x86_64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,37 @@ pub unsafe fn get_memory(memory_size: u64) -> u64 {
let address = PhysAlloc::allocate((memory_size as usize).align_up(Size2MiB::SIZE as usize));
unsafe { map_memory(address, memory_size as usize) as u64 }
}

#[cfg(target_os = "none")]
unsafe fn enter_kernel(
stack: *mut u8,
entry: *const (),
raw_boot_info: &'static hermit_entry::boot_info::RawBootInfo,
) -> ! {
use core::arch::asm;

use hermit_entry::boot_info::RawBootInfo;
use hermit_entry::Entry;
use log::info;

// Check expected signature of entry function
let entry: Entry = {
let entry: unsafe extern "C" fn(raw_boot_info: &'static RawBootInfo, cpu_id: u32) -> ! =
unsafe { core::mem::transmute(entry) };
entry
};

info!("Entering kernel at {entry:p}, stack at {stack:p}, raw_boot_info at {raw_boot_info:p}");

unsafe {
asm!(
"mov rsp, {stack_address}",
"jmp {entry}",
stack_address = in(reg) stack,
entry = in(reg) entry,
in("rdi") raw_boot_info,
in("rsi") 0,
options(noreturn)
)
}
}
37 changes: 3 additions & 34 deletions src/arch/x86_64/multiboot.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use alloc::format;
use core::arch::asm;
use core::ptr::write_bytes;
use core::{mem, ptr, slice};

Expand All @@ -8,7 +7,6 @@ use hermit_entry::boot_info::{
BootInfo, DeviceTreeAddress, HardwareInfo, PlatformInfo, RawBootInfo, SerialPortBase,
};
use hermit_entry::elf::LoadedKernel;
use hermit_entry::Entry;
use log::info;
use multiboot::information::{MemoryManagement, MemoryType, Multiboot, PAddr};
use sptr::Strict;
Expand Down Expand Up @@ -197,9 +195,6 @@ pub unsafe fn boot_kernel(kernel_info: LoadedKernel) -> ! {
}
}

let current_stack_address = new_stack as u64;
info!("Use stack address {:#x}", current_stack_address);

// map stack in the address space
paging::map::<Size4KiB>(
new_stack,
Expand Down Expand Up @@ -239,35 +234,9 @@ pub unsafe fn boot_kernel(kernel_info: LoadedKernel) -> ! {
};

info!("boot_info = {boot_info:#?}");
let stack = sptr::from_exposed_addr_mut(new_stack);
let entry = sptr::from_exposed_addr(entry_point.try_into().unwrap());
let boot_info_ptr = raw_boot_info.insert(RawBootInfo::from(boot_info));
info!("boot_info at {boot_info_ptr:p}");

// Jump to the kernel entry point and provide the Multiboot information to it.
info!(
"Jumping to HermitCore Application Entry Point at {:#x}",
entry_point
);

#[allow(dead_code)]
const ENTRY_TYPE_CHECK: Entry = {
unsafe extern "C" fn entry_signature(
_raw_boot_info: &'static RawBootInfo,
_cpu_id: u32,
) -> ! {
unimplemented!()
}
entry_signature
};

unsafe {
asm!(
"mov rsp, {stack_address}",
"jmp {entry}",
stack_address = in(reg) current_stack_address,
entry = in(reg) entry_point,
in("rdi") boot_info_ptr,
in("rsi") 0,
options(noreturn)
)
}
unsafe { super::enter_kernel(stack, entry, boot_info_ptr) }
}

0 comments on commit 60e0688

Please sign in to comment.