Files
nel_os_uefi/nel_os_kernel/src/main.rs
Masato Imai 3ae0ae4a82 hlt loop
2025-08-06 08:11:28 +00:00

165 lines
3.9 KiB
Rust

#![no_std]
#![no_main]
#![feature(abi_x86_interrupt)]
#![feature(allocator_api)]
extern crate alloc;
pub mod acpi;
pub mod constant;
pub mod cpuid;
pub mod graphics;
pub mod interrupt;
pub mod logging;
pub mod memory;
pub mod platform;
pub mod serial;
pub mod time;
pub mod vmm;
use core::arch::asm;
use core::panic::PanicInfo;
use core::ptr::addr_of;
use ::acpi::AcpiTables;
use x86_64::{registers::control::Cr3, structures::paging::OffsetPageTable, VirtAddr};
use crate::{
acpi::KernelAcpiHandler,
constant::{KERNEL_STACK_SIZE, PKG_VERSION},
graphics::{FrameBuffer, FRAME_BUFFER},
interrupt::apic,
memory::{allocator, memory::BitmapMemoryTable, paging},
};
#[repr(C, align(16))]
struct AlignedStack {
stack: [u8; KERNEL_STACK_SIZE],
}
#[used]
static mut KERNEL_STACK: AlignedStack = AlignedStack {
stack: [0; KERNEL_STACK_SIZE],
};
#[unsafe(no_mangle)]
pub extern "sysv64" fn asm_main() -> ! {
unsafe {
let stack_base = addr_of!(KERNEL_STACK.stack) as *const u8;
let stack_top = stack_base.add(KERNEL_STACK_SIZE);
asm!(
"mov rsp, {stack_top}",
"call {main}",
stack_top = in(reg) stack_top,
main = sym main
)
}
hlt_loop();
}
#[panic_handler]
fn panic(info: &PanicInfo) -> ! {
println!("{}", info);
hlt_loop();
}
#[inline]
fn hlt_loop() -> ! {
loop {
unsafe {
asm!("hlt");
}
}
}
#[unsafe(no_mangle)]
pub extern "sysv64" fn main(boot_info: &nel_os_common::BootInfo) {
interrupt::gdt::init();
interrupt::idt::init_idt();
let virt = VirtAddr::new(
x86_64::registers::control::Cr3::read()
.0
.start_address()
.as_u64(),
);
let phys = paging::translate_addr(virt);
info!("Level 4 page table: {:?} -> {:?}", virt, phys);
let ranges = boot_info.usable_memory.ranges();
let mut count = 0;
for range in ranges {
count += range.end - range.start;
}
info!("Usable memory: {}MiB", count / 1024 / 1024);
let mut bitmap_table = BitmapMemoryTable::init(&boot_info.usable_memory);
info!(
"Memory bitmap initialized: {} -> {}",
bitmap_table.start, bitmap_table.end
);
let mut usable_frame = 0;
for i in bitmap_table.start..bitmap_table.end {
if bitmap_table.get_bit(i) {
usable_frame += 1;
}
}
info!("Usable memory in bitmap: {}MiB", usable_frame * 4 / 1024);
let mut mapper = {
let lv4_table_ptr = paging::init_page_table(&mut bitmap_table);
let lv4_table = unsafe { &mut *lv4_table_ptr };
unsafe { OffsetPageTable::new(lv4_table, VirtAddr::new(0x0)) }
};
info!("Page table initialized");
allocator::init_heap(&mut mapper, &mut bitmap_table).unwrap();
let frame_buffer = FrameBuffer::from_raw_buffer(&boot_info.frame_buffer, (64, 64, 64));
frame_buffer.clear();
FRAME_BUFFER.lock().replace(frame_buffer);
println!("");
info!("Kernel initialized successfully");
info!("Kernel version: {}", PKG_VERSION);
info!(
"Level 4 page table at {:#x}",
Cr3::read().0.start_address().as_u64()
);
info!(
"Memory bitmap: {} -> {}",
bitmap_table.start, bitmap_table.end
);
info!("CPU: {} {}", cpuid::get_vendor_id(), cpuid::get_brand());
info!(
"Usable memory: {}MiB ({:.1}GiB)",
usable_frame * 4 / 1024,
usable_frame as f64 * 4. / 1024. / 1024.
);
info!("RSDP: {:#x}", boot_info.rsdp);
let acpi_tables =
unsafe { AcpiTables::from_rsdp(KernelAcpiHandler, boot_info.rsdp as usize) }.unwrap();
let platform_info = acpi_tables.platform_info().unwrap();
apic::init_local_apic(platform_info);
info!("Local APIC initialized",);
x86_64::instructions::interrupts::enable();
info!("Interrupts enabled");
let mut vcpu = vmm::get_vcpu(&mut bitmap_table).unwrap();
while vcpu.run().is_ok() {}
hlt_loop();
}