use core::ffi::c_void;
use super::head::_head;
use crate::{entry::PrimaryCpuInitInfo, smp::PerCpuMeta};
unsafe extern "C" {
fn __kernel_code_end();
}
#[unsafe(no_mangle)]
pub extern "C" fn kernel_entry(
efi_boot: usize,
_cmdline: *const u8,
systemtable: *const c_void,
) -> ! {
if efi_boot == 0 {
clear_bss();
}
if efi_boot != 0 {
crate::efi_stub::setup_service(systemtable);
println!("UEFI setup.");
}
let kernel_code_start_lma = sym_addr!(_head);
let kernel_code_end_lma = sym_addr!(__kernel_code_end);
crate::entry::primary_init_early(PrimaryCpuInitInfo {
kernel_start: kernel_code_start_lma.into(),
kernel_end: kernel_code_end_lma.into(),
kernel_start_link: crate::consts::VM_LOAD_ADDRESS.into(),
});
super::paging::enable_mmu()
}
pub(crate) fn mmu_entry() -> ! {
super::trap::setup();
super::trap::init_local();
crate::prime_entry()
}
pub(crate) unsafe extern "C" fn _secondary_entry(arg: usize) -> ! {
let cpu_meta = unsafe { &*(crate::mem::phys_to_virt(arg) as *const PerCpuMeta) };
super::power::notify_ap_started(cpu_meta.cpu_id);
crate::entry::secondary_entry(arg);
loop {
core::hint::spin_loop();
}
}
fn clear_bss() {
unsafe extern "C" {
static mut __bss_start: u8;
static mut __bss_stop: u8;
}
let start = core::ptr::addr_of_mut!(__bss_start);
let end = core::ptr::addr_of_mut!(__bss_stop);
let len = end as usize - start as usize;
unsafe {
core::ptr::write_bytes(start, 0, len);
}
}