Skip to content

Commit 45626c8

Browse files
authored
riscv: 解析dtb,获取可用内存空间并添加到memblock (#486)
1 parent 02343d0 commit 45626c8

File tree

16 files changed

+837
-50
lines changed

16 files changed

+837
-50
lines changed

kernel/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ smoltcp = { git = "https://git.mirrors.dragonos.org/DragonOS-Community/smoltcp.g
4444
system_error = { path = "crates/system_error" }
4545
unified-init = { path = "crates/unified-init" }
4646
virtio-drivers = { git = "https://git.mirrors.dragonos.org/DragonOS-Community/virtio-drivers.git", rev = "f1d1cbb" }
47+
fdt = "0.1.5"
4748

4849
# target为x86_64时,使用下面的依赖
4950
[target.'cfg(target_arch = "x86_64")'.dependencies]
@@ -52,6 +53,11 @@ x86 = "0.52.0"
5253
x86_64 = "0.14.10"
5354

5455

56+
# target为riscv64时,使用下面的依赖
57+
[target.'cfg(target_arch = "riscv64")'.dependencies]
58+
59+
60+
5561
# 构建时依赖项
5662
[build-dependencies]
5763
kernel_build = { path = "../build-scripts/kernel_build" }

kernel/src/arch/riscv64/init/mod.rs

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,71 @@
11
use core::intrinsics::unreachable;
22

3-
use crate::{init::init_before_mem_init, kinfo, mm::PhysAddr};
3+
use fdt::node::FdtNode;
4+
5+
use crate::{
6+
driver::open_firmware::fdt::open_firmware_fdt_driver,
7+
init::{boot_params, init_before_mem_init},
8+
kinfo,
9+
mm::{PhysAddr, VirtAddr},
10+
print, println,
11+
};
12+
13+
#[derive(Debug)]
14+
pub struct ArchBootParams {
15+
/// 启动时的fdt物理地址
16+
pub fdt_paddr: PhysAddr,
17+
}
18+
19+
impl ArchBootParams {
20+
pub const DEFAULT: Self = ArchBootParams {
21+
fdt_paddr: PhysAddr::new(0),
22+
};
23+
}
424

525
#[no_mangle]
626
unsafe extern "C" fn kernel_main(hartid: usize, fdt_paddr: usize) -> ! {
727
let fdt_paddr = PhysAddr::new(fdt_paddr);
828
init_before_mem_init();
29+
boot_params().write().arch.fdt_paddr = fdt_paddr;
930
kinfo!(
1031
"DragonOS kernel is running on hart {}, fdt address:{:?}",
1132
hartid,
1233
fdt_paddr
1334
);
35+
36+
let fdt = fdt::Fdt::from_ptr(fdt_paddr.data() as *const u8).expect("Failed to parse fdt!");
37+
print_node(fdt.find_node("/").unwrap(), 0);
38+
39+
parse_dtb();
40+
1441
loop {}
1542
unreachable()
1643
}
44+
45+
fn print_node(node: FdtNode<'_, '_>, n_spaces: usize) {
46+
(0..n_spaces).for_each(|_| print!(" "));
47+
println!("{}/", node.name);
48+
node.properties().for_each(|p| {
49+
(0..n_spaces + 4).for_each(|_| print!(" "));
50+
println!("{}: {:?}", p.name, p.value);
51+
});
52+
53+
for child in node.children() {
54+
print_node(child, n_spaces + 4);
55+
}
56+
}
57+
58+
/// 解析fdt,获取内核启动参数
59+
unsafe fn parse_dtb() {
60+
let fdt_paddr = boot_params().read().arch.fdt_paddr;
61+
if fdt_paddr.is_null() {
62+
panic!("Failed to get fdt address!");
63+
}
64+
65+
open_firmware_fdt_driver()
66+
.set_fdt_vaddr(VirtAddr::new(fdt_paddr.data()))
67+
.unwrap();
68+
open_firmware_fdt_driver()
69+
.early_scan_device_tree()
70+
.expect("Failed to scan device tree at boottime.");
71+
}

kernel/src/arch/riscv64/mm/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ impl MemoryManagementArch for RiscV64MMArch {
5353

5454
const USER_STACK_START: crate::mm::VirtAddr = VirtAddr::new(0x0000_001f_ffa0_0000);
5555

56-
unsafe fn init() -> &'static [crate::mm::PhysMemoryArea] {
56+
unsafe fn init() {
5757
todo!()
5858
}
5959

kernel/src/arch/riscv64/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
pub mod asm;
22
pub mod cpu;
33
pub mod driver;
4-
mod init;
4+
pub mod init;
55
pub mod interrupt;
66
pub mod ipc;
77
mod kvm;

kernel/src/arch/x86_64/init/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#[derive(Debug)]
2+
pub struct ArchBootParams {}
3+
4+
impl ArchBootParams {
5+
pub const DEFAULT: Self = ArchBootParams {};
6+
}

kernel/src/arch/x86_64/mm/bump.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
use crate::{
2-
kdebug,
32
libs::align::{page_align_down, page_align_up},
43
mm::{
5-
allocator::bump::BumpAllocator, MemoryManagementArch, PhysAddr, PhysMemoryArea, VirtAddr,
4+
allocator::bump::BumpAllocator, memblock::mem_block_manager, MemoryManagementArch,
5+
PhysAddr, PhysMemoryArea, VirtAddr,
66
},
77
};
88

9-
use super::{X86_64MMBootstrapInfo, BOOTSTRAP_MM_INFO, PHYS_MEMORY_AREAS};
9+
use super::{X86_64MMBootstrapInfo, BOOTSTRAP_MM_INFO};
1010

1111
impl<MMA: MemoryManagementArch> BumpAllocator<MMA> {
1212
pub unsafe fn arch_remain_areas(
@@ -23,7 +23,7 @@ impl<MMA: MemoryManagementArch> BumpAllocator<MMA> {
2323
let offset_end = page_align_down(kernel_code_start - 16384);
2424

2525
// 把内核代码前的空间加入到可用内存区域中
26-
for area in &PHYS_MEMORY_AREAS {
26+
for area in mem_block_manager().to_iter() {
2727
let area_base = area.area_base_aligned().data();
2828
let area_end = area.area_end_aligned().data();
2929
if area_base >= offset_end {
@@ -44,7 +44,6 @@ impl<MMA: MemoryManagementArch> BumpAllocator<MMA> {
4444
ret_areas[res_count] =
4545
PhysMemoryArea::new(PhysAddr::new(new_start), new_end - new_start);
4646

47-
kdebug!("new arch remain area: {:?}", ret_areas[res_count]);
4847
res_count += 1;
4948
}
5049

kernel/src/arch/x86_64/mm/mod.rs

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use crate::libs::printk::PrintkWriter;
1818
use crate::libs::spinlock::SpinLock;
1919

2020
use crate::mm::allocator::page_frame::{FrameAllocator, PageFrameCount, PageFrameUsage};
21+
use crate::mm::memblock::mem_block_manager;
2122
use crate::mm::mmio_buddy::mmio_init;
2223
use crate::{
2324
arch::MMArch,
@@ -26,8 +27,8 @@ use crate::{
2627

2728
use crate::mm::kernel_mapper::KernelMapper;
2829
use crate::mm::page::{PageEntry, PageFlags};
29-
use crate::mm::{MemoryManagementArch, PageTableKind, PhysAddr, PhysMemoryArea, VirtAddr};
30-
use crate::{kdebug, kinfo};
30+
use crate::mm::{MemoryManagementArch, PageTableKind, PhysAddr, VirtAddr};
31+
use crate::{kdebug, kinfo, kwarn};
3132
use system_error::SystemError;
3233

3334
use core::arch::asm;
@@ -43,12 +44,6 @@ use super::kvm::vmx::vmx_asm_wrapper::vmx_vmread;
4344
pub type PageMapper =
4445
crate::mm::page::PageMapper<crate::arch::x86_64::mm::X86_64MMArch, LockedFrameAllocator>;
4546

46-
/// @brief 用于存储物理内存区域的数组
47-
static mut PHYS_MEMORY_AREAS: [PhysMemoryArea; 512] = [PhysMemoryArea {
48-
base: PhysAddr::new(0),
49-
size: 0,
50-
}; 512];
51-
5247
/// 初始的CR3寄存器的值,用于内存管理初始化时,创建的第一个内核页表的位置
5348
static mut INITIAL_CR3_VALUE: PhysAddr = PhysAddr::new(0);
5449

@@ -121,7 +116,7 @@ impl MemoryManagementArch for X86_64MMArch {
121116
const USER_STACK_START: VirtAddr = VirtAddr::new(0x6ffff0a00000);
122117

123118
/// @brief 获取物理内存区域
124-
unsafe fn init() -> &'static [crate::mm::PhysMemoryArea] {
119+
unsafe fn init() {
125120
extern "C" {
126121
fn _text();
127122
fn _etext();
@@ -147,12 +142,9 @@ impl MemoryManagementArch for X86_64MMArch {
147142
}
148143

149144
// 初始化物理内存区域(从multiboot2中获取)
150-
let areas_count =
151-
Self::init_memory_area_from_multiboot2().expect("init memory area failed");
145+
Self::init_memory_area_from_multiboot2().expect("init memory area failed");
152146

153147
send_to_default_serial8250_port("x86 64 init end\n\0".as_bytes());
154-
155-
return &PHYS_MEMORY_AREAS[0..areas_count];
156148
}
157149

158150
/// @brief 刷新TLB中,关于指定虚拟地址的条目
@@ -336,9 +328,24 @@ impl X86_64MMArch {
336328
if mb2_mem_info[i].len == 0 {
337329
continue;
338330
}
331+
339332
total_mem_size += mb2_mem_info[i].len as usize;
340-
PHYS_MEMORY_AREAS[areas_count].base = PhysAddr::new(mb2_mem_info[i].addr as usize);
341-
PHYS_MEMORY_AREAS[areas_count].size = mb2_mem_info[i].len as usize;
333+
// PHYS_MEMORY_AREAS[areas_count].base = PhysAddr::new(mb2_mem_info[i].addr as usize);
334+
// PHYS_MEMORY_AREAS[areas_count].size = mb2_mem_info[i].len as usize;
335+
336+
mem_block_manager()
337+
.add_block(
338+
PhysAddr::new(mb2_mem_info[i].addr as usize),
339+
mb2_mem_info[i].len as usize,
340+
)
341+
.unwrap_or_else(|e| {
342+
kwarn!(
343+
"Failed to add memory block: base={:#x}, size={:#x}, error={:?}",
344+
mb2_mem_info[i].addr,
345+
mb2_mem_info[i].len,
346+
e
347+
);
348+
});
342349
areas_count += 1;
343350
}
344351
}
@@ -412,9 +419,7 @@ unsafe fn allocator_init() {
412419
let phy_offset =
413420
unsafe { MMArch::virt_2_phys(VirtAddr::new(page_align_up(virt_offset))) }.unwrap();
414421

415-
kdebug!("PhysArea[0..10] = {:?}", &PHYS_MEMORY_AREAS[0..10]);
416-
let mut bump_allocator =
417-
BumpAllocator::<X86_64MMArch>::new(&PHYS_MEMORY_AREAS, phy_offset.data());
422+
let mut bump_allocator = BumpAllocator::<X86_64MMArch>::new(phy_offset.data());
418423
kdebug!(
419424
"BumpAllocator created, offset={:?}",
420425
bump_allocator.offset()
@@ -450,7 +455,9 @@ unsafe fn allocator_init() {
450455
}
451456
kdebug!("Successfully emptied page table");
452457

453-
for area in PHYS_MEMORY_AREAS.iter() {
458+
let total_num = mem_block_manager().total_initial_memory_regions();
459+
for i in 0..total_num {
460+
let area = mem_block_manager().get_initial_memory_region(i).unwrap();
454461
// kdebug!("area: base={:?}, size={:#x}, end={:?}", area.base, area.size, area.base + area.size);
455462
for i in 0..((area.size + MMArch::PAGE_SIZE - 1) / MMArch::PAGE_SIZE) {
456463
let paddr = area.base.add(i * MMArch::PAGE_SIZE);

kernel/src/arch/x86_64/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ mod c_adapter;
55
pub mod cpu;
66
pub mod driver;
77
pub mod fpu;
8+
pub mod init;
89
pub mod interrupt;
910
pub mod ipc;
1011
pub mod kvm;

kernel/src/driver/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ pub mod base;
33
pub mod disk;
44
pub mod keyboard;
55
pub mod net;
6+
pub mod open_firmware;
67
pub mod pci;
78
pub mod timers;
89
pub mod tty;

0 commit comments

Comments
 (0)