Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions kernel/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions kernel/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ fifo_demo = []

# 运行时依赖项
[dependencies]
acpi = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/acpi-rs.git", rev = "282df2af7b" }
aml = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/acpi-rs.git", rev = "282df2af7b" }
acpi = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/acpi-rs.git", rev = "1bbdc9767ac72725fa7bdbc53260b5b6baa2bce1" }
aml = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/acpi-rs.git", rev = "1bbdc9767ac72725fa7bdbc53260b5b6baa2bce1" }
asm_macros = { path = "crates/asm_macros" }
atomic_enum = "=0.2.0"
bit_field = "=0.10"
Expand Down
1 change: 1 addition & 0 deletions kernel/src/arch/x86_64/init/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use super::{
mod boot;
mod multiboot2;
mod pvh;
mod rsdp;

mod boot_params;

Expand Down
45 changes: 36 additions & 9 deletions kernel/src/arch/x86_64/init/multiboot2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,23 @@ use crate::{
mm::{memblock::mem_block_manager, PhysAddr},
};

use super::rsdp::{cache_bios_rsdp_result, cached_bios_rsdp};

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 has_efi_context(boot_info: &BootInformation) -> bool {
boot_info.efi_sdt32_tag().is_some()
|| boot_info.efi_sdt64_tag().is_some()
|| boot_info.efi_memory_map_tag().is_some()
|| boot_info.efi_bs_not_exited_tag().is_some()
|| boot_info.efi_ih32_tag().is_some()
|| boot_info.efi_ih64_tag().is_some()
}

fn mb2_rsdp_v1_tag_to_rsdp_struct(tag: &RsdpV1Tag) -> Rsdp {
Rsdp {
signature: tag.signature,
Expand Down Expand Up @@ -70,17 +81,23 @@ impl BootCallbacks for Mb2Callback {
}

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(
let boot_info = MB2_INFO.get();
if let Some(v2_tag) = boot_info.rsdp_v2_tag() {
return Ok(BootloaderAcpiArg::Xsdt(mb2_rsdp_v2_tag_to_rsdp_struct(
v2_tag,
)))
} else {
Ok(BootloaderAcpiArg::NotProvided)
)));
}
if let Some(v1_tag) = boot_info.rsdp_v1_tag() {
return Ok(BootloaderAcpiArg::Rsdt(mb2_rsdp_v1_tag_to_rsdp_struct(
v1_tag,
)));
}
if let Some(paddr) = cached_bios_rsdp()? {
log::info!("multiboot2: found RSDP at {:#x}", paddr.data());
return Ok(BootloaderAcpiArg::Rsdp(paddr));
}

Ok(BootloaderAcpiArg::NotProvided)
}

fn init_kernel_cmdline(&self) -> Result<(), SystemError> {
Expand Down Expand Up @@ -209,6 +226,16 @@ impl BootCallbacks for Mb2Callback {
// setup kernel load base
self.setup_kernel_load_base();

// Legacy BIOS fallback is valid only when no ACPI tag and no EFI
// context were supplied. UEFI systems must use their configuration
// table and must not probe the fixed Legacy BIOS regions.
if mb2_info.rsdp_v2_tag().is_none()
&& mb2_info.rsdp_v1_tag().is_none()
&& !has_efi_context(mb2_info)
{
cache_bios_rsdp_result();
}

Ok(())
}

Expand Down
39 changes: 34 additions & 5 deletions kernel/src/arch/x86_64/init/pvh/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ use crate::{

mod param;

use super::rsdp::{cache_bios_rsdp_result, cached_bios_rsdp};

static START_INFO: Lazy<HvmStartInfo> = Lazy::new();

struct PvhBootCallback;
Expand All @@ -31,12 +33,29 @@ impl BootCallbacks for PvhBootCallback {
}

fn init_acpi_args(&self) -> Result<BootloaderAcpiArg, SystemError> {
let rsdp_paddr = PhysAddr::new(START_INFO.get().rsdp_paddr as usize);
let si = START_INFO.get();
log::info!(
"pvh: HvmStartInfo: magic={:#010x} version={} flags={:#x} nr_modules={} rsdp_paddr={:#x} memmap_paddr={:#x} memmap_entries={}",
si.magic, si.version, si.flags, si.nr_modules,
si.rsdp_paddr, si.memmap_paddr, si.memmap_entries
);

let rsdp_paddr = PhysAddr::new(si.rsdp_paddr as usize);

// if RSDP has been provided
if rsdp_paddr.data() != 0 {
Ok(BootloaderAcpiArg::Rsdp(rsdp_paddr))
} else {
Ok(BootloaderAcpiArg::NotProvided)
return Ok(BootloaderAcpiArg::Rsdp(rsdp_paddr));
}

// The bootloader did not provide an RSDP. Consume the shared x86
// early-discovery result without touching EarlyIoRemap after mm_init.
if let Some(paddr) = cached_bios_rsdp()? {
log::info!("pvh: found RSDP at {:#x}", paddr.data());
return Ok(BootloaderAcpiArg::Rsdp(paddr));
}

log::warn!("pvh: RSDP not found");
Ok(BootloaderAcpiArg::NotProvided)
}

fn init_kernel_cmdline(&self) -> Result<(), SystemError> {
Expand Down Expand Up @@ -86,7 +105,7 @@ impl BootCallbacks for PvhBootCallback {

total_mem_size += size;
match typ {
param::E820Type::Ram => {
E820Type::Ram => {
usable_mem_size += size;
mem_block_manager()
.add_block(start, size)
Expand Down Expand Up @@ -121,6 +140,16 @@ impl BootCallbacks for PvhBootCallback {
total_mem_size,
usable_mem_size
);

// Discover the RSDP here, in the early boot stage: the bootstrap page
// table is still active and mm_init has not run yet, so EarlyIoRemap may
// be used safely (this mirrors Linux, which scans the RSDP in setup_arch
// via early_memremap). If the bootloader already provided rsdp_paddr we
// skip the scan. The result is cached for init_acpi_args.
if start_info.rsdp_paddr == 0 {
cache_bios_rsdp_result();
}

Ok(())
}

Expand Down
2 changes: 1 addition & 1 deletion kernel/src/arch/x86_64/init/pvh/param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ pub struct HvmMemmapTableEntry {
}

/// The E820 types known to the kernel.
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum E820Type {
Ram = 1,
Expand Down
Loading
Loading