From 7a9bf544777a3dc33c706a21a77cbcfa6f7c2c27 Mon Sep 17 00:00:00 2001 From: mii443 Date: Fri, 11 Jul 2025 13:15:03 +0900 Subject: [PATCH] acpi --- nel_os_bootloader/Cargo.lock | 12 ++++++ nel_os_bootloader/Cargo.toml | 1 + nel_os_bootloader/run-qemu.sh | 1 + nel_os_kernel/src/acpi.rs | 26 +++++++++++++ nel_os_kernel/src/graphics.rs | 73 ++++++++++++++++++++++------------- nel_os_kernel/src/main.rs | 22 +++++------ 6 files changed, 97 insertions(+), 38 deletions(-) create mode 100644 nel_os_kernel/src/acpi.rs diff --git a/nel_os_bootloader/Cargo.lock b/nel_os_bootloader/Cargo.lock index aa16df7..1e89025 100644 --- a/nel_os_bootloader/Cargo.lock +++ b/nel_os_bootloader/Cargo.lock @@ -2,6 +2,17 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "acpi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94476c7ef97af4c4d998b3f422c1b01d5211aad57c80ed200baf148d1f1efab6" +dependencies = [ + "bit_field", + "bitflags 2.9.1", + "log", +] + [[package]] name = "bit_field" version = "0.10.2" @@ -47,6 +58,7 @@ checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" name = "nel_os_bootloader" version = "0.1.0" dependencies = [ + "acpi", "goblin", "log", "nel_os_common", diff --git a/nel_os_bootloader/Cargo.toml b/nel_os_bootloader/Cargo.toml index 1b16374..0e94e45 100644 --- a/nel_os_bootloader/Cargo.toml +++ b/nel_os_bootloader/Cargo.toml @@ -9,3 +9,4 @@ log = "0.4.27" uefi = { version = "0.35.0", features = ["logger", "panic_handler", "alloc"] } x86 = "0.52.0" nel_os_common = { path = "../nel_os_common" } +acpi = "5.2.0" diff --git a/nel_os_bootloader/run-qemu.sh b/nel_os_bootloader/run-qemu.sh index 3cb2749..e114d4a 100755 --- a/nel_os_bootloader/run-qemu.sh +++ b/nel_os_bootloader/run-qemu.sh @@ -14,4 +14,5 @@ qemu-system-x86_64 -enable-kvm \ -cdrom nel_os.iso \ -boot d \ -cpu host \ + -smp 1 \ -s diff --git a/nel_os_kernel/src/acpi.rs b/nel_os_kernel/src/acpi.rs new file mode 100644 index 0000000..711bbda --- /dev/null +++ b/nel_os_kernel/src/acpi.rs @@ -0,0 +1,26 @@ +use core::ptr::NonNull; + +use acpi::{AcpiHandler, PhysicalMapping}; + +#[derive(Clone)] +pub struct KernelAcpiHandler; + +impl AcpiHandler for KernelAcpiHandler { + unsafe fn map_physical_region( + &self, + physical_address: usize, + size: usize, + ) -> acpi::PhysicalMapping { + unsafe { + PhysicalMapping::new( + physical_address, + NonNull::new(physical_address as *mut _).unwrap(), + size, + size, + self.clone(), + ) + } + } + + fn unmap_physical_region(_region: &acpi::PhysicalMapping) {} +} diff --git a/nel_os_kernel/src/graphics.rs b/nel_os_kernel/src/graphics.rs index f0c6455..7bdd03f 100644 --- a/nel_os_kernel/src/graphics.rs +++ b/nel_os_kernel/src/graphics.rs @@ -1,4 +1,5 @@ use ab_glyph::{Font, FontRef, ScaleFont}; +use alloc::vec::Vec; use lazy_static::lazy_static; use nel_os_common::gop::{FrameBuffer as RawFrameBuffer, PixelFormat as RawPixelFormat}; use spin::Mutex; @@ -22,14 +23,20 @@ pub struct FrameBuffer { pub pixel_format: PixelFormat, + pub background_color: (u8, u8, u8), + pub text_cursor: (usize, usize), + + pub text_buffer: Vec>, + pub textscreen_width: usize, + pub textscreen_height: usize, } unsafe impl Send for FrameBuffer {} unsafe impl Sync for FrameBuffer {} impl FrameBuffer { - pub fn from_raw_buffer(raw_buffer: &RawFrameBuffer) -> Self { + pub fn from_raw_buffer(raw_buffer: &RawFrameBuffer, background_color: (u8, u8, u8)) -> Self { Self { frame_buffer: raw_buffer.frame_buffer, width: raw_buffer.width, @@ -40,7 +47,11 @@ impl FrameBuffer { RawPixelFormat::Rgb => PixelFormat::Rgb, RawPixelFormat::Bgr => PixelFormat::Bgr, }, + background_color, text_cursor: (0, 0), + text_buffer: Vec::new(), + textscreen_width: raw_buffer.width / 8, + textscreen_height: raw_buffer.height / 14, } } @@ -76,39 +87,47 @@ impl FrameBuffer { } } - pub fn print_text(&mut self, text: &str) { - let (mut x, mut y) = self.text_cursor; - - for c in text.chars() { - if c == '\n' { - x = 0; - y += 14; - - continue; - } - - self.draw_char(c, x, y); - x += 8; - if x + 8 > self.width { - x = 0; - y += 14; + pub fn clear(&self) { + let (r, g, b) = self.background_color; + for y in 0..self.height { + for x in 0..self.width { + self.draw_pixel(r, g, b, x, y); } } - - self.text_cursor = (x, y); } - pub fn print_char(&mut self, c: char) { - let (x, y) = self.text_cursor; - - self.draw_char(c, x, y); - self.text_cursor.0 += 8; - if self.text_cursor.0 >= self.width { - self.text_cursor.0 = 0; - self.text_cursor.1 += 14; + pub fn update_textscreen(&mut self) { + self.clear(); + for (y, line) in self.text_buffer.iter().enumerate() { + let mut x = 0; + for &c in line { + self.draw_char(c, x, y * 14); + x += 8; + } } } + pub fn add_text_line(&mut self, text: &str) { + if self.text_buffer.len() >= self.textscreen_height { + self.text_buffer.remove(0); + } + self.text_buffer.push(text.chars().collect()); + } + + pub fn clear_text(&mut self) { + self.text_cursor = (0, 0); + self.text_buffer.clear(); + self.clear(); + } + + pub fn print_text(&mut self, text: &str) { + let lines = text.lines(); + for line in lines { + self.add_text_line(line); + } + self.update_textscreen(); + } + pub fn draw_char(&self, c: char, x: usize, y: usize) { let font = FontRef::try_from_slice(FONT).unwrap(); diff --git a/nel_os_kernel/src/main.rs b/nel_os_kernel/src/main.rs index f8985cb..835ba1f 100644 --- a/nel_os_kernel/src/main.rs +++ b/nel_os_kernel/src/main.rs @@ -4,6 +4,7 @@ extern crate alloc; +pub mod acpi; pub mod constant; pub mod cpuid; pub mod graphics; @@ -16,9 +17,11 @@ 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}, memory::{allocator, memory::BitmapMemoryTable, paging}, @@ -112,13 +115,8 @@ pub extern "sysv64" fn main(boot_info: &nel_os_common::BootInfo) { allocator::init_heap(&mut mapper, &mut bitmap_table).unwrap(); - let frame_buffer = FrameBuffer::from_raw_buffer(&boot_info.frame_buffer); - - for x in 0..frame_buffer.width { - for y in 0..frame_buffer.height { - frame_buffer.draw_pixel(64, 64, 64, x, y); - } - } + let frame_buffer = FrameBuffer::from_raw_buffer(&boot_info.frame_buffer, (64, 64, 64)); + frame_buffer.clear(); FRAME_BUFFER.lock().replace(frame_buffer); @@ -141,11 +139,13 @@ pub extern "sysv64" fn main(boot_info: &nel_os_common::BootInfo) { usable_frame as f64 * 4. / 1024. / 1024. ); - x86_64::instructions::interrupts::int3(); + info!("RSDP: {:#x}", boot_info.rsdp); - unsafe { - *(0xffdeadbeaf as *mut u8) = 0x43; - } + let acpi_tables = + unsafe { AcpiTables::from_rsdp(KernelAcpiHandler, boot_info.rsdp as usize) }.unwrap(); + let platform_info = acpi_tables.platform_info().unwrap(); + let processor_info = platform_info.processor_info; + info!("Processor info: {:#x?}", processor_info); hlt_loop(); }