Skip to content

Commit 7d3731e

Browse files
authored
Merge pull request #287 from duanyu-yu/fdt
Create devicetree for x86_64
2 parents d22fcda + 0a1d0ac commit 7d3731e

File tree

5 files changed

+120
-1
lines changed

5 files changed

+120
-1
lines changed

Cargo.lock

+58
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ align-address = "0.1"
1111
hermit-entry = { version = "0.9", features = ["loader"] }
1212
log = "0.4"
1313
sptr = "0.3"
14+
vm-fdt = { version = "0.3", default-features = false, features = ["alloc"] }
1415

1516
[features]
1617
default = []

src/arch/x86_64/fdt.rs

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
use alloc::format;
2+
3+
use multiboot::information::{MemoryType, Multiboot};
4+
use vm_fdt::{Error as FdtError, FdtWriter};
5+
6+
use super::{mb_info, MEM};
7+
8+
pub struct DeviceTree;
9+
10+
impl DeviceTree {
11+
#[cfg(all(target_os = "none", not(feature = "fc")))]
12+
pub fn create() -> Result<&'static [u8], FdtError> {
13+
let multiboot = unsafe { Multiboot::from_ptr(mb_info as u64, &mut MEM).unwrap() };
14+
15+
let all_regions = multiboot
16+
.memory_regions()
17+
.expect("Could not find a memory map in the Multiboot information");
18+
let ram_regions = all_regions.filter(|m| m.memory_type() == MemoryType::Available);
19+
20+
let mut fdt = FdtWriter::new()?;
21+
22+
let root_node = fdt.begin_node("")?;
23+
fdt.property_string("compatible", "linux,dummy-virt")?;
24+
fdt.property_u32("#address-cells", 0x2)?;
25+
fdt.property_u32("#size-cells", 0x2)?;
26+
27+
if let Some(cmdline) = multiboot.command_line() {
28+
let chosen_node = fdt.begin_node("chosen")?;
29+
fdt.property_string("bootargs", cmdline)?;
30+
fdt.end_node(chosen_node)?;
31+
}
32+
33+
for m in ram_regions {
34+
let start_address = m.base_address();
35+
let length = m.length();
36+
37+
let memory_node = fdt.begin_node(format!("memory@{:x}", start_address).as_str())?;
38+
fdt.property_string("device_type", "memory")?;
39+
fdt.property_array_u64("reg", &[start_address, length])?;
40+
fdt.end_node(memory_node)?;
41+
}
42+
43+
fdt.end_node(root_node)?;
44+
45+
let fdt = fdt.finish()?;
46+
47+
Ok(fdt.leak())
48+
}
49+
}

src/arch/x86_64/mod.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#[cfg(all(target_os = "none", not(feature = "fc")))]
2+
mod fdt;
13
mod paging;
24
mod physicalmem;
35

@@ -10,6 +12,8 @@ use core::ptr::write_bytes;
1012
use core::slice;
1113

1214
use align_address::Align;
15+
#[cfg(all(target_os = "none", not(feature = "fc")))]
16+
use hermit_entry::boot_info::DeviceTreeAddress;
1317
use hermit_entry::boot_info::{BootInfo, HardwareInfo, PlatformInfo, RawBootInfo, SerialPortBase};
1418
use hermit_entry::elf::LoadedKernel;
1519
#[cfg(all(target_os = "none", feature = "fc"))]
@@ -27,6 +31,8 @@ use multiboot::information::{Multiboot, PAddr};
2731
use uart_16550::SerialPort;
2832
use x86_64::structures::paging::{PageSize, PageTableFlags, Size2MiB, Size4KiB};
2933

34+
#[cfg(all(target_os = "none", not(feature = "fc")))]
35+
use self::fdt::DeviceTree;
3036
use self::physicalmem::PhysAlloc;
3137

3238
#[cfg(target_os = "none")]
@@ -472,14 +478,16 @@ pub unsafe fn boot_kernel(kernel_info: LoadedKernel) -> ! {
472478
);
473479
}
474480

481+
let device_tree = DeviceTree::create().expect("Unable to create devicetree!");
482+
475483
static mut BOOT_INFO: Option<RawBootInfo> = None;
476484

477485
let boot_info = {
478486
let boot_info = BootInfo {
479487
hardware_info: HardwareInfo {
480488
phys_addr_range: 0..0,
481489
serial_port_base: SerialPortBase::new(SERIAL_IO_PORT),
482-
device_tree: None,
490+
device_tree: DeviceTreeAddress::new(device_tree.as_ptr() as u64),
483491
},
484492
load_info,
485493
platform_info: PlatformInfo::Multiboot {

src/main.rs

+3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ mod none;
2020
#[cfg(target_os = "uefi")]
2121
mod uefi;
2222

23+
#[cfg(all(target_arch = "x86_64", target_os = "none", not(feature = "fc")))]
24+
extern crate alloc;
25+
2326
#[cfg(target_os = "none")]
2427
#[doc(hidden)]
2528
fn _print(args: core::fmt::Arguments<'_>) {

0 commit comments

Comments
 (0)