Move .bss and .data tests to inline asm
If .bss is not properly cleared or .data is incorrectly cleared, there is no way to tell what will happen if we try to run Rust code.
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
//! 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,
|
||||
slice,
|
||||
sync::atomic::{AtomicBool, Ordering},
|
||||
};
|
||||
@@ -21,19 +22,35 @@ 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);
|
||||
|
||||
global_asm!("
|
||||
.globl kstart
|
||||
kstart:
|
||||
// BSS should already be zero
|
||||
adrp x9, {bss_test_zero}
|
||||
ldr x9, [x9, :lo12:{bss_test_zero}]
|
||||
cbnz x9, .Lkstart_crash
|
||||
adrp x9, {data_test_nonzero}
|
||||
ldr x9, [x9, :lo12:{data_test_nonzero}]
|
||||
cbz x9, .Lkstart_crash
|
||||
|
||||
mov lr, 0
|
||||
b {start}
|
||||
|
||||
.Lkstart_crash:
|
||||
mov x9, 0
|
||||
br x9
|
||||
",
|
||||
bss_test_zero = sym BSS_TEST_ZERO,
|
||||
data_test_nonzero = sym DATA_TEST_NONZERO,
|
||||
start = sym start,
|
||||
);
|
||||
|
||||
/// The entry to Rust, all things must be initialized
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn kstart(args_ptr: *const KernelArgs) -> ! {
|
||||
unsafe extern "C" fn start(args_ptr: *const KernelArgs) -> ! {
|
||||
unsafe {
|
||||
let bootstrap = {
|
||||
let args = args_ptr.read();
|
||||
|
||||
// BSS should already be zero
|
||||
{
|
||||
assert_eq!(BSS_TEST_ZERO, 0);
|
||||
assert_eq!(DATA_TEST_NONZERO, 0xFFFF_FFFF_FFFF_FFFF);
|
||||
}
|
||||
|
||||
// Set up graphical debug
|
||||
graphical_debug::init(args.env());
|
||||
|
||||
|
||||
+26
-13
@@ -1,9 +1,7 @@
|
||||
use core::{
|
||||
arch::asm,
|
||||
slice,
|
||||
arch::{asm, global_asm},
|
||||
sync::atomic::{AtomicUsize, Ordering},
|
||||
};
|
||||
use fdt::Fdt;
|
||||
|
||||
use crate::{
|
||||
allocator,
|
||||
@@ -38,13 +36,34 @@ fn get_boot_hart_id(env: &[u8]) -> Option<usize> {
|
||||
None
|
||||
}
|
||||
|
||||
global_asm!("
|
||||
.globl kstart
|
||||
kstart:
|
||||
mv gp, x0 // ensure gp relative accesses crash
|
||||
mv tp, x0 // reset percpu until it is initialized
|
||||
csrw sscratch, tp
|
||||
|
||||
// BSS should already be zero
|
||||
ld t0, {bss_test_zero}
|
||||
bnez t0, .Lkstart_crash
|
||||
ld t0, {data_test_nonzero}
|
||||
beqz t0, .Lkstart_crash
|
||||
|
||||
li ra, 0
|
||||
j {start}
|
||||
|
||||
.Lkstart_crash:
|
||||
jr x0
|
||||
",
|
||||
bss_test_zero = sym BSS_TEST_ZERO,
|
||||
data_test_nonzero = sym DATA_TEST_NONZERO,
|
||||
start = sym start,
|
||||
);
|
||||
|
||||
/// The entry to Rust, all things must be initialized
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn kstart(args_ptr: *const KernelArgs) -> ! {
|
||||
unsafe extern "C" fn start(args_ptr: *const KernelArgs) -> ! {
|
||||
unsafe {
|
||||
asm!(
|
||||
"mv tp, x0", // reset percpu until it is initialized
|
||||
"csrw sscratch, tp",
|
||||
"sd x0, -16(fp)", // and stop frame walker here
|
||||
"sd x0, -8(fp)",
|
||||
);
|
||||
@@ -52,12 +71,6 @@ pub unsafe extern "C" fn kstart(args_ptr: *const KernelArgs) -> ! {
|
||||
let bootstrap = {
|
||||
let args = args_ptr.read();
|
||||
|
||||
// BSS should already be zero
|
||||
{
|
||||
assert_eq!(BSS_TEST_ZERO, 0);
|
||||
assert_eq!(DATA_TEST_NONZERO, 0xFFFF_FFFF_FFFF_FFFF);
|
||||
}
|
||||
|
||||
let dtb_data = if args.hwdesc_base != 0 {
|
||||
Some((
|
||||
crate::PHYS_OFFSET + args.hwdesc_base as usize,
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
//! 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,
|
||||
hint,
|
||||
sync::atomic::{AtomicBool, Ordering},
|
||||
@@ -29,19 +30,54 @@ 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);
|
||||
|
||||
#[cfg(target_arch = "x86")]
|
||||
global_asm!("
|
||||
.globl kstart
|
||||
kstart:
|
||||
// BSS should already be zero
|
||||
cmp dword ptr [{bss_test_zero}], 0
|
||||
jne .Lkstart_crash
|
||||
cmp dword ptr [{data_test_nonzero}], 0
|
||||
je .Lkstart_crash
|
||||
|
||||
jmp {start}
|
||||
|
||||
.Lkstart_crash:
|
||||
mov eax, 0
|
||||
jmp eax
|
||||
",
|
||||
bss_test_zero = sym BSS_TEST_ZERO,
|
||||
data_test_nonzero = sym DATA_TEST_NONZERO,
|
||||
start = sym start,
|
||||
);
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
global_asm!("
|
||||
.globl kstart
|
||||
kstart:
|
||||
// BSS should already be zero
|
||||
cmp qword ptr [rip + {bss_test_zero}], 0
|
||||
jne .Lkstart_crash
|
||||
cmp qword ptr [rip + {data_test_nonzero}], 0
|
||||
je .Lkstart_crash
|
||||
|
||||
jmp {start}
|
||||
|
||||
.Lkstart_crash:
|
||||
mov rax, 0
|
||||
jmp rax
|
||||
",
|
||||
bss_test_zero = sym BSS_TEST_ZERO,
|
||||
data_test_nonzero = sym DATA_TEST_NONZERO,
|
||||
start = sym start,
|
||||
);
|
||||
|
||||
/// The entry to Rust, all things must be initialized
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn kstart(args_ptr: *const KernelArgs) -> ! {
|
||||
unsafe extern "C" fn start(args_ptr: *const KernelArgs) -> ! {
|
||||
unsafe {
|
||||
let bootstrap = {
|
||||
let args = args_ptr.read();
|
||||
|
||||
// BSS should already be zero
|
||||
{
|
||||
assert_eq!(BSS_TEST_ZERO.get().read(), 0);
|
||||
assert_eq!(DATA_TEST_NONZERO.get().read(), usize::max_value());
|
||||
}
|
||||
|
||||
// Set up serial debug
|
||||
device::serial::init();
|
||||
|
||||
@@ -123,8 +159,6 @@ pub unsafe extern "C" fn kstart_ap(args_ptr: *const KernelArgsAp) -> ! {
|
||||
unsafe {
|
||||
let cpu_id = {
|
||||
let args = &*args_ptr;
|
||||
assert_eq!(BSS_TEST_ZERO.get().read(), 0);
|
||||
assert_eq!(DATA_TEST_NONZERO.get().read(), usize::max_value());
|
||||
|
||||
// Set up GDT
|
||||
gdt::install_pcr(args.pcr_ptr);
|
||||
|
||||
Reference in New Issue
Block a user