Skip to content

Commit 34ffa7f

Browse files
committed
feat: implement BootInfoFrameAllocator
1 parent 39b9920 commit 34ffa7f

File tree

2 files changed

+43
-14
lines changed

2 files changed

+43
-14
lines changed

src/main.rs

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,28 @@
77
use bootloader::{BootInfo, entry_point};
88
use core::panic::PanicInfo;
99
use osdev_rust::println;
10-
use x86_64::structures::paging::Translate;
1110

1211
entry_point!(kernel_main);
1312

1413
fn kernel_main(boot_info: &'static BootInfo) -> ! {
1514
use osdev_rust::memory;
16-
use x86_64::VirtAddr;
15+
use osdev_rust::memory::BootInfoFrameAllocator;
16+
use x86_64::{VirtAddr, structures::paging::Page};
1717

1818
println!("Hello World!");
1919

2020
osdev_rust::init();
2121

2222
let phys_mem_offset = VirtAddr::new(boot_info.physical_memory_offset);
23-
let mapper = unsafe { memory::init(phys_mem_offset) };
24-
let addresses = [
25-
0xb8000,
26-
0x201008,
27-
0x0100_0020_1a10,
28-
boot_info.physical_memory_offset,
29-
];
30-
31-
for &address in &addresses {
32-
let virt = VirtAddr::new(address);
33-
let phys = mapper.translate_addr(virt);
34-
println!("{:?} -> {:?}", virt, phys);
23+
let mut mapper = unsafe { memory::init(phys_mem_offset) };
24+
let mut frame_allocator = unsafe { BootInfoFrameAllocator::init(&boot_info.memory_map) };
25+
26+
let page = Page::containing_address(VirtAddr::new(0xdeadbeef000));
27+
memory::create_example_mapping(page, &mut mapper, &mut frame_allocator);
28+
29+
let page_ptr: *mut u64 = page.start_address().as_mut_ptr();
30+
unsafe {
31+
page_ptr.offset(400).write_volatile(0x_f021_f077_f065_f04e);
3532
}
3633

3734
#[cfg(test)]

src/memory.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use core::panic;
22

3+
use bootloader::bootinfo::{MemoryMap, MemoryRegionType};
34
use x86_64::{
45
PhysAddr, VirtAddr,
56
structures::paging::{
@@ -49,6 +50,37 @@ unsafe impl FrameAllocator<Size4KiB> for EmptyFrameAllocator {
4950
}
5051
}
5152

53+
pub struct BootInfoFrameAllocator {
54+
memory_map: &'static MemoryMap,
55+
next: usize,
56+
}
57+
58+
impl BootInfoFrameAllocator {
59+
pub unsafe fn init(memory_map: &'static MemoryMap) -> Self {
60+
BootInfoFrameAllocator {
61+
memory_map,
62+
next: 0,
63+
}
64+
}
65+
66+
fn usable_frames(&self) -> impl Iterator<Item = PhysFrame> {
67+
let regions = self.memory_map.iter();
68+
let usable_regions = regions.filter(|r| r.region_type == MemoryRegionType::Usable);
69+
let addr_ranges = usable_regions.map(|r| r.range.start_addr()..r.range.end_addr());
70+
let frame_addresses = addr_ranges.flat_map(|r| r.step_by(4096));
71+
72+
frame_addresses.map(|addr| PhysFrame::containing_address(PhysAddr::new(addr)))
73+
}
74+
}
75+
76+
unsafe impl FrameAllocator<Size4KiB> for BootInfoFrameAllocator {
77+
fn allocate_frame(&mut self) -> Option<PhysFrame> {
78+
let frame = self.usable_frames().nth(self.next);
79+
self.next += 1;
80+
frame
81+
}
82+
}
83+
5284
pub unsafe fn translate_addr(addr: VirtAddr, physical_memory_offset: VirtAddr) -> Option<PhysAddr> {
5385
translate_addr_inner(addr, physical_memory_offset)
5486
}

0 commit comments

Comments
 (0)