Browse Source

feat: 添加对内核引导协议的抽象 (#913)

* 添加multiboot header

* head.S传参增加bootloader类型

* feat: 添加引导加载协议的抽象,并为multiboot2实现这个抽象.

* 把framebuffer的映射地址改为从early ioremap和mmio pool分配

* riscv64能运行
LoGin 6 months ago
parent
commit
2b7818e80e
42 changed files with 828 additions and 1329 deletions
  1. 0 1
      .vscode/settings.json
  2. 16 4
      docs/kernel/boot/bootloader.md
  3. 0 1
      docs/kernel/boot/index.rst
  4. 0 46
      docs/kernel/boot/multiboot2.md
  5. 3 2
      kernel/Cargo.toml
  6. 3 1
      kernel/src/arch/riscv64/driver/sbi.rs
  7. 15 0
      kernel/src/arch/riscv64/init/boot.rs
  8. 41 0
      kernel/src/arch/riscv64/init/dragonstub.rs
  9. 9 1
      kernel/src/arch/riscv64/init/mod.rs
  10. 11 1
      kernel/src/arch/riscv64/rand.rs
  11. 65 21
      kernel/src/arch/x86_64/asm/head.S
  12. 55 0
      kernel/src/arch/x86_64/init/boot.rs
  13. 15 3
      kernel/src/arch/x86_64/init/mod.rs
  14. 248 0
      kernel/src/arch/x86_64/init/multiboot2.rs
  15. 1 0
      kernel/src/arch/x86_64/link.lds
  16. 17 81
      kernel/src/arch/x86_64/mm/mod.rs
  17. 8 8
      kernel/src/arch/x86_64/pci/pci.rs
  18. 1 1
      kernel/src/driver/Makefile
  19. 0 10
      kernel/src/driver/acpi/Makefile
  20. 0 35
      kernel/src/driver/acpi/acpi.c
  21. 0 37
      kernel/src/driver/acpi/acpi.h
  22. 0 8
      kernel/src/driver/acpi/c_adapter.rs
  23. 51 32
      kernel/src/driver/acpi/mod.rs
  24. 0 10
      kernel/src/driver/multiboot2/Makefile
  25. 0 165
      kernel/src/driver/multiboot2/multiboot2.c
  26. 0 473
      kernel/src/driver/multiboot2/multiboot2.h
  27. 11 74
      kernel/src/driver/video/fbdev/vesafb.rs
  28. 19 33
      kernel/src/driver/video/mod.rs
  29. 0 16
      kernel/src/include/bindings/wrapper.h
  30. 176 0
      kernel/src/init/boot.rs
  31. 9 5
      kernel/src/init/init.rs
  32. 3 96
      kernel/src/init/mod.rs
  33. 10 1
      kernel/src/libs/lib_ui/screen_manager.rs
  34. 4 50
      kernel/src/mm/c_adapter.rs
  35. 6 54
      kernel/src/mm/mm.h
  36. 28 0
      kernel/src/mm/mmio_buddy.rs
  37. 2 2
      kernel/src/mm/page.rs
  38. 1 2
      kernel/src/net/event_poll/mod.rs
  39. 0 1
      kernel/src/syscall/syscall.c
  40. 0 13
      kernel/src/time/sleep.h
  41. 0 40
      kernel/src/time/sleep.rs
  42. 0 1
      user/apps/test_gettimeofday/main.c

+ 0 - 1
.vscode/settings.json

@@ -129,7 +129,6 @@
         "assert.h": "c",
         "sys_version.h": "c",
         "cmd.h": "c",
-        "sleep.h": "c",
         "net.h": "c",
         "cmd_test.h": "c",
         "cmpxchg.h": "c",

+ 16 - 4
docs/kernel/boot/bootloader.md

@@ -1,12 +1,24 @@
 # 引导加载程序
 
-## 原理
+## X86_64
 
-  目前,DragonOS支持Legacy BIOS以及UEFI两种方式,进行启动引导。
+- [x] multiboot2
 
-  在`head.S`的头部包含了Multiboot2引导头,里面标志了一些Multiboot2相关的特定信息,以及一些配置命令。
+## RISC-V 64
 
-  在DragonOS的启动初期,会存储由GRUB2传来的magic number以及multiboot2_boot_info_addr。当系统进入`Start_Kernel`函数之后,将会把这两个信息保存到multiboot2驱动程序之中。信息的具体含义请参照Multiboot2 Specification进行理解,该部分难度不大,相信读者经过思考能理解其中的原理。
+DragonOS在RISC-V 64上,启动流程为:
+
+opensbi --> uboot --> DragonStub --> kernel
+
+这个启动流程,使得DragonOS内核与具体的硬件板卡解耦,能够以同一个二进制文件,在不同的硬件板卡上启动运行。
+
+
+## 内核启动回调
+
+DragonOS对内核引导加载程序进行了抽象,体现为`BootCallbacks`这个trait。
+不同的引导加载程序,实现对应的callback,初始化内核bootParams或者是其他的一些数据结构。
+
+内核启动时,自动根据引导加载程序的类型,注册回调。并且在适当的时候,会调用这些回调函数。
 
 ## 参考资料
 

+ 0 - 1
docs/kernel/boot/index.rst

@@ -8,4 +8,3 @@
    :caption: 目录
 
    bootloader
-   multiboot2

+ 0 - 46
docs/kernel/boot/multiboot2.md

@@ -1,46 +0,0 @@
-# Multiboot2支持模块
-
-  Multiboot2支持模块提供对Multiboot2协议的支持。位于`kernel/driver/multiboot2`文件夹中。
-
-  根据Multiboot2协议,操作系统能够从BootLoader处获得一些信息,比如基本的硬件信息以及ACPI表的起始地址等。
-
----
-
-## 数据结构
-
-  `kernel/driver/multiboot2/multiboot2.h`中按照Multiboot2协议的规定,定义了大部分的数据结构,具体细节可查看该文件: [DragonOS/multiboot2.h at master · fslongjin/DragonOS · GitHub](https://github.com/fslongjin/DragonOS/blob/master/kernel/driver/multiboot2/multiboot2.h)
-
----
-
-## 迭代器
-
-  由于Multiboot2的信息存储在自`multiboot2_boot_info_addr`开始的一段连续的内存空间之中,且不同类型的header的长度不同,因此设计了一迭代器`multiboot2_iter`。
-
-### 函数原型
-
-```c
-void multiboot2_iter(bool (*_fun)(const struct iter_data_t *, void *, unsigned int *),
-                     void *data, unsigned int *count)
-```
-
-**_fun**
-
-  指定的handler。当某个header的tag与该handler所处理的tag相同时,handler将处理该header,并返回true。
-
-  其第一个参数为tag类型,第二个参数为返回的数据的指针,第三个值为计数(某些没有用到该值的地方,该值可以为空)
-
-**data**
-
-  传递给`_fun`的第二个参数,`_fun`函数将填充该指针所指向的内存区域,从而返回数据。
-
-**count**
-
-  当返回的**data**为一个列表时,通过该值来指示列表中有多少项。
-
----
-
-## 迭代工作函数
-
-  在模块中,按照我们需要获取不同类型的tag的需要,定义了一些迭代器工作函数。
-
-

+ 3 - 2
kernel/Cargo.toml

@@ -27,7 +27,7 @@ fatfs-secure = ["fatfs"]
 
 # 运行时依赖项
 [dependencies]
-acpi = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/acpi-rs.git", rev = "fb69243dcf" }
+acpi = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/acpi-rs.git", rev = "282df2af7b" }
 asm_macros = { path = "crates/asm_macros" }
 atomic_enum = "=0.2.0"
 bit_field = "=0.10"
@@ -35,9 +35,9 @@ bitfield-struct = "=0.5.3"
 bitflags = "=1.3.2"
 bitmap = { path = "crates/bitmap" }
 driver_base_macros = { "path" = "crates/driver_base_macros" }
-# 一个no_std的hashmap、hashset
 elf = { version = "=0.7.2", default-features = false }
 fdt = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/fdt", rev = "9862813020" }
+# 一个no_std的hashmap、hashset
 hashbrown = "=0.13.2"
 ida = { path = "src/libs/ida" }
 intertrait = { path = "crates/intertrait" }
@@ -63,6 +63,7 @@ lru = "0.12.3"
 # target为x86_64时,使用下面的依赖
 [target.'cfg(target_arch = "x86_64")'.dependencies]
 mini-backtrace = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/mini-backtrace.git", rev = "e0b1d90940" }
+multiboot2 = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/multiboot2", rev = "05739aab40" }
 raw-cpuid = "11.0.1"
 x86 = "=0.52.0"
 x86_64 = "=0.14.10"

+ 3 - 1
kernel/src/arch/riscv64/driver/sbi.rs

@@ -1,3 +1,5 @@
+use core::ptr::addr_of;
+
 /// 向控制台打印字符串。
 ///
 /// 该函数接受一个字节切片 `s` 作为输入,并迭代切片中的每个字节 `c`。
@@ -75,7 +77,7 @@ impl SbiDriver {
 
     /// 获取probe得到的SBI扩展信息。
     pub fn extensions() -> &'static SBIExtensions {
-        unsafe { &EXTENSIONS }
+        unsafe { addr_of!(EXTENSIONS).as_ref().unwrap() }
     }
 
     fn probe_extensions() -> SBIExtensions {

+ 15 - 0
kernel/src/arch/riscv64/init/boot.rs

@@ -0,0 +1,15 @@
+use system_error::SystemError;
+
+use super::dragonstub::early_dragonstub_init;
+
+#[derive(Debug)]
+#[repr(u64)]
+pub(super) enum BootProtocol {
+    DragonStub = 1,
+}
+
+pub(super) fn early_boot_init(protocol: BootProtocol) -> Result<(), SystemError> {
+    match protocol {
+        BootProtocol::DragonStub => early_dragonstub_init(),
+    }
+}

+ 41 - 0
kernel/src/arch/riscv64/init/dragonstub.rs

@@ -0,0 +1,41 @@
+use alloc::string::String;
+use system_error::SystemError;
+
+use crate::{
+    driver::video::fbdev::base::BootTimeScreenInfo,
+    init::boot::{register_boot_callbacks, BootCallbacks, BootloaderAcpiArg},
+};
+
+pub(super) fn early_dragonstub_init() -> Result<(), SystemError> {
+    register_boot_callbacks(&DragonStubCallBack);
+    Ok(())
+}
+
+struct DragonStubCallBack;
+
+impl BootCallbacks for DragonStubCallBack {
+    fn init_bootloader_name(&self) -> Result<Option<String>, SystemError> {
+        Ok(format!("DragonStub").into())
+    }
+
+    fn init_acpi_args(&self) -> Result<BootloaderAcpiArg, SystemError> {
+        Ok(BootloaderAcpiArg::NotProvided)
+    }
+
+    fn init_kernel_cmdline(&self) -> Result<(), SystemError> {
+        // parsed in `early_init_scan_chosen()`
+        Ok(())
+    }
+
+    fn early_init_framebuffer_info(
+        &self,
+        _scinfo: &mut BootTimeScreenInfo,
+    ) -> Result<(), SystemError> {
+        unimplemented!("dragonstub early_init_framebuffer_info")
+    }
+
+    fn early_init_memory_blocks(&self) -> Result<(), SystemError> {
+        // parsed in `early_init_scan_memory()` and uefi driver
+        Ok(())
+    }
+}

+ 9 - 1
kernel/src/arch/riscv64/init/mod.rs

@@ -3,7 +3,11 @@ use log::{debug, info};
 use system_error::SystemError;
 
 use crate::{
-    arch::{driver::sbi::SbiDriver, mm::init::mm_early_init},
+    arch::{
+        driver::sbi::SbiDriver,
+        init::boot::{early_boot_init, BootProtocol},
+        mm::init::mm_early_init,
+    },
     driver::{firmware::efi::init::efi_init, open_firmware::fdt::open_firmware_fdt_driver},
     init::{boot_params, init::start_kernel},
     mm::{memblock::mem_block_manager, PhysAddr, VirtAddr},
@@ -13,6 +17,9 @@ use crate::{
 
 use super::{cpu::init_local_context, interrupt::entry::handle_exception};
 
+mod boot;
+mod dragonstub;
+
 #[derive(Debug)]
 pub struct ArchBootParams {
     /// 启动时的fdt物理地址
@@ -119,6 +126,7 @@ pub fn early_setup_arch() -> Result<(), SystemError> {
         "DragonOS kernel is running on hart {}, fdt address:{:?}",
         hartid, fdt_paddr
     );
+    early_boot_init(BootProtocol::DragonStub).expect("Failed to init boot protocol!");
     mm_early_init();
 
     print_node(fdt.find_node("/").unwrap(), 0);

+ 11 - 1
kernel/src/arch/riscv64/rand.rs

@@ -1,3 +1,13 @@
 pub fn rand() -> usize {
-    unimplemented!("RiscV64 rand");
+    static mut SEED: u64 = 0xdead_beef_cafe_babe;
+    let mut buf = [0u8; size_of::<usize>()];
+    for x in buf.iter_mut() {
+        unsafe {
+            // from musl
+            SEED = SEED.wrapping_mul(0x5851_f42d_4c95_7f2d);
+            *x = (SEED >> 33) as u8;
+        }
+    }
+    let x: usize = unsafe { core::mem::transmute(buf) };
+    return x;
 }

+ 65 - 21
kernel/src/arch/x86_64/asm/head.S

@@ -13,8 +13,7 @@
 //  The magic field should contain this.
 #define MULTIBOOT2_HEADER_MAGIC 0xe85250d6
 
-//  This should be in %eax.
-#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289
+
 
 //  Alignment of multiboot modules.
 #define MULTIBOOT_MOD_ALIGN 0x00001000
@@ -71,7 +70,15 @@
 #define MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED 1
 #define MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2
 
+//  This should be in %eax.
+#define MULTIBOOT_BOOTLOADER_MAGIC 0x2badb002
+#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289
 
+// 存储到boot_entry_type的值
+#define BOOT_ENTRY_TYPE_MULTIBOOT 1
+#define BOOT_ENTRY_TYPE_MULTIBOOT2  2
+#define BOOT_ENTRY_TYPE_LINUX_32  3
+#define BOOT_ENTRY_TYPE_LINUX_64  4
 
 // 直接用 -m64 编译出来的是 64 位代码,
 // 但是启动后的机器是 32 位的,相当于在 32 位机器上跑 64 位程序。
@@ -85,25 +92,40 @@
 // 声明这一段代码以 32 位模式编译
 .code32
 
+.section ".multiboot_header", "a"
+
+MB_MAGIC = 0x1BADB002
+MB_FLAGS = 0
+MB_CHECKSUM = -(MB_MAGIC + MB_FLAGS)
+
+.code32
+multiboot_header:
+    .align 8
+    .long MB_MAGIC
+    .long MB_FLAGS
+    .long MB_CHECKSUM
+
+
 // multiboot2 文件头
 // 计算头长度
-.SET HEADER_LENGTH, multiboot_header_end - multiboot_header
+.SET MB2_HEADER_LENGTH, multiboot2_header_end - multiboot2_header
 // 计算校验和
-.SET CHECKSUM, -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT_ARCHITECTURE_I386 + HEADER_LENGTH)
+.SET MB2_CHECKSUM, -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT_ARCHITECTURE_I386 + MB2_HEADER_LENGTH)
 // 8 字节对齐
-.section .multiboot_header
+.code32
+.section .multiboot2_header
 .align MULTIBOOT_HEADER_ALIGN
 // 声明所属段
 
-multiboot_header:
+multiboot2_header:
     // 魔数
     .long MULTIBOOT2_HEADER_MAGIC
     // 架构
     .long MULTIBOOT_ARCHITECTURE_I386
     // 头长度
-    .long HEADER_LENGTH
+    .long MB2_HEADER_LENGTH
     // 校验和
-    .long CHECKSUM
+    .long MB2_CHECKSUM
     // 添加其它内容在此,详细信息见 Multiboot2 Specification version 2.0.pdf
 
 // 设置帧缓冲区(同时在这里设置qemu的分辨率, 默认为: 1440*900, 还支持: 640*480, 等)
@@ -121,13 +143,13 @@ framebuffer_tag_end:
     // 结束标记
     .short 0
     .long 8
-multiboot_header_end:
+multiboot2_header_end:
 
 .section .bootstrap
 
+
 .global _start
 .type _start, @function
-# 在 multiboot2.cpp 中定义
 
 .extern _start64
 .extern boot_info_addr
@@ -136,12 +158,30 @@ ENTRY(_start)
     // 关中断
     cli
     
-    // multiboot2_info 结构体指针
-    mov %ebx, mb2_info
+    // multiboot2_info/ multiboot_info 结构体指针
+    mov %ebx, mb_entry_info
     //mov %ebx, %e8
-    // 魔数
-    mov %eax, mb2_magic
-
+    // multiboot魔数
+    mov %eax, mb_entry_magic
+
+    mov $MULTIBOOT_BOOTLOADER_MAGIC, %ebx
+    cmp %eax, %ebx
+    je bl_magic_is_mb
+    mov $MULTIBOOT2_BOOTLOADER_MAGIC, %ebx
+    cmp %eax, %ebx
+    je bl_magic_is_mb2
+    jmp halt // unreachable
+
+bl_magic_is_mb:
+    mov $BOOT_ENTRY_TYPE_MULTIBOOT, %ebx
+    mov %ebx, boot_entry_type
+    jmp protected_mode_setup
+bl_magic_is_mb2:
+    mov $BOOT_ENTRY_TYPE_MULTIBOOT2, %ebx
+    mov %ebx, boot_entry_type
+    jmp protected_mode_setup
+
+protected_mode_setup:
     //mov %eax, %e9
     / 从保护模式跳转到长模式
     // 1. 允许 PAE
@@ -225,9 +265,10 @@ switch_to_start64:
 
 
 .code64
-is_from_ap:
-    
+halt:
+    cli
     hlt
+    jmp halt
 
 .global _start64
 .type _start64, @function
@@ -435,10 +476,11 @@ repeat_set_idt:
 
     
     // 传参
-    movq mb2_info, %rdi
-    movq mb2_magic, %rsi
+    movq mb_entry_info, %rdi
+    movq mb_entry_magic, %rsi
     movq %r13, %rdx // GDT size
     movq %r12, %r10 // IDT size
+    movq boot_entry_type, %r8
 
 	lretq
 
@@ -573,8 +615,10 @@ IDT_BASE64: .quad IDT_Table + 0xffff800000000000
 
 
 .section .bootstrap.data
-mb2_magic: .quad 0
-mb2_info: .quad 0
+mb_entry_magic: .quad 0
+mb_entry_info: .quad 0
+// 引导协议类型
+boot_entry_type: .quad 0
 
 .code32
 // 临时页表 4KB/页

+ 55 - 0
kernel/src/arch/x86_64/init/boot.rs

@@ -0,0 +1,55 @@
+use system_error::SystemError;
+
+use super::multiboot2::early_multiboot2_init;
+
+const BOOT_ENTRY_TYPE_MULTIBOOT: u64 = 1;
+const BOOT_ENTRY_TYPE_MULTIBOOT2: u64 = 2;
+const BOOT_ENTRY_TYPE_LINUX_32: u64 = 3;
+const BOOT_ENTRY_TYPE_LINUX_64: u64 = 4;
+
+#[derive(Debug)]
+#[repr(u64)]
+enum BootProtocol {
+    Multiboot = 1,
+    Multiboot2,
+    Linux32,
+    Linux64,
+}
+
+impl TryFrom<u64> for BootProtocol {
+    type Error = SystemError;
+
+    fn try_from(value: u64) -> Result<Self, Self::Error> {
+        match value {
+            BOOT_ENTRY_TYPE_MULTIBOOT => Ok(BootProtocol::Multiboot),
+            BOOT_ENTRY_TYPE_MULTIBOOT2 => Ok(BootProtocol::Multiboot2),
+            BOOT_ENTRY_TYPE_LINUX_32 => Ok(BootProtocol::Linux32),
+            BOOT_ENTRY_TYPE_LINUX_64 => Ok(BootProtocol::Linux64),
+            _ => Err(SystemError::EINVAL),
+        }
+    }
+}
+
+#[inline(never)]
+pub(super) fn early_boot_init(
+    boot_entry_type: u64,
+    arg1: u64,
+    arg2: u64,
+) -> Result<(), SystemError> {
+    let boot_protocol = BootProtocol::try_from(boot_entry_type)?;
+    match boot_protocol {
+        BootProtocol::Multiboot => {
+            // early_multiboot_init(arg1, arg2);
+            unimplemented!();
+        }
+        BootProtocol::Multiboot2 => early_multiboot2_init(arg1 as u32, arg2),
+        BootProtocol::Linux32 => {
+            // linux32_init(arg1, arg2);
+            unimplemented!();
+        }
+        BootProtocol::Linux64 => {
+            // linux64_init(arg1, arg2);
+            unimplemented!();
+        }
+    }
+}

+ 15 - 3
kernel/src/arch/x86_64/init/mod.rs

@@ -1,4 +1,7 @@
-use core::sync::atomic::{compiler_fence, Ordering};
+use core::{
+    hint::spin_loop,
+    sync::atomic::{compiler_fence, Ordering},
+};
 
 use log::debug;
 use system_error::SystemError;
@@ -11,6 +14,8 @@ use crate::{
     mm::{MemoryManagementArch, PhysAddr},
 };
 
+use self::boot::early_boot_init;
+
 use super::{
     driver::{
         hpet::{hpet_init, hpet_instance},
@@ -19,6 +24,9 @@ use super::{
     MMArch,
 };
 
+mod boot;
+mod multiboot2;
+
 #[derive(Debug)]
 pub struct ArchBootParams {}
 
@@ -31,7 +39,6 @@ extern "C" {
     static mut IDT_Table: [usize; 0usize];
     fn head_stack_start();
 
-    fn multiboot2_init(mb2_info: u64, mb2_magic: u32) -> bool;
 }
 
 #[no_mangle]
@@ -41,6 +48,7 @@ unsafe extern "C" fn kernel_main(
     mb2_magic: u64,
     bsp_gdt_size: u64,
     bsp_idt_size: u64,
+    boot_entry_type: u64,
 ) -> ! {
     let mut gdtp = DescriptorTablePointer::<usize>::default();
     let gdt_vaddr =
@@ -59,7 +67,11 @@ unsafe extern "C" fn kernel_main(
     x86::dtables::lidt(&idtp);
 
     compiler_fence(Ordering::SeqCst);
-    multiboot2_init(mb2_info, (mb2_magic & 0xFFFF_FFFF) as u32);
+    if early_boot_init(boot_entry_type, mb2_magic, mb2_info).is_err() {
+        loop {
+            spin_loop();
+        }
+    }
     compiler_fence(Ordering::SeqCst);
 
     start_kernel();

+ 248 - 0
kernel/src/arch/x86_64/init/multiboot2.rs

@@ -0,0 +1,248 @@
+use core::hint::spin_loop;
+
+use acpi::rsdp::Rsdp;
+use alloc::string::{String, ToString};
+use multiboot2::{BootInformation, BootInformationHeader, MemoryAreaType, RsdpV1Tag};
+use system_error::SystemError;
+
+use crate::{
+    arch::mm::x86_64_set_kernel_load_base_paddr,
+    driver::{
+        serial::serial8250::send_to_default_serial8250_port,
+        video::fbdev::{
+            base::{BootTimeScreenInfo, BootTimeVideoType},
+            vesafb::vesafb_early_map,
+        },
+    },
+    init::{
+        boot::{register_boot_callbacks, BootCallbacks, BootloaderAcpiArg},
+        boot_params,
+    },
+    libs::lazy_init::Lazy,
+    mm::{memblock::mem_block_manager, PhysAddr},
+};
+
+pub(super) const MULTIBOOT2_ENTRY_MAGIC: u32 = multiboot2::MAGIC;
+static MB2_INFO: Lazy<BootInformation> = Lazy::new();
+const MB2_RAW_INFO_MAX_SIZE: usize = 4096;
+
+static mut MB2_RAW_INFO: [u8; MB2_RAW_INFO_MAX_SIZE] = [0u8; MB2_RAW_INFO_MAX_SIZE];
+
+fn mb2_rsdp_v1_tag_to_rsdp_struct(tag: &RsdpV1Tag) -> Rsdp {
+    Rsdp {
+        signature: tag.signature,
+        checksum: tag.checksum,
+        oem_id: tag.oem_id,
+        revision: tag.revision,
+        rsdt_address: tag.rsdt_address,
+        length: 0,
+        xsdt_address: 0,
+        ext_checksum: 0,
+        reserved: [0u8; 3],
+    }
+}
+
+fn mb2_rsdp_v2_tag_to_rsdp_struct(tag: &multiboot2::RsdpV2Tag) -> Rsdp {
+    Rsdp {
+        signature: tag.signature,
+        checksum: tag.checksum,
+        oem_id: tag.oem_id,
+        revision: tag.revision,
+        rsdt_address: tag.rsdt_address,
+        length: tag.length,
+        xsdt_address: tag.xsdt_address,
+        ext_checksum: tag.ext_checksum,
+        reserved: tag._reserved,
+    }
+}
+struct Mb2Callback;
+
+impl BootCallbacks for Mb2Callback {
+    fn init_bootloader_name(&self) -> Result<Option<String>, SystemError> {
+        let name = MB2_INFO
+            .get()
+            .boot_loader_name_tag()
+            .expect("MB2: Bootloader name tag not found!")
+            .name()
+            .expect("Failed to parse bootloader name!")
+            .to_string();
+        Ok(Some(name))
+    }
+
+    fn init_acpi_args(&self) -> Result<BootloaderAcpiArg, SystemError> {
+        if let Some(v1_tag) = MB2_INFO.get().rsdp_v1_tag() {
+            Ok(BootloaderAcpiArg::Rsdt(mb2_rsdp_v1_tag_to_rsdp_struct(
+                v1_tag,
+            )))
+        } else if let Some(v2_tag) = MB2_INFO.get().rsdp_v2_tag() {
+            Ok(BootloaderAcpiArg::Xsdt(mb2_rsdp_v2_tag_to_rsdp_struct(
+                v2_tag,
+            )))
+        } else {
+            Ok(BootloaderAcpiArg::NotProvided)
+        }
+    }
+
+    fn init_kernel_cmdline(&self) -> Result<(), SystemError> {
+        let cmdline = MB2_INFO
+            .get()
+            .command_line_tag()
+            .expect("Mb2: Command line tag not found!")
+            .cmdline()
+            .expect("Mb2: Failed to parse command line!");
+        boot_params()
+            .write_irqsave()
+            .boot_cmdline_append(cmdline.as_bytes());
+        Ok(())
+    }
+
+    fn early_init_framebuffer_info(
+        &self,
+        scinfo: &mut BootTimeScreenInfo,
+    ) -> Result<(), SystemError> {
+        let Some(Ok(fb_tag)) = MB2_INFO.get().framebuffer_tag() else {
+            return Err(SystemError::ENODEV);
+        };
+        let width = fb_tag.width();
+        let height = fb_tag.height();
+        scinfo.is_vga = true;
+        scinfo.lfb_base = PhysAddr::new(fb_tag.address() as usize);
+
+        let fb_type = fb_tag.buffer_type().unwrap();
+        match fb_type {
+            multiboot2::FramebufferType::Indexed { palette: _ } => todo!(),
+            multiboot2::FramebufferType::RGB { red, green, blue } => {
+                scinfo.lfb_width = width;
+                scinfo.lfb_height = height;
+                scinfo.video_type = BootTimeVideoType::Vlfb;
+                scinfo.lfb_depth = fb_tag.bpp();
+                scinfo.red_pos = red.position;
+                scinfo.red_size = red.size;
+                scinfo.green_pos = green.position;
+                scinfo.green_size = green.size;
+                scinfo.blue_pos = blue.position;
+                scinfo.blue_size = blue.size;
+            }
+            multiboot2::FramebufferType::Text => {
+                scinfo.origin_video_cols = width as u8;
+                scinfo.origin_video_lines = height as u8;
+                scinfo.video_type = BootTimeVideoType::Mda;
+                scinfo.lfb_depth = 8;
+            }
+        };
+
+        scinfo.lfb_size = (width * height * ((fb_tag.bpp() as u32 + 7) / 8)) as usize;
+
+        scinfo.lfb_virt_base = Some(vesafb_early_map(scinfo.lfb_base, scinfo.lfb_size)?);
+
+        return Ok(());
+    }
+
+    fn early_init_memory_blocks(&self) -> Result<(), SystemError> {
+        let mb2_info = MB2_INFO.get();
+        send_to_default_serial8250_port("init_memory_area_from_multiboot2\n\0".as_bytes());
+
+        let mem_regions_tag = mb2_info
+            .memory_map_tag()
+            .expect("MB2: Memory map tag not found!");
+        let mut total_mem_size = 0usize;
+        let mut usable_mem_size = 0usize;
+        for region in mem_regions_tag.memory_areas() {
+            let start = PhysAddr::new(region.start_address() as usize);
+            let size = region.size() as usize;
+            let area_typ = MemoryAreaType::from(region.typ());
+            total_mem_size += size;
+
+            match area_typ {
+                MemoryAreaType::Available => {
+                    usable_mem_size += size;
+                    mem_block_manager()
+                        .add_block(start, size)
+                        .unwrap_or_else(|e| {
+                            log::warn!(
+                                "Failed to add memory block: base={:?}, size={:#x}, error={:?}",
+                                start,
+                                size,
+                                e
+                            );
+                        });
+                }
+
+                _ => {
+                    mem_block_manager()
+                        .reserve_block(start, size)
+                        .unwrap_or_else(|e| {
+                            log::warn!(
+                                "Failed to reserve memory block: base={:?}, size={:#x}, error={:?}",
+                                start,
+                                size,
+                                e
+                            );
+                        });
+                }
+            }
+        }
+        send_to_default_serial8250_port("init_memory_area_from_multiboot2 end\n\0".as_bytes());
+        log::info!(
+            "Total memory size: {:#x}, Usable memory size: {:#x}",
+            total_mem_size,
+            usable_mem_size
+        );
+
+        // Add the boot module region since Grub does not specify it.
+        let mb2_module_tag = mb2_info.module_tags();
+        for module in mb2_module_tag {
+            let start = PhysAddr::new(module.start_address() as usize);
+            let size = module.module_size() as usize;
+            mem_block_manager()
+                .reserve_block(start, size)
+                .unwrap_or_else(|e| {
+                    log::warn!(
+                        "Failed to reserve memory block for mb2 modules: base={:?}, size={:#x}, error={:?}",
+                        start,
+                        size,
+                        e
+                    );
+                });
+        }
+
+        // setup kernel load base
+        self.setup_kernel_load_base();
+
+        Ok(())
+    }
+}
+
+impl Mb2Callback {
+    fn setup_kernel_load_base(&self) {
+        let mb2_info = MB2_INFO.get();
+        let kernel_start = mb2_info
+            .load_base_addr_tag()
+            .expect("MB2: Load base address tag not found!")
+            .load_base_addr();
+        let loadbase = PhysAddr::new(kernel_start as usize);
+        x86_64_set_kernel_load_base_paddr(loadbase);
+    }
+}
+pub(super) fn early_multiboot2_init(boot_magic: u32, boot_info: u64) -> Result<(), SystemError> {
+    assert_eq!(boot_magic, MULTIBOOT2_ENTRY_MAGIC);
+    let bi_ptr = boot_info as usize as *const BootInformationHeader;
+    let bi_size = unsafe { (*bi_ptr).total_size() as usize };
+    assert!(bi_size <= MB2_RAW_INFO_MAX_SIZE);
+    unsafe {
+        core::ptr::copy_nonoverlapping(bi_ptr as *const u8, MB2_RAW_INFO.as_mut_ptr(), bi_size);
+    }
+
+    let boot_info =
+        unsafe { BootInformation::load(MB2_RAW_INFO.as_mut_ptr() as *const BootInformationHeader) }
+            .inspect_err(|_| loop {
+                spin_loop();
+            })
+            .unwrap();
+
+    MB2_INFO.init(boot_info);
+
+    register_boot_callbacks(&Mb2Callback);
+
+    return Ok(());
+}

+ 1 - 0
kernel/src/arch/x86_64/link.lds

@@ -13,6 +13,7 @@ SECTIONS
 	.boot.text :
 	{
 		KEEP(*(.multiboot_header))
+		KEEP(*(.multiboot2_header))
 		*(.bootstrap)
 		*(.bootstrap.code64)
 		*(.bootstrap.data)

+ 17 - 81
kernel/src/arch/x86_64/mm/mod.rs

@@ -6,15 +6,13 @@ pub mod pkru;
 use alloc::sync::Arc;
 use alloc::vec::Vec;
 use hashbrown::HashSet;
-use log::{debug, info, warn};
+use log::{debug, info};
 use x86::time::rdtsc;
 use x86_64::registers::model_specific::EferFlags;
 
 use crate::driver::serial::serial8250::send_to_default_serial8250_port;
-use crate::include::bindings::bindings::{
-    multiboot2_get_load_base, multiboot2_get_memory, multiboot2_iter, multiboot_mmap_entry_t,
-    multiboot_tag_load_base_addr_t,
-};
+
+use crate::init::boot::boot_callbacks;
 use crate::libs::align::page_align_up;
 use crate::libs::lib_ui::screen_manager::scm_disable_put_to_window;
 use crate::libs::spinlock::SpinLock;
@@ -34,9 +32,7 @@ use crate::mm::{MemoryManagementArch, PageTableKind, PhysAddr, VirtAddr, VmFlags
 use system_error::SystemError;
 
 use core::arch::asm;
-use core::ffi::c_void;
 use core::fmt::Debug;
-use core::mem::{self};
 
 use core::sync::atomic::{compiler_fence, AtomicBool, Ordering};
 
@@ -63,6 +59,12 @@ pub struct X86_64MMBootstrapInfo {
 
 pub(super) static mut BOOTSTRAP_MM_INFO: Option<X86_64MMBootstrapInfo> = None;
 
+pub(super) fn x86_64_set_kernel_load_base_paddr(paddr: PhysAddr) {
+    unsafe {
+        BOOTSTRAP_MM_INFO.as_mut().unwrap().kernel_load_base_paddr = paddr.data();
+    }
+}
+
 /// @brief X86_64的内存管理架构结构体
 #[derive(Debug, Clone, Copy, Hash)]
 pub struct X86_64MMArch;
@@ -125,8 +127,8 @@ impl MemoryManagementArch for X86_64MMArch {
     const USER_STACK_START: VirtAddr = VirtAddr::new(0x6ffff0a00000);
 
     const FIXMAP_START_VADDR: VirtAddr = VirtAddr::new(0xffffb00000000000);
-    /// 设置FIXMAP区域大小为1M
-    const FIXMAP_SIZE: usize = 256 * 4096;
+    /// 设置FIXMAP区域大小为16M
+    const FIXMAP_SIZE: usize = 256 * 4096 * 16;
 
     const MMIO_BASE: VirtAddr = VirtAddr::new(0xffffa10000000000);
     const MMIO_SIZE: usize = 1 << PAGE_1G_SHIFT;
@@ -142,10 +144,9 @@ impl MemoryManagementArch for X86_64MMArch {
         }
 
         Self::init_xd_rsvd();
-        let load_base_paddr = Self::get_load_base_paddr();
 
         let bootstrap_info = X86_64MMBootstrapInfo {
-            kernel_load_base_paddr: load_base_paddr.data(),
+            kernel_load_base_paddr: 0,
             kernel_code_start: _text as usize,
             kernel_code_end: _etext as usize,
             kernel_data_end: _edata as usize,
@@ -157,8 +158,10 @@ impl MemoryManagementArch for X86_64MMArch {
             BOOTSTRAP_MM_INFO = Some(bootstrap_info);
         }
 
-        // 初始化物理内存区域(从multiboot2中获取)
-        Self::init_memory_area_from_multiboot2().expect("init memory area failed");
+        // 初始化物理内存区域
+        boot_callbacks()
+            .early_init_memory_blocks()
+            .expect("init memory area failed");
 
         debug!("bootstrap info: {:?}", unsafe { BOOTSTRAP_MM_INFO });
         debug!("phys[0]=virt[0x{:x}]", unsafe {
@@ -168,7 +171,7 @@ impl MemoryManagementArch for X86_64MMArch {
         // 初始化内存管理器
         unsafe { allocator_init() };
 
-        send_to_default_serial8250_port("x86 64 init done\n\0".as_bytes());
+        send_to_default_serial8250_port("x86 64 mm init done\n\0".as_bytes());
     }
 
     /// @brief 刷新TLB中,关于指定虚拟地址的条目
@@ -416,73 +419,6 @@ const fn protection_map() -> [EntryFlags<MMArch>; 16] {
 }
 
 impl X86_64MMArch {
-    unsafe fn get_load_base_paddr() -> PhysAddr {
-        let mut mb2_lb_info: [multiboot_tag_load_base_addr_t; 512] = mem::zeroed();
-        send_to_default_serial8250_port("get_load_base_paddr begin\n\0".as_bytes());
-
-        let mut mb2_count: u32 = 0;
-        multiboot2_iter(
-            Some(multiboot2_get_load_base),
-            &mut mb2_lb_info as *mut [multiboot_tag_load_base_addr_t; 512] as usize as *mut c_void,
-            &mut mb2_count,
-        );
-
-        if mb2_count == 0 {
-            send_to_default_serial8250_port(
-                "get_load_base_paddr mb2_count == 0, default to 1MB\n\0".as_bytes(),
-            );
-            return PhysAddr::new(0x100000);
-        }
-
-        let phys = mb2_lb_info[0].load_base_addr as usize;
-
-        return PhysAddr::new(phys);
-    }
-    unsafe fn init_memory_area_from_multiboot2() -> Result<usize, SystemError> {
-        // 这个数组用来存放内存区域的信息(从C获取)
-        let mut mb2_mem_info: [multiboot_mmap_entry_t; 512] = mem::zeroed();
-        send_to_default_serial8250_port("init_memory_area_from_multiboot2 begin\n\0".as_bytes());
-
-        let mut mb2_count: u32 = 0;
-        multiboot2_iter(
-            Some(multiboot2_get_memory),
-            &mut mb2_mem_info as *mut [multiboot_mmap_entry_t; 512] as usize as *mut c_void,
-            &mut mb2_count,
-        );
-        send_to_default_serial8250_port("init_memory_area_from_multiboot2 2\n\0".as_bytes());
-
-        let mb2_count = mb2_count as usize;
-        let mut areas_count = 0usize;
-        let mut total_mem_size = 0usize;
-        for info_entry in mb2_mem_info.iter().take(mb2_count) {
-            // Only use the memory area if its type is 1 (RAM)
-            if info_entry.type_ == 1 {
-                // Skip the memory area if its len is 0
-                if info_entry.len == 0 {
-                    continue;
-                }
-
-                total_mem_size += info_entry.len as usize;
-
-                mem_block_manager()
-                    .add_block(
-                        PhysAddr::new(info_entry.addr as usize),
-                        info_entry.len as usize,
-                    )
-                    .unwrap_or_else(|e| {
-                        warn!(
-                            "Failed to add memory block: base={:#x}, size={:#x}, error={:?}",
-                            info_entry.addr, info_entry.len, e
-                        );
-                    });
-                areas_count += 1;
-            }
-        }
-        send_to_default_serial8250_port("init_memory_area_from_multiboot2 end\n\0".as_bytes());
-        info!("Total memory size: {} MB, total areas from multiboot2: {mb2_count}, valid areas: {areas_count}", total_mem_size / 1024 / 1024);
-        return Ok(areas_count);
-    }
-
     fn init_xd_rsvd() {
         // 读取ia32-EFER寄存器的值
         let efer: EferFlags = x86_64::registers::model_specific::Efer::read();

+ 8 - 8
kernel/src/arch/x86_64/pci/pci.rs

@@ -1,4 +1,5 @@
-use crate::arch::TraitPciArch;
+use crate::arch::io::PortIOArch;
+use crate::arch::{CurrentPortIOArch, TraitPciArch};
 use crate::driver::acpi::acpi_manager;
 use crate::driver::pci::ecam::{pci_ecam_root_info_manager, EcamRootInfo};
 use crate::driver::pci::pci::{
@@ -6,7 +7,6 @@ use crate::driver::pci::pci::{
     PORT_PCI_CONFIG_DATA,
 };
 use crate::driver::pci::root::{pci_root_manager, PciRoot};
-use crate::include::bindings::bindings::{io_in32, io_in8, io_out32};
 use crate::init::initcall::INITCALL_SUBSYS;
 use crate::mm::PhysAddr;
 
@@ -22,7 +22,7 @@ impl X86_64PciArch {
     /// 参考:https://code.dragonos.org.cn/xref/linux-6.6.21/arch/x86/pci/early.c?fi=read_pci_config_byte#19
     fn read_config_early(bus: u8, slot: u8, func: u8, offset: u8) -> u8 {
         unsafe {
-            io_out32(
+            CurrentPortIOArch::out32(
                 PORT_PCI_CONFIG_ADDRESS,
                 0x80000000
                     | ((bus as u32) << 16)
@@ -31,7 +31,7 @@ impl X86_64PciArch {
                     | offset as u32,
             );
         }
-        let value = unsafe { io_in8(PORT_PCI_CONFIG_DATA + (offset & 3) as u16) };
+        let value = unsafe { CurrentPortIOArch::in8(PORT_PCI_CONFIG_DATA + (offset & 3) as u16) };
         return value;
     }
 }
@@ -45,8 +45,8 @@ impl TraitPciArch for X86_64PciArch {
             | (offset & 0xfc) as u32
             | (0x80000000);
         let ret = unsafe {
-            io_out32(PORT_PCI_CONFIG_ADDRESS, address);
-            let temp = io_in32(PORT_PCI_CONFIG_DATA);
+            CurrentPortIOArch::out32(PORT_PCI_CONFIG_ADDRESS, address);
+            let temp = CurrentPortIOArch::in32(PORT_PCI_CONFIG_DATA);
             temp
         };
         return ret;
@@ -59,9 +59,9 @@ impl TraitPciArch for X86_64PciArch {
             | (offset & 0xfc) as u32
             | (0x80000000);
         unsafe {
-            io_out32(PORT_PCI_CONFIG_ADDRESS, address);
+            CurrentPortIOArch::out32(PORT_PCI_CONFIG_ADDRESS, address);
             // 写入数据
-            io_out32(PORT_PCI_CONFIG_DATA, data);
+            CurrentPortIOArch::out32(PORT_PCI_CONFIG_DATA, data);
         }
     }
 

+ 1 - 1
kernel/src/driver/Makefile

@@ -1,7 +1,7 @@
 
 CFLAGS += -I .
 
-kernel_driver_subdirs:=acpi multiboot2 
+kernel_driver_subdirs:= 
 
 ECHO:
 	@echo "$@"

+ 0 - 10
kernel/src/driver/acpi/Makefile

@@ -1,10 +0,0 @@
-SRC = $(wildcard *.c)
-OBJ = $(SRC:.c=.o)
-CFLAGS += -I .
-
-.PHONY: all
-
-all: $(OBJ)
-
-%.o: %.c
-	$(CC) $(CFLAGS) -c $< -o $@

+ 0 - 35
kernel/src/driver/acpi/acpi.c

@@ -1,35 +0,0 @@
-#include "acpi.h"
-#include <common/kprint.h>
-#include <driver/multiboot2/multiboot2.h>
-
-extern void rs_acpi_init(uint64_t rsdp_paddr1, uint64_t rsdp_paddr2);
-
-static struct acpi_RSDP_t *rsdpv1;
-static struct acpi_RSDP_2_t *rsdpv2;
-
-static struct multiboot_tag_old_acpi_t old_acpi;
-static struct multiboot_tag_new_acpi_t new_acpi;
-
-/**
- * @brief 初始化acpi模块
- *
- */
-void acpi_init()
-{
-    kinfo("Initializing ACPI...");
-
-    // 获取物理地址
-    int reserved;
-
-    multiboot2_iter(multiboot2_get_acpi_old_RSDP, &old_acpi, &reserved);
-    rsdpv1 = &(old_acpi.rsdp);
-
-    multiboot2_iter(multiboot2_get_acpi_new_RSDP, &new_acpi, &reserved);
-    rsdpv2 = &(new_acpi.rsdp);
-
-    // rsdpv1、rsdpv2,二者有一个能成功即可
-    rs_acpi_init((uint64_t)rsdpv1, (uint64_t)rsdpv2);
-
-    kinfo("ACPI module initialized!");
-    return;
-}

+ 0 - 37
kernel/src/driver/acpi/acpi.h

@@ -1,37 +0,0 @@
-/**
- * 解析acpi信息的模块
- **/
-
-#pragma once
-
-#include <common/glib.h>
-#include <mm/mm.h>
-
-struct acpi_RSDP_t
-{
-    unsigned char Signature[8];
-    unsigned char Checksum;
-    unsigned char OEMID[6];
-
-    unsigned char Revision;
-
-    // 32bit physical address of the RSDT
-    uint RsdtAddress;
-} __attribute__((packed));
-
-struct acpi_RSDP_2_t
-{
-    struct acpi_RSDP_t rsdp1;
-
-    // fields below are only valid when the revision value is 2 or above
-    // 表的长度(单位:字节)从offset=0开始算
-    uint Length;
-    // 64bit的XSDT的物理地址
-    ul XsdtAddress;
-    unsigned char ExtendedChecksum; // 整个表的checksum,包括了之前的checksum区域
-
-    unsigned char Reserved[3];
-} __attribute__((packed));
-
-// 初始化acpi模块
-void acpi_init();

+ 0 - 8
kernel/src/driver/acpi/c_adapter.rs

@@ -1,8 +0,0 @@
-use super::acpi_manager;
-
-#[no_mangle]
-unsafe extern "C" fn rs_acpi_init(rsdp_vaddr1: u64, rsdp_vaddr2: u64) {
-    acpi_manager()
-        .init(rsdp_vaddr1, rsdp_vaddr2)
-        .expect("rs_acpi_init(): failed to init acpi");
-}

+ 51 - 32
kernel/src/driver/acpi/mod.rs

@@ -1,4 +1,4 @@
-use core::{fmt::Debug, hint::spin_loop, ptr::NonNull};
+use core::{fmt::Debug, ptr::NonNull};
 
 use acpi::{AcpiHandler, AcpiTables, PlatformInfo};
 use alloc::{string::ToString, sync::Arc};
@@ -7,6 +7,7 @@ use log::{error, info};
 use crate::{
     arch::MMArch,
     driver::base::firmware::sys_firmware_kset,
+    init::{boot::BootloaderAcpiArg, boot_params},
     libs::align::{page_align_down, page_align_up, AlignedBox},
     mm::{
         mmio_buddy::{mmio_pool, MMIOSpaceGuard},
@@ -20,7 +21,6 @@ use super::base::kset::KSet;
 extern crate acpi;
 
 pub mod bus;
-mod c_adapter;
 pub mod glue;
 pub mod pmtmr;
 mod sysfs;
@@ -56,7 +56,7 @@ impl AcpiManager {
     /// ## 参考资料
     ///
     /// https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/acpi/bus.c#1390
-    pub fn init(&self, rsdp_vaddr1: u64, rsdp_vaddr2: u64) -> Result<(), SystemError> {
+    fn init(&self) -> Result<(), SystemError> {
         info!("Initializing Acpi Manager...");
 
         // 初始化`/sys/firmware/acpi`的kset
@@ -65,45 +65,45 @@ impl AcpiManager {
         unsafe {
             ACPI_KSET_INSTANCE = Some(kset.clone());
         }
-        self.map_tables(rsdp_vaddr1, rsdp_vaddr2)?;
+        let acpi_args = boot_params().read().acpi;
+        if let BootloaderAcpiArg::NotProvided = acpi_args {
+            error!("acpi_init(): ACPI not provided by bootloader");
+            return Err(SystemError::ENODEV);
+        }
+
+        self.map_tables(acpi_args)?;
         self.bus_init()?;
         info!("Acpi Manager initialized.");
         return Ok(());
     }
 
-    fn map_tables(&self, rsdp_vaddr1: u64, rsdp_vaddr2: u64) -> Result<(), SystemError> {
-        let rsdp_paddr1 = Self::rsdp_paddr(rsdp_vaddr1);
-        let res1 = unsafe { acpi::AcpiTables::from_rsdp(AcpiHandlerImpl, rsdp_paddr1.data()) };
-        let e1;
-        match res1 {
-            // 如果rsdpv1能够获取到acpi_table,则就用该表,不用rsdpv2了
+    fn map_tables(&self, acpi_args: BootloaderAcpiArg) -> Result<(), SystemError> {
+        let table_paddr: PhysAddr = match acpi_args {
+            BootloaderAcpiArg::Rsdt(rsdpv1) => Self::rsdp_paddr(&rsdpv1),
+            BootloaderAcpiArg::Xsdt(rsdpv2) => Self::rsdp_paddr(&rsdpv2),
+            _ => {
+                error!(
+                    "AcpiManager::map_tables(): unsupported acpi_args: {:?}",
+                    acpi_args
+                );
+                return Err(SystemError::ENODEV);
+            }
+        };
+        let res = unsafe { acpi::AcpiTables::from_rsdp(AcpiHandlerImpl, table_paddr.data()) };
+        match res {
             Ok(acpi_table) => {
                 Self::set_acpi_table(acpi_table);
                 return Ok(());
             }
             Err(e) => {
-                e1 = e;
-                Self::drop_rsdp_tmp_box();
-            }
-        }
-
-        let rsdp_paddr2 = Self::rsdp_paddr(rsdp_vaddr2);
-        let res2 = unsafe { acpi::AcpiTables::from_rsdp(AcpiHandlerImpl, rsdp_paddr2.data()) };
-        match res2 {
-            Ok(acpi_table) => {
-                Self::set_acpi_table(acpi_table);
-            }
-            // 如果rsdpv1和rsdpv2都无法获取到acpi_table,说明有问题,打印报错信息后进入死循环
-            Err(e2) => {
-                error!("acpi_init(): failed to parse acpi tables, error: (rsdpv1: {:?}) or (rsdpv2: {:?})", e1, e2);
+                error!(
+                    "AcpiManager::map_tables(): failed to map tables, error: {:?}",
+                    e
+                );
                 Self::drop_rsdp_tmp_box();
-                loop {
-                    spin_loop();
-                }
+                return Err(SystemError::ENODEV);
             }
         }
-
-        return Ok(());
     }
 
     /// 通过RSDP虚拟地址获取RSDP物理地址
@@ -115,13 +115,18 @@ impl AcpiManager {
     /// ## 返回值
     ///
     /// RSDP物理地址
-    fn rsdp_paddr(rsdp_vaddr: u64) -> PhysAddr {
+    fn rsdp_paddr(rsdp_instance: &acpi::rsdp::Rsdp) -> PhysAddr {
         unsafe {
             RSDP_TMP_BOX = Some(AlignedBox::new_zeroed().expect("rs_acpi_init(): failed to alloc"))
         };
+
         let size = core::mem::size_of::<acpi::rsdp::Rsdp>();
-        let tmp_data =
-            unsafe { core::slice::from_raw_parts(rsdp_vaddr as usize as *const u8, size) };
+        let tmp_data = unsafe {
+            core::slice::from_raw_parts(
+                rsdp_instance as *const acpi::rsdp::Rsdp as usize as *const u8,
+                size,
+            )
+        };
         unsafe { RSDP_TMP_BOX.as_mut().unwrap()[0..size].copy_from_slice(tmp_data) };
         let rsdp_paddr = unsafe {
             MMArch::virt_2_phys(VirtAddr::new(
@@ -221,3 +226,17 @@ impl AcpiHandler for AcpiHandlerImpl {
         drop(mmio_guard);
     }
 }
+
+#[inline(never)]
+pub fn acpi_init() -> Result<(), SystemError> {
+    #[cfg(target_arch = "x86_64")]
+    {
+        acpi_manager().init()
+    }
+
+    #[cfg(not(target_arch = "x86_64"))]
+    {
+        log::warn!("acpi_init(): unsupported arch");
+        return Ok(());
+    }
+}

+ 0 - 10
kernel/src/driver/multiboot2/Makefile

@@ -1,10 +0,0 @@
-SRC = $(wildcard *.c)
-OBJ = $(SRC:.c=.o)
-CFLAGS += -I .
-
-.PHONY: all
-
-all: $(OBJ)
-
-%.o: %.c
-	$(CC) $(CFLAGS) -c $< -o $@

+ 0 - 165
kernel/src/driver/multiboot2/multiboot2.c

@@ -1,165 +0,0 @@
-#include "multiboot2.h"
-
-#include <common/glib.h>
-#include <common/kprint.h>
-// uintptr_t multiboot2_boot_info_addr;
-// unsigned int multiboot2_magic;
-unsigned int multiboot2_boot_info_size;
-
-#define MBI_RAW_MAX_SIZE 409600
-// 由于启动时传递的mb2 info所在的地址,在内存管理初始化之后会被覆盖,所以需要将其拷贝到一个固定的位置
-static uint8_t mbi_raw[MBI_RAW_MAX_SIZE] = {0};
-bool multiboot2_init(uint64_t mb2_info_paddr, uint32_t mb2_magic)
-{
-  uint64_t vaddr = (uint64_t)phys_2_virt(mb2_info_paddr);
-  if (mb2_magic != MULTIBOOT2_BOOTLOADER_MAGIC)
-    return false;
-  // vaddr+0 处保存了大小
-  multiboot2_boot_info_size = *(uint32_t *)vaddr;
-  if (multiboot2_boot_info_size > MBI_RAW_MAX_SIZE)
-    return false;
-
-  memcpy((void *)mbi_raw, (void *)vaddr, multiboot2_boot_info_size);
-  
-  return true;
-}
-
-void multiboot2_iter(bool (*_fun)(const struct iter_data_t *, void *, unsigned int *),
-                     void *data, unsigned int *count)
-{
-  // kdebug("multiboot2_boot_info_addr=%#018lx", multiboot2_boot_info_addr);
-
-  // uintptr_t addr = multiboot2_boot_info_addr;
-
-  // for(int i=0;i<8192;i++)
-  // {
-  //   mbi_raw[i] = ((uint8_t *)multiboot2_boot_info_addr)[i];
-  // }
-  uint8_t * addr = mbi_raw;
-  // 接下来的第8字节开始,为 tag 信息
-  struct iter_data_t *tag = (struct iter_data_t *)((void *)addr + 8);
-  for (; tag->type != MULTIBOOT_TAG_TYPE_END;
-       tag = (struct iter_data_t *)((uint8_t *)tag + ALIGN(tag->size, 8)))
-  {
-
-    if (_fun(tag, data, count) == true)
-    {
-      return;
-    }
-  }
-  return;
-}
-
-// 读取 grub2 传递的物理内存信息,保存到 e820map_t 结构体中
-// 一般而言是这样的
-// 地址(长度) 类型
-// 0x00(0x9F000) 0x1
-// 0x9F000(0x1000) 0x2
-// 0xE8000(0x18000) 0x2
-// 0x100000(0x7EF0000) 0x1
-// 0x7FF0000(0x10000) 0x3
-// 0xFFFC0000(0x40000) 0x2
-/**
- * @brief 获取multiboot2协议提供的内存区域信息
- *
- * @param _iter_data 要被迭代的信息的结构体
- * @param _data 返回信息的结构体指针
- * @param count 返回数组的长度
- * @return true
- * @return false
- */
-bool multiboot2_get_memory(const struct iter_data_t *_iter_data, void *data, unsigned int *count)
-{
-  if (_iter_data->type != MULTIBOOT_TAG_TYPE_MMAP)
-    return false;
-
-  struct multiboot_mmap_entry_t *resource = (struct multiboot_mmap_entry_t *)data;
-  struct multiboot_mmap_entry_t *mmap = ((struct multiboot_tag_mmap_t *)_iter_data)->entries;
-  *count = 0;
-  for (; (uint8_t *)mmap < (uint8_t *)_iter_data + _iter_data->size;
-       mmap = (struct multiboot_mmap_entry_t *)((uint8_t *)mmap + ((struct multiboot_tag_mmap_t *)_iter_data)->entry_size))
-  {
-    *resource = *mmap;
-    // 将指针进行增加
-    resource = (struct multiboot_mmap_entry_t *)((uint8_t *)resource + ((struct multiboot_tag_mmap_t *)_iter_data)->entry_size);
-    ++(*count);
-  }
-  return true;
-}
-
-/**
- * @brief 获取VBE信息
- *
- * @param _iter_data 要被迭代的信息的结构体
- * @param _data 返回信息的结构体指针
- */
-bool multiboot2_get_VBE_info(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved)
-{
-
-  if (_iter_data->type != MULTIBOOT_TAG_TYPE_VBE)
-    return false;
-  *(struct multiboot_tag_vbe_t *)data = *(struct multiboot_tag_vbe_t *)_iter_data;
-  return true;
-}
-
-/// @brief 获取加载基地址
-/// @param _iter_data 
-/// @param data 
-/// @param reserved 
-/// @return 
-bool multiboot2_get_load_base(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved)
-{
-
-  if (_iter_data->type != MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR)
-    return false;
-  *(struct multiboot_tag_load_base_addr_t *)data = *(struct multiboot_tag_load_base_addr_t *)_iter_data;
-  return true;
-}
-
-/**
- * @brief 获取帧缓冲区信息
- *
- * @param _iter_data 要被迭代的信息的结构体
- * @param _data 返回信息的结构体指针
- */
-bool multiboot2_get_Framebuffer_info(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved)
-{
-  if (_iter_data->type != MULTIBOOT_TAG_TYPE_FRAMEBUFFER)
-    return false;
-  *(struct multiboot_tag_framebuffer_info_t *)data = *(struct multiboot_tag_framebuffer_info_t *)_iter_data;
-  return true;
-}
-
-/**
- * @brief 获取acpi旧版RSDP
- *
- * @param _iter_data 要被迭代的信息的结构体
- * @param _data old RSDP的结构体指针
- * @param reserved
- * @return uint8_t*  struct multiboot_tag_old_acpi_t
- */
-bool multiboot2_get_acpi_old_RSDP(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved)
-{
-  if (_iter_data->type != MULTIBOOT_TAG_TYPE_ACPI_OLD)
-    return false;
-
-  *(struct multiboot_tag_old_acpi_t *)data = *(struct multiboot_tag_old_acpi_t *)_iter_data;
-
-  return true;
-}
-
-/**
- * @brief 获取acpi新版RSDP
- *
- * @param _iter_data 要被迭代的信息的结构体
- * @param _data old RSDP的结构体指针
- * @param reserved
- * @return uint8_t*  struct multiboot_tag_old_acpi_t
- */
-bool multiboot2_get_acpi_new_RSDP(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved)
-{
-  if (_iter_data->type != MULTIBOOT_TAG_TYPE_ACPI_NEW)
-    return false;
-  *(struct multiboot_tag_new_acpi_t *)data = *(struct multiboot_tag_new_acpi_t *)_iter_data;
-  return true;
-}

+ 0 - 473
kernel/src/driver/multiboot2/multiboot2.h

@@ -1,473 +0,0 @@
-/**
- * @file multiboot2.h
- * @brief multiboot2 解析
- */
-
-#pragma once
-
-#include <DragonOS/stdint.h>
-#include "stdbool.h"
-#include <common/boot_info.h>
-#include <driver/acpi/acpi.h>
-
-/// @see Multiboot2 Specification version 2.0.pdf
-// 启动后,在 32 位内核进入点,机器状态如下:
-//   1. CS 指向基地址为 0x00000000,限长为4G – 1的代码段描述符。
-//   2. DS,SS,ES,FS 和 GS 指向基地址为0x00000000,限长为4G –
-//   1的数据段描述符。
-//   3. A20 地址线已经打开。
-//   4. 页机制被禁止。
-//   5. 中断被禁止。
-//   6. EAX = 0x2BADB002
-//   7. 系统信息和启动信息块的线性地址保存在 EBX中(相当于一个指针)。
-//      以下即为这个信息块的结构
-
-/**
- * @brief MULTIBOOT2 接口抽象
- */
-
-/*  How many bytes from the start of the file we search for the header. */
-static const unsigned int MULTIBOOT_SEARCH = 32768;
-static const unsigned int MULTIBOOT_HEADER_ALIGN = 8;
-
-/*  The magic field should contain this. */
-static const unsigned int MULTIBOOT2_HEADER_MAGIC = 0xe85250d6;
-
-/*  This should be in %eax. */
-static const unsigned int MULTIBOOT2_BOOTLOADER_MAGIC = 0x36d76289;
-
-/*  Alignment of multiboot modules. */
-static const unsigned int MULTIBOOT_MOD_ALIGN = 0x00001000;
-
-/*  Alignment of the multiboot info structure. */
-static const unsigned int MULTIBOOT_INFO_ALIGN = 0x00000008;
-
-/*  Flags set in the 'flags' member of the multiboot header. */
-
-static const unsigned int MULTIBOOT_TAG_ALIGN = 8;
-static const unsigned int MULTIBOOT_TAG_TYPE_END = 0;
-static const unsigned int MULTIBOOT_TAG_TYPE_CMDLINE = 1;
-static const unsigned int MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME = 2;
-static const unsigned int MULTIBOOT_TAG_TYPE_MODULE = 3;
-static const unsigned int MULTIBOOT_TAG_TYPE_BASIC_MEMINFO = 4;
-static const unsigned int MULTIBOOT_TAG_TYPE_BOOTDEV = 5;
-static const unsigned int MULTIBOOT_TAG_TYPE_MMAP = 6;
-static const unsigned int MULTIBOOT_TAG_TYPE_VBE = 7;
-static const unsigned int MULTIBOOT_TAG_TYPE_FRAMEBUFFER = 8;
-static const unsigned int MULTIBOOT_TAG_TYPE_ELF_SECTIONS = 9;
-static const unsigned int MULTIBOOT_TAG_TYPE_APM = 10;
-static const unsigned int MULTIBOOT_TAG_TYPE_EFI32 = 11;
-static const unsigned int MULTIBOOT_TAG_TYPE_EFI64 = 12;
-static const unsigned int MULTIBOOT_TAG_TYPE_SMBIOS = 13;
-static const unsigned int MULTIBOOT_TAG_TYPE_ACPI_OLD = 14;
-static const unsigned int MULTIBOOT_TAG_TYPE_ACPI_NEW = 15;
-static const unsigned int MULTIBOOT_TAG_TYPE_NETWORK = 16;
-static const unsigned int MULTIBOOT_TAG_TYPE_EFI_MMAP = 17;
-static const unsigned int MULTIBOOT_TAG_TYPE_EFI_BS = 18;
-static const unsigned int MULTIBOOT_TAG_TYPE_EFI32_IH = 19;
-static const unsigned int MULTIBOOT_TAG_TYPE_EFI64_IH = 20;
-static const unsigned int MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR = 21;
-
-static const unsigned int MULTIBOOT_HEADER_TAG_END = 0;
-static const unsigned int MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST =
-    1;
-static const unsigned int MULTIBOOT_HEADER_TAG_ADDRESS = 2;
-static const unsigned int MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS = 3;
-static const unsigned int MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS = 4;
-static const unsigned int MULTIBOOT_HEADER_TAG_FRAMEBUFFER = 5;
-static const unsigned int MULTIBOOT_HEADER_TAG_MODULE_ALIGN = 6;
-static const unsigned int MULTIBOOT_HEADER_TAG_EFI_BS = 7;
-static const unsigned int MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI32 =
-    8;
-static const unsigned int MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64 =
-    9;
-static const unsigned int MULTIBOOT_HEADER_TAG_RELOCATABLE = 10;
-
-static const unsigned int MULTIBOOT_ARCHITECTURE_I386 = 0;
-static const unsigned int MULTIBOOT_ARCHITECTURE_MIPS32 = 4;
-static const unsigned int MULTIBOOT_HEADER_TAG_OPTIONAL = 1;
-
-static const unsigned int MULTIBOOT_LOAD_PREFERENCE_NONE = 0;
-static const unsigned int MULTIBOOT_LOAD_PREFERENCE_LOW = 1;
-static const unsigned int MULTIBOOT_LOAD_PREFERENCE_HIGH = 2;
-
-static const unsigned int MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED =
-    1;
-static const unsigned int MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED =
-    2;
-
-static const unsigned int MULTIBOOT_MEMORY_AVAILABLE = 1;
-static const unsigned int MULTIBOOT_MEMORY_RESERVED = 2;
-static const unsigned int MULTIBOOT_MEMORY_ACPI_RECLAIMABLE = 3;
-static const unsigned int MULTIBOOT_MEMORY_NVS = 4;
-static const unsigned int MULTIBOOT_MEMORY_BADRAM = 5;
-
-struct multiboot_header_t
-{
-    // Must be MULTIBOOT_MAGIC - see above.
-    unsigned int magic;
-    // ISA
-    unsigned int architecture;
-    // Total header length.
-    unsigned int header_length;
-    // The above fields plus this one must equal 0 mod 2^32.
-    unsigned int checksum;
-};
-
-struct multiboot_header_tag_t
-{
-    uint16_t type;
-    uint16_t flags;
-    unsigned int size;
-};
-struct multiboot_header_tag_information_request_t
-{
-    uint16_t type;
-    uint16_t flags;
-    unsigned int size;
-
-    unsigned int requests[0];
-};
-struct multiboot_header_tag_address_t
-{
-    uint16_t type;
-    uint16_t flags;
-    unsigned int size;
-
-    unsigned int header_addr;
-    unsigned int load_addr;
-    unsigned int load_end_addr;
-    unsigned int bss_end_addr;
-};
-
-struct multiboot_header_tag_entry_address_t
-{
-    uint16_t type;
-    uint16_t flags;
-    unsigned int size;
-
-    unsigned int entry_addr;
-};
-
-struct multiboot_header_tag_console_flags_t
-{
-    uint16_t type;
-    uint16_t flags;
-    unsigned int size;
-
-    unsigned int console_flags;
-};
-
-struct multiboot_header_tag_framebuffer_t
-{
-    uint16_t type;
-    uint16_t flags;
-    unsigned int size;
-
-    unsigned int width;
-    unsigned int height;
-    unsigned int depth;
-};
-
-struct multiboot_header_tag_module_align_t
-{
-    uint16_t type;
-    uint16_t flags;
-    unsigned int size;
-};
-
-struct multiboot_header_tag_relocatable_t
-{
-    uint16_t type;
-    uint16_t flags;
-    unsigned int size;
-
-    unsigned int min_addr;
-    unsigned int max_addr;
-    unsigned int align;
-    unsigned int preference;
-};
-
-struct multiboot_color_t
-{
-    uint8_t red;
-    uint8_t green;
-    uint8_t blue;
-};
-
-// multiboot2协议的内存区域信息
-struct multiboot_mmap_entry_t
-{
-    uint64_t addr;
-    uint64_t len;
-    unsigned int type;
-    unsigned int reserved;
-};
-
-struct multiboot_tag_t
-{
-    unsigned int type;
-    unsigned int size;
-};
-
-struct multiboot_tag_string_t
-{
-    struct multiboot_tag_t tag_t;
-    char string[0];
-};
-
-struct multiboot_tag_module_t
-{
-    struct multiboot_tag_t tag_t;
-    unsigned int mod_start;
-    unsigned int mod_end;
-    char cmdline[0];
-};
-
-struct multiboot_tag_basic_meminfo_t
-{
-    struct multiboot_tag_t tag_t;
-    unsigned int mem_lower;
-    unsigned int mem_upper;
-};
-
-struct multiboot_tag_bootdev_t
-{
-    struct multiboot_tag_t tag_t;
-    unsigned int biosdev;
-    unsigned int slice;
-    unsigned int part;
-};
-
-struct multiboot_tag_mmap_t
-{
-    struct multiboot_tag_t tag_t;
-    unsigned int entry_size;
-    unsigned int entry_version;
-    struct multiboot_mmap_entry_t entries[0];
-};
-
-struct multiboot_vbe_info_block_t
-{
-    uint8_t external_specification[512];
-};
-
-struct multiboot_vbe_mode_info_block_t
-{
-    uint8_t external_specification[256];
-};
-
-// bootloader传递的VBE信息的结构体
-struct multiboot_tag_vbe_t
-{
-    struct multiboot_tag_t tag_t;
-    uint16_t vbe_mode;
-    uint16_t vbe_interface_seg;
-    uint16_t vbe_interface_off;
-    uint16_t vbe_interface_len;
-
-    // The fields ‘vbe_control_info’ and ‘vbe_mode_info’ contain VBE control information returned by the VBE Function 00h and VBE mode information
-    // returned by the VBE Function 01h, respectively.
-    struct multiboot_vbe_info_block_t vbe_control_info;
-    struct multiboot_vbe_mode_info_block_t vbe_mode_info;
-};
-
-struct multiboot_tag_framebuffer_info_t
-{
-    struct multiboot_tag_t tag_t;
-    uint64_t framebuffer_addr;
-    uint32_t framebuffer_pitch; // 帧缓存上界
-    // width and height expressed in pixels except type=2
-    // when type=2, they are expressed in characters
-    uint32_t framebuffer_width;
-    uint32_t framebuffer_height;
-    // number of bits per pixel.
-    uint8_t framebuffer_bpp;
-    // 帧缓存的类型
-    uint8_t framebuffer_type;
-    uint8_t reserved;
-};
-
-// indexed color
-struct multiboot_tag_framebuffer_info_type0_t
-{
-    struct multiboot_tag_framebuffer_info_t header;
-    uint32_t framebuffer_palette_num_colors;
-    struct multiboot_color_t color_desc;
-};
-
-// direct RGB color
-struct multiboot_tag_framebuffer_info_type1_t
-{
-    struct multiboot_tag_framebuffer_info_t header;
-
-    uint8_t framebuffer_red_field_position;
-    uint8_t framebuffer_red_mask_size;
-    uint8_t framebuffer_green_field_position;
-    uint8_t framebuffer_green_mask_size;
-    uint8_t framebuffer_blue_field_position;
-    uint8_t framebuffer_blue_mask_size;
-};
-
-struct multiboot_tag_elf_sections_t
-{
-    struct multiboot_tag_t tag_t;
-    unsigned int num;
-    unsigned int entsize;
-    // 段字符串表索引
-    unsigned int shndx;
-    char sections[0];
-};
-
-struct multiboot_tag_apm_t
-{
-    struct multiboot_tag_t tag_t;
-    uint16_t version;
-    uint16_t cseg;
-    unsigned int offset;
-    uint16_t cseg_16;
-    uint16_t dseg;
-    uint16_t flags;
-    uint16_t cseg_len;
-    uint16_t cseg_16_len;
-    uint16_t dseg_len;
-};
-
-struct multiboot_tag_efi32_t
-{
-    struct multiboot_tag_t tag_t;
-    unsigned int pointer;
-};
-
-struct multiboot_tag_efi64_t
-{
-    struct multiboot_tag_t tag_t;
-    uint64_t pointer;
-};
-
-struct multiboot_tag_smbios_t
-{
-    struct multiboot_tag_t tag_t;
-    uint8_t major;
-    uint8_t minor;
-    uint8_t reserved[6];
-    uint8_t tables[0];
-};
-
-struct multiboot_tag_old_acpi_t
-{
-    struct multiboot_tag_t tag_t;
-    //uint8_t rsdp[0];
-    struct acpi_RSDP_t rsdp;
-};
-
-struct multiboot_tag_new_acpi_t
-{
-    struct multiboot_tag_t tag_t;
-    //uint8_t rsdp[0];
-    struct acpi_RSDP_2_t rsdp;
-};
-
-struct multiboot_tag_network_t
-{
-    struct multiboot_tag_t tag_t;
-    uint8_t dhcpack[0];
-};
-
-struct multiboot_tag_efi_mmap_t
-{
-    struct multiboot_tag_t tag_t;
-    unsigned int descr_size;
-    unsigned int descr_vers;
-    uint8_t efi_mmap[0];
-};
-
-struct multiboot_tag_efi32_ih_t
-{
-    struct multiboot_tag_t tag_t;
-    unsigned int pointer;
-};
-
-struct multiboot_tag_efi64_ih_t
-{
-    struct multiboot_tag_t tag_t;
-    uint64_t pointer;
-};
-
-struct multiboot_tag_load_base_addr_t
-{
-    struct multiboot_tag_t tag_t;
-    unsigned int load_base_addr;
-};
-
-// 迭代变量
-// 与 multiboot_tag_t 相同
-struct iter_data_t
-{
-    unsigned int type;
-    unsigned int size;
-};
-
-/**
- * @brief 初始化
- * @return true            成功
- * @return false           失败
- */
-bool multiboot2_init(uint64_t mb2_info_paddr, uint32_t mb2_magic);
-
-/**
- * @brief 迭代器
- * @param  _fun            迭代操作
- * @param  _data           数据
- */
-void multiboot2_iter(bool (*_fun)(const struct iter_data_t *, void *, unsigned int *),
-                     void *_data, unsigned int *count);
-
-/**
- * @brief 获取multiboot2协议提供的内存区域信息
- *
- * @param _iter_data 要被迭代的信息的结构体
- * @param _data 返回信息的结构体指针
- * @param count 返回数组的长度
- * @return true
- * @return false
- */
-bool multiboot2_get_memory(const struct iter_data_t *_iter_data, void *_data, unsigned int *count);
-
-bool multiboot2_get_load_base(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved);
-
-/**
- * @brief 获取VBE信息
- *
- * @param _iter_data 要被迭代的信息的结构体
- * @param _data 返回信息的结构体指针
- */
-bool multiboot2_get_VBE_info(const struct iter_data_t *_iter_data, void *_data, unsigned int *reserved);
-
-/**
- * @brief 获取帧缓冲区信息
- *
- * @param _iter_data 要被迭代的信息的结构体
- * @param _data 返回信息的结构体指针
- */
-bool multiboot2_get_Framebuffer_info(const struct iter_data_t *_iter_data, void *_data, unsigned int *reserved);
-
-/**
- * @brief 获取acpi旧版RSDP
- *
- * @param _iter_data 要被迭代的信息的结构体
- * @param _data old RSDP的结构体指针
- * @param reserved
- * @return uint8_t*
- */
-bool multiboot2_get_acpi_old_RSDP(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved);
-
-/**
- * @brief 获取acpi新版RSDP
- *
- * @param _iter_data 要被迭代的信息的结构体
- * @param _data old RSDP的结构体指针
- * @param reserved
- * @return uint8_t*  struct multiboot_tag_old_acpi_t
- */
-bool multiboot2_get_acpi_new_RSDP(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved);

+ 11 - 74
kernel/src/driver/video/fbdev/vesafb.rs

@@ -1,8 +1,4 @@
-use core::{
-    ffi::{c_uint, c_void},
-    mem::MaybeUninit,
-    sync::atomic::AtomicBool,
-};
+use core::sync::atomic::AtomicBool;
 
 use alloc::{
     string::{String, ToString},
@@ -14,7 +10,6 @@ use system_error::SystemError;
 use unified_init::macros::unified_init;
 
 use crate::{
-    arch::MMArch,
     driver::{
         base::{
             class::Class,
@@ -36,21 +31,13 @@ use crate::{
         sysfs::{file::sysfs_emit_str, Attribute, AttributeGroup, SysFSOpsSupport},
         vfs::syscall::ModeType,
     },
-    include::bindings::bindings::{
-        multiboot2_get_Framebuffer_info, multiboot2_iter, multiboot_tag_framebuffer_info_t,
-        FRAME_BUFFER_MAPPING_OFFSET,
-    },
-    init::{boot_params, initcall::INITCALL_DEVICE},
+    init::{boot::boot_callbacks, boot_params, initcall::INITCALL_DEVICE},
     libs::{
-        align::page_align_up,
         once::Once,
         rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard},
         spinlock::SpinLock,
     },
-    mm::{
-        allocator::page_frame::PageFrameCount, no_init::pseudo_map_phys, MemoryManagementArch,
-        PhysAddr, VirtAddr,
-    },
+    mm::{early_ioremap::EarlyIoRemap, PhysAddr, VirtAddr},
 };
 
 use super::base::{
@@ -933,68 +920,18 @@ pub fn vesa_fb_driver_init() -> Result<(), SystemError> {
 }
 
 /// 在内存管理初始化之前,初始化vesafb
-pub fn vesafb_early_init() -> Result<VirtAddr, SystemError> {
-    let mut _reserved: u32 = 0;
-
-    let mut fb_info: MaybeUninit<multiboot_tag_framebuffer_info_t> = MaybeUninit::uninit();
-    //从multiboot2中读取帧缓冲区信息至fb_info
-
-    // todo: 换成rust的,并且检测是否成功获取
-    unsafe {
-        multiboot2_iter(
-            Some(multiboot2_get_Framebuffer_info),
-            fb_info.as_mut_ptr() as usize as *mut c_void,
-            &mut _reserved as *mut c_uint,
-        )
-    };
-    unsafe { fb_info.assume_init() };
-    let fb_info: multiboot_tag_framebuffer_info_t = unsafe { core::mem::transmute(fb_info) };
+pub fn vesafb_early_init() -> Result<(), SystemError> {
+    let mut boot_params_guard = boot_params().write();
+    boot_callbacks().early_init_framebuffer_info(&mut boot_params_guard.screen_info)?;
 
-    // todo: 判断是否有vesa帧缓冲区,这里暂时直接设置true
     HAS_VESA_FB.store(true, core::sync::atomic::Ordering::SeqCst);
 
-    let width = fb_info.framebuffer_width;
-    let height = fb_info.framebuffer_height;
+    return Ok(());
+}
+
+pub fn vesafb_early_map(paddr: PhysAddr, size: usize) -> Result<VirtAddr, SystemError> {
+    let (buf_vaddr, _) = EarlyIoRemap::map(paddr, size, false)?;
 
-    let mut boot_params_guard = boot_params().write();
-    let boottime_screen_info = &mut boot_params_guard.screen_info;
-
-    boottime_screen_info.is_vga = true;
-
-    boottime_screen_info.lfb_base = PhysAddr::new(fb_info.framebuffer_addr as usize);
-
-    if fb_info.framebuffer_type == 2 {
-        //当type=2时,width与height用字符数表示,故depth=8
-        boottime_screen_info.origin_video_cols = width as u8;
-        boottime_screen_info.origin_video_lines = height as u8;
-        boottime_screen_info.video_type = BootTimeVideoType::Mda;
-        boottime_screen_info.lfb_depth = 8;
-    } else {
-        //否则为图像模式,depth应参照帧缓冲区信息里面的每个像素的位数
-        boottime_screen_info.lfb_width = width;
-        boottime_screen_info.lfb_height = height;
-        boottime_screen_info.video_type = BootTimeVideoType::Vlfb;
-        boottime_screen_info.lfb_depth = fb_info.framebuffer_bpp as u8;
-    }
-
-    boottime_screen_info.lfb_size =
-        (width * height * ((fb_info.framebuffer_bpp as u32 + 7) / 8)) as usize;
-
-    // let buf_vaddr = VirtAddr::new(0xffff800003200000);
-    let buf_vaddr = VirtAddr::new(
-        crate::include::bindings::bindings::SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE as usize
-            + FRAME_BUFFER_MAPPING_OFFSET as usize,
-    );
-    boottime_screen_info.lfb_virt_base = Some(buf_vaddr);
-
-    let init_text = "Video driver to map.\n\0";
-    send_to_default_serial8250_port(init_text.as_bytes());
-
-    // 地址映射
-    let paddr = PhysAddr::new(fb_info.framebuffer_addr as usize);
-    let count =
-        PageFrameCount::new(page_align_up(boottime_screen_info.lfb_size) / MMArch::PAGE_SIZE);
-    unsafe { pseudo_map_phys(buf_vaddr, paddr, count) };
     return Ok(buf_vaddr);
 }
 

+ 19 - 33
kernel/src/driver/video/mod.rs

@@ -9,10 +9,7 @@ use crate::{
         rwlock::{RwLock, RwLockReadGuard},
         spinlock::SpinLock,
     },
-    mm::{
-        allocator::page_frame::PageFrameCount, kernel_mapper::KernelMapper, page::EntryFlags,
-        MemoryManagementArch,
-    },
+    mm::{mmio_buddy::mmio_pool, page::EntryFlags},
     time::timer::{Timer, TimerFunction},
 };
 use alloc::{boxed::Box, sync::Arc};
@@ -74,46 +71,33 @@ impl VideoRefreshManager {
     }
 
     /**
-     * @brief VBE帧缓存区的地址重新映射
-     * 将帧缓存区映射到地址SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE处
+     * VBE帧缓存区的地址重新映射
      */
     fn init_frame_buffer(&self) {
         info!("Re-mapping VBE frame buffer...");
-        let buf_vaddr = boot_params()
-            .read_irqsave()
-            .screen_info
-            .lfb_virt_base
-            .unwrap();
+        let mut bp = boot_params().write_irqsave();
+        let buf_size = bp.screen_info.lfb_size;
 
-        let mut frame_buffer_info_guard = self.device_buffer.write();
+        let mmio_guard = mmio_pool().create_mmio(page_align_up(buf_size)).unwrap();
+        let mmio_guard = Arc::new(mmio_guard);
+        let buf_vaddr = mmio_guard.vaddr();
+        bp.screen_info.lfb_virt_base = Some(buf_vaddr);
+
+        let mut frame_buffer_info_guard: crate::libs::rwlock::RwLockWriteGuard<ScmBufferInfo> =
+            self.device_buffer.write();
+        unsafe { frame_buffer_info_guard.set_device_buffer_mmio_guard(mmio_guard.clone()) };
         if let ScmBuffer::DeviceBuffer(vaddr) = &mut (frame_buffer_info_guard).buf {
             *vaddr = buf_vaddr;
         }
-
         // 地址映射
-        let mut paddr = boot_params().read().screen_info.lfb_base;
-        let count = PageFrameCount::new(
-            page_align_up(frame_buffer_info_guard.buf_size()) / MMArch::PAGE_SIZE,
-        );
+        let paddr = bp.screen_info.lfb_base;
         let page_flags: EntryFlags<MMArch> = EntryFlags::new().set_execute(true).set_write(true);
 
-        let mut kernel_mapper = KernelMapper::lock();
-        let mut kernel_mapper = kernel_mapper.as_mut();
-        assert!(kernel_mapper.is_some());
-        let mut vaddr = buf_vaddr;
         unsafe {
-            for _ in 0..count.data() {
-                let flusher = kernel_mapper
-                    .as_mut()
-                    .unwrap()
-                    .map_phys(vaddr, paddr, page_flags)
-                    .unwrap();
-
-                flusher.flush();
-                vaddr += MMArch::PAGE_SIZE;
-                paddr += MMArch::PAGE_SIZE;
-            }
-        }
+            mmio_guard
+                .map_phys_with_flags(paddr, page_align_up(buf_size), page_flags)
+                .expect("Failed to map VBE frame buffer!")
+        };
 
         info!("VBE frame buffer successfully Re-mapped!");
     }
@@ -196,6 +180,7 @@ impl VideoRefreshManager {
                 screen_info.lfb_depth.into(),
                 buf_flag,
                 buf_vaddr,
+                None,
             )
             .unwrap();
         } else {
@@ -208,6 +193,7 @@ impl VideoRefreshManager {
                 screen_info.lfb_depth.into(),
                 buf_flag,
                 buf_vaddr,
+                None,
             )
             .unwrap();
         }

+ 0 - 16
kernel/src/include/bindings/wrapper.h

@@ -10,19 +10,3 @@
  */
 #pragma once
 
-
-#include <common/glib.h>
-#include <common/printk.h>
-#include <common/spinlock.h>
-#include <common/stdio.h>
-#include <common/string.h>
-#include <common/time.h>
-#include <common/unistd.h>
-#include <driver/multiboot2/multiboot2.h>
-#include <libs/lib_ui/textui.h>
-#include <mm/mm.h>
-#include <mm/mmio.h>
-#include <mm/slab.h>
-#include <process/process.h>
-#include <time/sleep.h>
-#include <common/errno.h>

+ 176 - 0
kernel/src/init/boot.rs

@@ -0,0 +1,176 @@
+use core::cmp::min;
+
+use acpi::rsdp::Rsdp;
+use alloc::string::String;
+use system_error::SystemError;
+
+use crate::{
+    arch::init::ArchBootParams,
+    driver::video::fbdev::base::BootTimeScreenInfo,
+    libs::lazy_init::Lazy,
+    mm::{PhysAddr, VirtAddr},
+};
+
+use super::boot_params;
+#[derive(Debug)]
+pub struct BootParams {
+    pub screen_info: BootTimeScreenInfo,
+    bootloader_name: Option<String>,
+    #[allow(dead_code)]
+    pub arch: ArchBootParams,
+    boot_command_line: [u8; Self::BOOT_COMMAND_LINE_SIZE],
+    pub acpi: BootloaderAcpiArg,
+}
+
+impl BootParams {
+    const DEFAULT: Self = BootParams {
+        screen_info: BootTimeScreenInfo::DEFAULT,
+        bootloader_name: None,
+        arch: ArchBootParams::DEFAULT,
+        boot_command_line: [0u8; Self::BOOT_COMMAND_LINE_SIZE],
+        acpi: BootloaderAcpiArg::NotProvided,
+    };
+
+    /// 开机命令行参数字符串最大大小
+    pub const BOOT_COMMAND_LINE_SIZE: usize = 2048;
+
+    pub(super) const fn new() -> Self {
+        Self::DEFAULT
+    }
+
+    /// 开机命令行参数(原始字节数组)
+    #[allow(dead_code)]
+    pub fn boot_cmdline(&self) -> &[u8] {
+        &self.boot_command_line
+    }
+
+    /// 开机命令行参数字符串
+    pub fn boot_cmdline_str(&self) -> &str {
+        core::str::from_utf8(self.boot_cmdline()).unwrap()
+    }
+
+    pub fn bootloader_name(&self) -> Option<&str> {
+        self.bootloader_name.as_deref()
+    }
+
+    /// 追加开机命令行参数
+    ///
+    /// 如果开机命令行参数已经满了,则不会追加。
+    /// 如果超过了最大长度,则截断。
+    ///
+    /// ## 参数
+    ///
+    /// - `data`:追加的数据
+    pub fn boot_cmdline_append(&mut self, data: &[u8]) {
+        if data.is_empty() {
+            return;
+        }
+
+        let mut pos: Option<usize> = None;
+        // 寻找结尾
+        for (i, x) in self.boot_command_line.iter().enumerate() {
+            if *x == 0 {
+                pos = Some(i);
+                break;
+            }
+        }
+        let pos = pos.unwrap_or(self.boot_command_line.len() - 1) as isize;
+
+        let avail = self.boot_command_line.len() as isize - pos - 1;
+        if avail <= 0 {
+            return;
+        }
+
+        let len = min(avail as usize, data.len());
+        let pos = pos as usize;
+        self.boot_command_line[pos..pos + len].copy_from_slice(&data[0..len]);
+
+        self.boot_command_line[pos + len] = 0;
+    }
+
+    /// 获取FDT的虚拟地址
+    #[allow(dead_code)]
+    pub fn fdt(&self) -> Option<VirtAddr> {
+        #[cfg(target_arch = "riscv64")]
+        return Some(self.arch.arch_fdt());
+
+        #[cfg(target_arch = "x86_64")]
+        return None;
+    }
+
+    /// 获取FDT的物理地址
+    #[allow(dead_code)]
+    pub fn fdt_paddr(&self) -> Option<PhysAddr> {
+        #[cfg(target_arch = "riscv64")]
+        return Some(self.arch.fdt_paddr);
+
+        #[cfg(target_arch = "x86_64")]
+        return None;
+    }
+}
+
+/// 开机引导回调,用于初始化内核启动参数
+pub trait BootCallbacks: Send + Sync {
+    /// 初始化引导程序名称
+    fn init_bootloader_name(&self) -> Result<Option<String>, SystemError>;
+    /// 初始化ACPI参数
+    fn init_acpi_args(&self) -> Result<BootloaderAcpiArg, SystemError>;
+    /// 初始化内核命令行参数
+    ///
+    /// 该函数应该把内核命令行参数追加到`boot_params().boot_cmdline`中
+    fn init_kernel_cmdline(&self) -> Result<(), SystemError>;
+    /// 初始化帧缓冲区信息
+    ///
+    /// - 该函数应该把帧缓冲区信息写入`scinfo`中。
+    /// - 该函数应该在内存管理初始化之前调用。
+    fn early_init_framebuffer_info(
+        &self,
+        scinfo: &mut BootTimeScreenInfo,
+    ) -> Result<(), SystemError>;
+
+    /// 初始化内存块
+    fn early_init_memory_blocks(&self) -> Result<(), SystemError>;
+}
+
+static BOOT_CALLBACKS: Lazy<&'static dyn BootCallbacks> = Lazy::new();
+
+/// 注册开机引导回调
+pub fn register_boot_callbacks(callbacks: &'static dyn BootCallbacks) {
+    BOOT_CALLBACKS.init(callbacks);
+}
+
+/// 获取开机引导回调
+pub fn boot_callbacks() -> &'static dyn BootCallbacks {
+    let p = BOOT_CALLBACKS
+        .try_get()
+        .expect("Boot callbacks not initialized");
+
+    *p
+}
+
+pub(super) fn boot_callback_except_early() {
+    boot_callbacks()
+        .init_kernel_cmdline()
+        .expect("Failed to init kernel cmdline");
+    let mut boot_params = boot_params().write();
+    boot_params.bootloader_name = boot_callbacks()
+        .init_bootloader_name()
+        .expect("Failed to init bootloader name");
+    boot_params.acpi = boot_callbacks()
+        .init_acpi_args()
+        .unwrap_or(BootloaderAcpiArg::NotProvided);
+}
+
+/// ACPI information from the bootloader.
+#[derive(Copy, Clone, Debug)]
+pub enum BootloaderAcpiArg {
+    /// The bootloader does not provide one, a manual search is needed.
+    NotProvided,
+    /// Physical address of the RSDP.
+    #[allow(dead_code)]
+    Rsdp(PhysAddr),
+    /// Address of RSDT provided in RSDP v1.
+    Rsdt(Rsdp),
+    /// Address of XSDT provided in RSDP v2+.
+    Xsdt(Rsdp),
+}

+ 9 - 5
kernel/src/init/init.rs

@@ -4,7 +4,10 @@ use crate::{
         time::time_init,
         CurrentIrqArch, CurrentSMPArch, CurrentSchedArch,
     },
-    driver::{base::init::driver_init, serial::serial_early_init, video::VideoRefreshManager},
+    driver::{
+        acpi::acpi_init, base::init::driver_init, serial::serial_early_init,
+        video::VideoRefreshManager,
+    },
     exception::{init::irq_init, softirq::softirq_init, InterruptArch},
     filesystem::vfs::core::vfs_init,
     init::init_intertrait,
@@ -26,6 +29,8 @@ use crate::{
     },
 };
 
+use super::boot::boot_callback_except_early;
+
 /// The entry point for the kernel
 ///
 /// 前面可能会有一个架构相关的函数
@@ -52,15 +57,14 @@ fn do_start_kernel() {
 
     scm_reinit().unwrap();
     textui_init().unwrap();
+
+    boot_callback_except_early();
     init_intertrait();
 
     vfs_init().expect("vfs init failed");
     driver_init().expect("driver init failed");
 
-    #[cfg(target_arch = "x86_64")]
-    unsafe {
-        crate::include::bindings::bindings::acpi_init()
-    };
+    acpi_init().expect("acpi init failed");
     crate::sched::sched_init();
     process_init();
     early_smp_init().expect("early smp init failed");

+ 3 - 96
kernel/src/init/mod.rs

@@ -1,11 +1,7 @@
-use core::cmp::min;
+use crate::libs::rwlock::RwLock;
 
-use crate::{
-    arch::init::ArchBootParams,
-    driver::video::fbdev::base::BootTimeScreenInfo,
-    libs::rwlock::RwLock,
-    mm::{PhysAddr, VirtAddr},
-};
+use self::boot::BootParams;
+pub mod boot;
 #[allow(clippy::module_inception)]
 pub mod init;
 pub mod initcall;
@@ -23,92 +19,3 @@ pub fn boot_params() -> &'static RwLock<BootParams> {
 fn init_intertrait() {
     intertrait::init_caster_map();
 }
-
-#[derive(Debug)]
-pub struct BootParams {
-    pub screen_info: BootTimeScreenInfo,
-    #[allow(dead_code)]
-    pub arch: ArchBootParams,
-    boot_command_line: [u8; Self::BOOT_COMMAND_LINE_SIZE],
-}
-
-impl BootParams {
-    const DEFAULT: Self = BootParams {
-        screen_info: BootTimeScreenInfo::DEFAULT,
-        arch: ArchBootParams::DEFAULT,
-        boot_command_line: [0u8; Self::BOOT_COMMAND_LINE_SIZE],
-    };
-
-    /// 开机命令行参数字符串最大大小
-    pub const BOOT_COMMAND_LINE_SIZE: usize = 2048;
-
-    const fn new() -> Self {
-        Self::DEFAULT
-    }
-
-    /// 开机命令行参数(原始字节数组)
-    #[allow(dead_code)]
-    pub fn boot_cmdline(&self) -> &[u8] {
-        &self.boot_command_line
-    }
-
-    /// 开机命令行参数字符串
-    pub fn boot_cmdline_str(&self) -> &str {
-        core::str::from_utf8(self.boot_cmdline()).unwrap()
-    }
-
-    /// 追加开机命令行参数
-    ///
-    /// 如果开机命令行参数已经满了,则不会追加。
-    /// 如果超过了最大长度,则截断。
-    ///
-    /// ## 参数
-    ///
-    /// - `data`:追加的数据
-    pub fn boot_cmdline_append(&mut self, data: &[u8]) {
-        if data.is_empty() {
-            return;
-        }
-
-        let mut pos: Option<usize> = None;
-        // 寻找结尾
-        for (i, x) in self.boot_command_line.iter().enumerate() {
-            if *x == 0 {
-                pos = Some(i);
-                break;
-            }
-        }
-        let pos = pos.unwrap_or(self.boot_command_line.len() - 1) as isize;
-
-        let avail = self.boot_command_line.len() as isize - pos - 1;
-        if avail <= 0 {
-            return;
-        }
-
-        let len = min(avail as usize, data.len());
-        let pos = pos as usize;
-        self.boot_command_line[pos..pos + len].copy_from_slice(&data[0..len]);
-
-        self.boot_command_line[pos + len] = 0;
-    }
-
-    /// 获取FDT的虚拟地址
-    #[allow(dead_code)]
-    pub fn fdt(&self) -> Option<VirtAddr> {
-        #[cfg(target_arch = "riscv64")]
-        return Some(self.arch.arch_fdt());
-
-        #[cfg(target_arch = "x86_64")]
-        return None;
-    }
-
-    /// 获取FDT的物理地址
-    #[allow(dead_code)]
-    pub fn fdt_paddr(&self) -> Option<PhysAddr> {
-        #[cfg(target_arch = "riscv64")]
-        return Some(self.arch.fdt_paddr);
-
-        #[cfg(target_arch = "x86_64")]
-        return None;
-    }
-}

+ 10 - 1
kernel/src/libs/lib_ui/screen_manager.rs

@@ -10,7 +10,7 @@ use system_error::SystemError;
 use crate::{
     driver::{serial::serial8250::send_to_default_serial8250_port, video::video_refresh_manager},
     libs::{lib_ui::textui::textui_is_enable_put_to_window, rwlock::RwLock, spinlock::SpinLock},
-    mm::VirtAddr,
+    mm::{mmio_buddy::MMIOSpaceGuard, VirtAddr},
 };
 
 use super::{
@@ -56,6 +56,7 @@ pub struct ScmBufferInfo {
     height: u32,    // 帧缓冲区高度(pixel或lines)
     size: u32,      // 帧缓冲区大小(bytes)
     bit_depth: u32, // 像素点位深度
+    device_buffer_mmio_guard: Option<Arc<MMIOSpaceGuard>>,
     pub buf: ScmBuffer,
     flags: ScmBufferFlag, // 帧缓冲区标志位
 }
@@ -100,6 +101,7 @@ impl ScmBufferInfo {
                 bit_depth: device_buffer_guard.bit_depth,
                 flags: buf_type,
                 buf: ScmBuffer::DoubleBuffer(buf_space),
+                device_buffer_mmio_guard: None,
             };
             drop(device_buffer_guard);
 
@@ -107,6 +109,10 @@ impl ScmBufferInfo {
         }
     }
 
+    pub unsafe fn set_device_buffer_mmio_guard(&mut self, guard: Arc<MMIOSpaceGuard>) {
+        self.device_buffer_mmio_guard = Some(guard);
+    }
+
     pub unsafe fn new_device_buffer(
         width: u32,
         height: u32,
@@ -114,7 +120,9 @@ impl ScmBufferInfo {
         bit_depth: u32,
         buf_type: ScmBufferFlag,
         vaddr: VirtAddr,
+        mut device_buffer_mmio_guard: Option<MMIOSpaceGuard>,
     ) -> Result<Self, SystemError> {
+        let mmio_guard = device_buffer_mmio_guard.take().map(Arc::new);
         let buffer = Self {
             width,
             height,
@@ -122,6 +130,7 @@ impl ScmBufferInfo {
             bit_depth,
             flags: buf_type,
             buf: ScmBuffer::DeviceBuffer(vaddr),
+            device_buffer_mmio_guard: mmio_guard,
         };
         return Ok(buffer);
     }

+ 4 - 50
kernel/src/mm/c_adapter.rs

@@ -7,69 +7,23 @@ use hashbrown::HashMap;
 use log::error;
 use system_error::SystemError;
 
-use crate::{
-    include::bindings::bindings::{gfp_t, PAGE_U_S},
-    libs::{align::page_align_up, spinlock::SpinLock},
-    mm::MMArch,
-};
+use crate::libs::spinlock::SpinLock;
 
-use super::{
-    allocator::page_frame::PageFrameCount, kernel_mapper::KernelMapper, mmio_buddy::mmio_pool,
-    no_init::pseudo_map_phys, page::EntryFlags, MemoryManagementArch, PhysAddr, VirtAddr,
-};
+use super::{mmio_buddy::mmio_pool, VirtAddr};
 
 lazy_static! {
     // 用于记录内核分配给C的空间信息
     static ref C_ALLOCATION_MAP: SpinLock<HashMap<VirtAddr, (VirtAddr, usize, usize)>> = SpinLock::new(HashMap::new());
 }
 
-/// [EXTERN TO C] Use pseudo mapper to map physical memory to virtual memory.
 #[no_mangle]
-pub unsafe extern "C" fn rs_pseudo_map_phys(vaddr: usize, paddr: usize, size: usize) {
-    let vaddr = VirtAddr::new(vaddr);
-    let paddr = PhysAddr::new(paddr);
-    let count = PageFrameCount::new(page_align_up(size) / MMArch::PAGE_SIZE);
-    pseudo_map_phys(vaddr, paddr, count);
-}
-
-/// [EXTERN TO C] Use kernel mapper to map physical memory to virtual memory.
-#[no_mangle]
-pub unsafe extern "C" fn rs_map_phys(vaddr: usize, paddr: usize, size: usize, flags: usize) {
-    let mut vaddr = VirtAddr::new(vaddr);
-    let mut paddr = PhysAddr::new(paddr);
-    let count = PageFrameCount::new(page_align_up(size) / MMArch::PAGE_SIZE);
-    // debug!("rs_map_phys: vaddr: {vaddr:?}, paddr: {paddr:?}, count: {count:?}, flags: {flags:?}");
-
-    let mut page_flags: EntryFlags<MMArch> = EntryFlags::new().set_execute(true).set_write(true);
-    if flags & PAGE_U_S as usize != 0 {
-        page_flags = page_flags.set_user(true);
-    }
-
-    let mut kernel_mapper = KernelMapper::lock();
-    let mut kernel_mapper = kernel_mapper.as_mut();
-    assert!(kernel_mapper.is_some());
-    for _i in 0..count.data() {
-        let flusher = kernel_mapper
-            .as_mut()
-            .unwrap()
-            .map_phys(vaddr, paddr, page_flags)
-            .unwrap();
-
-        flusher.flush();
-
-        vaddr += MMArch::PAGE_SIZE;
-        paddr += MMArch::PAGE_SIZE;
-    }
-}
-
-#[no_mangle]
-pub unsafe extern "C" fn kzalloc(size: usize, _gfp: gfp_t) -> usize {
+pub unsafe extern "C" fn kzalloc(size: usize, _gfp: u64) -> usize {
     // debug!("kzalloc: size: {size}");
     return do_kmalloc(size, true);
 }
 
 #[no_mangle]
-pub unsafe extern "C" fn kmalloc(size: usize, _gfp: gfp_t) -> usize {
+pub unsafe extern "C" fn kmalloc(size: usize, _gfp: u64) -> usize {
     // debug!("kmalloc: size: {size}");
     // 由于C代码不规范,因此都全部清空
     return do_kmalloc(size, true);

+ 6 - 54
kernel/src/mm/mm.h

@@ -3,18 +3,6 @@
 #include <common/glib.h>
 #include <process/process.h>
 
-extern void rs_pseudo_map_phys(uint64_t virt_addr, uint64_t phys_addr, uint64_t size);
-extern void rs_map_phys(uint64_t virt_addr, uint64_t phys_addr, uint64_t size, uint64_t flags);
-extern uint64_t rs_unmap_at_low_addr();
-
-// 内核层的起始地址
-#define PAGE_OFFSET 0xffff800000000000UL
-#define KERNEL_BASE_LINEAR_ADDR 0xffff800000000000UL
-#define USER_MAX_LINEAR_ADDR 0x00007fffffffffffUL
-// MMIO虚拟地址空间:1TB
-#define MMIO_BASE 0xffffa10000000000UL
-#define MMIO_TOP 0xffffa20000000000UL
-
 #define PAGE_4K_SHIFT 12
 #define PAGE_2M_SHIFT 21
 #define PAGE_1G_SHIFT 30
@@ -30,19 +18,15 @@ extern uint64_t rs_unmap_at_low_addr();
 #define PAGE_2M_MASK (~(PAGE_2M_SIZE - 1))
 
 // 将addr按照x的上边界对齐
-#define PAGE_4K_ALIGN(addr) (((unsigned long)(addr) + PAGE_4K_SIZE - 1) & PAGE_4K_MASK)
-#define PAGE_2M_ALIGN(addr) (((unsigned long)(addr) + PAGE_2M_SIZE - 1) & PAGE_2M_MASK)
+#define PAGE_4K_ALIGN(addr)                                                    \
+  (((unsigned long)(addr) + PAGE_4K_SIZE - 1) & PAGE_4K_MASK)
+#define PAGE_2M_ALIGN(addr)                                                    \
+  (((unsigned long)(addr) + PAGE_2M_SIZE - 1) & PAGE_2M_MASK)
 
 // 虚拟地址与物理地址转换
 #define virt_2_phys(addr) ((unsigned long)(addr)-PAGE_OFFSET)
-#define phys_2_virt(addr) ((unsigned long *)((unsigned long)(addr) + PAGE_OFFSET))
-
-// 在这个地址以上的虚拟空间,用来进行特殊的映射
-#define SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE 0xffffa00000000000UL
-#define FRAME_BUFFER_MAPPING_OFFSET 0x3000000UL
-#define IO_APIC_MAPPING_OFFSET 0xfec00000UL
-#define LOCAL_APIC_MAPPING_OFFSET 0xfee00000UL
-#define AHCI_MAPPING_OFFSET 0xff200000UL // AHCI 映射偏移量,之后使用了4M的地址
+#define phys_2_virt(addr)                                                      \
+  ((unsigned long *)((unsigned long)(addr) + PAGE_OFFSET))
 
 // ===== 页面属性 =====
 // 页面在页表中已被映射 mapped=1 unmapped=0
@@ -123,22 +107,6 @@ extern uint64_t rs_unmap_at_low_addr();
 
 #define PAGE_USER_4K_PAGE (PAGE_U_S | PAGE_R_W | PAGE_PRESENT)
 
-/**
- * @brief 刷新TLB的宏定义
- * 由于任何写入cr3的操作都会刷新TLB,因此这个宏定义可以刷新TLB
- */
-#define flush_tlb()                                  \
-    do                                               \
-    {                                                \
-        ul tmp;                                      \
-        io_mfence();                                 \
-        __asm__ __volatile__("movq %%cr3, %0\n\t"    \
-                             "movq %0, %%cr3\n\t"    \
-                             : "=r"(tmp)::"memory"); \
-                                                     \
-    } while (0);
-
-
 // 导出内核程序的几个段的起止地址
 extern char _text;
 extern char _etext;
@@ -150,22 +118,6 @@ extern char _bss;
 extern char _ebss;
 extern char _end;
 
-#if ARCH(I386) || ARCH(X86_64)
-/**
- * @brief 读取CR3寄存器的值(存储了页目录的基地址)
- *
- * @return unsigned*  cr3的值的指针
- */
-unsigned long *get_CR3()
-{
-    ul *tmp;
-    __asm__ __volatile__("movq %%cr3, %0\n\t"
-                         : "=r"(tmp)::"memory");
-    return tmp;
-}
-
-#endif
-
 /*
  *  vm_area_struct中的vm_flags的可选值
  * 对应的结构体请见mm-types.h

+ 28 - 0
kernel/src/mm/mmio_buddy.rs

@@ -684,6 +684,34 @@ impl MMIOSpaceGuard {
         return r;
     }
 
+    /// 将物理地址填写到虚拟地址空间中
+    ///
+    /// ## Safety
+    ///
+    /// 传入的物理地址【一定要是设备的物理地址】。
+    /// 如果物理地址是从内存分配器中分配的,那么会造成内存泄露。因为mmio_release的时候,只取消映射,不会释放内存。
+    pub unsafe fn map_phys_with_flags(
+        &self,
+        paddr: PhysAddr,
+        length: usize,
+        flags: EntryFlags<MMArch>,
+    ) -> Result<(), SystemError> {
+        if length > self.size {
+            return Err(SystemError::EINVAL);
+        }
+
+        let check = self
+            .mapped
+            .compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst);
+        if check.is_err() {
+            return Err(SystemError::EINVAL);
+        }
+
+        let mut kernel_mapper = KernelMapper::lock();
+        let r = kernel_mapper.map_phys_with_size(self.vaddr, paddr, length, flags, true);
+        return r;
+    }
+
     /// # map_any_phys - 将任意物理地址映射到虚拟地址
     ///
     /// 将指定的物理地址和长度映射到虚拟地址空间。

+ 2 - 2
kernel/src/mm/page.rs

@@ -25,7 +25,7 @@ use crate::{
         spinlock::{SpinLock, SpinLockGuard},
     },
     process::{ProcessControlBlock, ProcessManager},
-    time::{sleep::usleep, PosixTimeSpec},
+    time::{sleep::nanosleep, PosixTimeSpec},
 };
 
 use super::{
@@ -150,7 +150,7 @@ fn page_reclaim_thread() -> i32 {
             page_reclaimer_lock_irqsave().flush_dirty_pages();
             // 休眠5秒
             // log::info!("sleep");
-            let _ = usleep(PosixTimeSpec::new(5, 0));
+            let _ = nanosleep(PosixTimeSpec::new(5, 0));
         }
     }
 }

+ 1 - 2
kernel/src/net/event_poll/mod.rs

@@ -17,7 +17,6 @@ use crate::{
         file::{File, FileMode},
         FilePrivateData, IndexNode, Metadata,
     },
-    include::bindings::bindings::INT32_MAX,
     libs::{
         rbtree::RBTree,
         rwlock::RwLock,
@@ -53,7 +52,7 @@ pub struct EventPoll {
 }
 
 impl EventPoll {
-    pub const EP_MAX_EVENTS: u32 = INT32_MAX / (core::mem::size_of::<EPollEvent>() as u32);
+    pub const EP_MAX_EVENTS: u32 = u32::MAX / (core::mem::size_of::<EPollEvent>() as u32);
     /// 用于获取inode中的epitem队列
     pub const ADD_EPOLLITEM: u32 = 0x7965;
     pub fn new() -> Self {

+ 0 - 1
kernel/src/syscall/syscall.c

@@ -5,7 +5,6 @@
 #include <common/string.h>
 #include <mm/slab.h>
 #include <process/process.h>
-#include <time/sleep.h>
 
 #if ARCH(I386) || ARCH(X86_64)
 // 导出系统调用入口函数,定义在entry.S中

+ 0 - 13
kernel/src/time/sleep.h

@@ -1,13 +0,0 @@
-#pragma once
-
-#include <common/glib.h>
-#include <common/time.h>
-#include <process/ptrace.h>
-
-/**
- * @brief 睡眠指定时间
- *
- * @param usec 微秒
- * @return int
- */
-int rs_usleep(useconds_t usec);

+ 0 - 40
kernel/src/time/sleep.rs

@@ -6,7 +6,6 @@ use system_error::SystemError;
 use crate::{
     arch::{CurrentIrqArch, CurrentTimeArch},
     exception::InterruptArch,
-    include::bindings::bindings::useconds_t,
     process::ProcessManager,
     sched::{schedule, SchedMode},
     time::timekeeping::getnstimeofday,
@@ -63,42 +62,3 @@ pub fn nanosleep(sleep_time: PosixTimeSpec) -> Result<PosixTimeSpec, SystemError
 
     return Ok(rm_time);
 }
-
-/// @brief 休眠指定时间(单位:微秒)
-///
-///  @param usec 微秒
-///
-/// @return Ok(TimeSpec) 剩余休眠时间
-///
-/// @return Err(SystemError) 错误码
-pub fn usleep(sleep_time: PosixTimeSpec) -> Result<PosixTimeSpec, SystemError> {
-    match nanosleep(sleep_time) {
-        Ok(value) => return Ok(value),
-        Err(err) => return Err(err),
-    };
-}
-
-//===== 以下为提供给C的接口 =====
-
-/// @brief 休眠指定时间(单位:微秒)(提供给C的接口)
-///
-///  @param usec 微秒
-///
-/// @return Ok(i32) 0
-///
-/// @return Err(SystemError) 错误码
-#[no_mangle]
-pub extern "C" fn rs_usleep(usec: useconds_t) -> i32 {
-    let sleep_time = PosixTimeSpec {
-        tv_sec: (usec / 1000000) as i64,
-        tv_nsec: ((usec % 1000000) * 1000) as i64,
-    };
-    match usleep(sleep_time) {
-        Ok(_) => {
-            return 0;
-        }
-        Err(err) => {
-            return err.to_posix_errno();
-        }
-    };
-}

+ 0 - 1
user/apps/test_gettimeofday/main.c

@@ -1,7 +1,6 @@
 #include <sys/time.h>
 #include <stdio.h>
 #include <stdlib.h>
-// #include <sleep.h>
 #include <unistd.h>
 #include <time.h>