Don't depend on the stack setup by the bootloader
This way we can choose our own size for the stack and don't have to identity map it manually. Also this way the bootloader doesn't have to change the stack pointer right before calling into the kernel (which it currently does in an unsound way)
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
//! This function is where the kernel sets up IRQ handlers
|
||||
//! It is increcibly unsafe, and should be minimal in nature
|
||||
//! It is incredibly unsafe, and should be minimal in nature
|
||||
//! It must create the IDT with the correct entries, those entries are
|
||||
//! defined in other files inside of the `arch` module
|
||||
use core::{
|
||||
arch::global_asm,
|
||||
cell::SyncUnsafeCell,
|
||||
slice,
|
||||
sync::atomic::{AtomicBool, Ordering},
|
||||
};
|
||||
@@ -22,6 +23,12 @@ static mut DATA_TEST_NONZERO: usize = 0xFFFF_FFFF_FFFF_FFFF;
|
||||
pub static AP_READY: AtomicBool = AtomicBool::new(false);
|
||||
static BSP_READY: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
#[repr(C, align(16))]
|
||||
struct StackAlign<T>(T);
|
||||
|
||||
static STACK: SyncUnsafeCell<StackAlign<[u8; 128 * 1024]>> =
|
||||
SyncUnsafeCell::new(StackAlign([0; 128 * 1024]));
|
||||
|
||||
global_asm!("
|
||||
.globl kstart
|
||||
kstart:
|
||||
@@ -33,6 +40,11 @@ global_asm!("
|
||||
ldr x9, [x9, :lo12:{data_test_nonzero}]
|
||||
cbz x9, .Lkstart_crash
|
||||
|
||||
adrp x1, {stack}
|
||||
add x1, x1, :lo12:{stack}
|
||||
mov x2, {stack_size}-16
|
||||
add sp, x1, x2
|
||||
|
||||
mov lr, 0
|
||||
b {start}
|
||||
|
||||
@@ -42,6 +54,8 @@ global_asm!("
|
||||
",
|
||||
bss_test_zero = sym BSS_TEST_ZERO,
|
||||
data_test_nonzero = sym DATA_TEST_NONZERO,
|
||||
stack = sym STACK,
|
||||
stack_size = const size_of_val(&STACK),
|
||||
start = sym start,
|
||||
);
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use core::{
|
||||
arch::{asm, global_asm},
|
||||
cell::SyncUnsafeCell,
|
||||
sync::atomic::{AtomicUsize, Ordering},
|
||||
};
|
||||
|
||||
@@ -36,6 +37,12 @@ fn get_boot_hart_id(env: &[u8]) -> Option<usize> {
|
||||
None
|
||||
}
|
||||
|
||||
#[repr(C, align(16))]
|
||||
struct StackAlign<T>(T);
|
||||
|
||||
static STACK: SyncUnsafeCell<StackAlign<[u8; 128 * 1024]>> =
|
||||
SyncUnsafeCell::new(StackAlign([0; 128 * 1024]));
|
||||
|
||||
global_asm!("
|
||||
.globl kstart
|
||||
kstart:
|
||||
@@ -49,6 +56,10 @@ global_asm!("
|
||||
ld t0, {data_test_nonzero}
|
||||
beqz t0, .Lkstart_crash
|
||||
|
||||
.Lpcrel_hi0:
|
||||
auipc sp, %pcrel_hi({stack}+{stack_size}-16)
|
||||
addi sp, sp, %pcrel_lo(.Lpcrel_hi0)
|
||||
|
||||
li ra, 0
|
||||
j {start}
|
||||
|
||||
@@ -57,17 +68,14 @@ global_asm!("
|
||||
",
|
||||
bss_test_zero = sym BSS_TEST_ZERO,
|
||||
data_test_nonzero = sym DATA_TEST_NONZERO,
|
||||
stack = sym STACK,
|
||||
stack_size = const size_of_val(&STACK),
|
||||
start = sym start,
|
||||
);
|
||||
|
||||
/// The entry to Rust, all things must be initialized
|
||||
unsafe extern "C" fn start(args_ptr: *const KernelArgs) -> ! {
|
||||
unsafe {
|
||||
asm!(
|
||||
"sd x0, -16(fp)", // and stop frame walker here
|
||||
"sd x0, -8(fp)",
|
||||
);
|
||||
|
||||
let bootstrap = {
|
||||
let args = args_ptr.read();
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//! This function is where the kernel sets up IRQ handlers
|
||||
//! It is increcibly unsafe, and should be minimal in nature
|
||||
//! It is incredibly unsafe, and should be minimal in nature
|
||||
//! It must create the IDT with the correct entries, those entries are
|
||||
//! defined in other files inside of the `arch` module
|
||||
use core::{
|
||||
@@ -30,6 +30,12 @@ static DATA_TEST_NONZERO: SyncUnsafeCell<usize> = SyncUnsafeCell::new(usize::MAX
|
||||
pub static AP_READY: AtomicBool = AtomicBool::new(false);
|
||||
static BSP_READY: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
#[repr(C, align(16))]
|
||||
struct StackAlign<T>(T);
|
||||
|
||||
static STACK: SyncUnsafeCell<StackAlign<[u8; 128 * 1024]>> =
|
||||
SyncUnsafeCell::new(StackAlign([0; 128 * 1024]));
|
||||
|
||||
#[cfg(target_arch = "x86")]
|
||||
global_asm!("
|
||||
.globl kstart
|
||||
@@ -40,6 +46,11 @@ global_asm!("
|
||||
cmp dword ptr [{data_test_nonzero}], 0
|
||||
je .Lkstart_crash
|
||||
|
||||
mov eax, [esp + 4]
|
||||
lea esp, [{stack}+{stack_size}-16]
|
||||
mov [esp + 4], eax
|
||||
mov [esp + 8], esp
|
||||
|
||||
jmp {start}
|
||||
|
||||
.Lkstart_crash:
|
||||
@@ -48,6 +59,8 @@ global_asm!("
|
||||
",
|
||||
bss_test_zero = sym BSS_TEST_ZERO,
|
||||
data_test_nonzero = sym DATA_TEST_NONZERO,
|
||||
stack = sym STACK,
|
||||
stack_size = const size_of_val(&STACK),
|
||||
start = sym start,
|
||||
);
|
||||
|
||||
@@ -61,6 +74,14 @@ global_asm!("
|
||||
cmp qword ptr [rip + {data_test_nonzero}], 0
|
||||
je .Lkstart_crash
|
||||
|
||||
// Note: The System V ABI requires the stack to be aligned to 16 bytes
|
||||
// before the call instruction. As we jump rather than call it has to
|
||||
// be offset by 8 bytes. Additionally reserve a bit more space at the
|
||||
// end of the stack to ensure that the start function returns to
|
||||
// address 0.
|
||||
lea rsp, [rip + {stack}+{stack_size}-24]
|
||||
mov rsi, rsp
|
||||
|
||||
jmp {start}
|
||||
|
||||
.Lkstart_crash:
|
||||
@@ -69,11 +90,13 @@ global_asm!("
|
||||
",
|
||||
bss_test_zero = sym BSS_TEST_ZERO,
|
||||
data_test_nonzero = sym DATA_TEST_NONZERO,
|
||||
stack = sym STACK,
|
||||
stack_size = const size_of_val(&STACK),
|
||||
start = sym start,
|
||||
);
|
||||
|
||||
/// The entry to Rust, all things must be initialized
|
||||
unsafe extern "C" fn start(args_ptr: *const KernelArgs) -> ! {
|
||||
unsafe extern "C" fn start(args_ptr: *const KernelArgs, stack_end: usize) -> ! {
|
||||
unsafe {
|
||||
let bootstrap = {
|
||||
let args = args_ptr.read();
|
||||
@@ -88,7 +111,7 @@ unsafe extern "C" fn start(args_ptr: *const KernelArgs) -> ! {
|
||||
args.print();
|
||||
|
||||
// Set up GDT
|
||||
gdt::init_bsp(args.stack_base as usize + args.stack_size as usize);
|
||||
gdt::init_bsp(stack_end);
|
||||
|
||||
// Set up IDT
|
||||
idt::init_bsp();
|
||||
|
||||
@@ -155,11 +155,6 @@ fn register_memory_from_kernel_args(args: &KernelArgs) {
|
||||
args.kernel_size as usize,
|
||||
BootloaderMemoryKind::Kernel,
|
||||
);
|
||||
register_memory_region(
|
||||
args.stack_base as usize,
|
||||
args.stack_size as usize,
|
||||
BootloaderMemoryKind::IdentityMap,
|
||||
);
|
||||
register_memory_region(
|
||||
args.env_base as usize,
|
||||
args.env_size as usize,
|
||||
|
||||
@@ -40,11 +40,6 @@ impl KernelArgs {
|
||||
{ self.kernel_base },
|
||||
self.kernel_base + self.kernel_size
|
||||
);
|
||||
info!(
|
||||
"Stack: {:X}:{:X}",
|
||||
{ self.stack_base },
|
||||
self.stack_base + self.stack_size
|
||||
);
|
||||
info!(
|
||||
"Env: {:X}:{:X}",
|
||||
{ self.env_base },
|
||||
|
||||
Reference in New Issue
Block a user