-amend
This commit is contained in:
parent
2a2f377b9f
commit
0f5bf89493
2 changed files with 93 additions and 0 deletions
74
kernel-rs/src/memory/area_allocator.rs
Normal file
74
kernel-rs/src/memory/area_allocator.rs
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
use memory::*;
|
||||
use multiboot2::{MemoryAreaIter, MemoryArea};
|
||||
|
||||
pub struct AreaAllocator {
|
||||
next_free_frame: Frame,
|
||||
current_area: Option<&'static MemoryArea>,
|
||||
areas: MemoryAreaIter,
|
||||
kernel_start: Frame,
|
||||
kernel_end: Frame,
|
||||
multiboot_start: Frame,
|
||||
multiboot_end: Frame,
|
||||
}
|
||||
|
||||
impl AreaFrameAllocator {
|
||||
pub fn new(kernel_start: usize, kernel_end: usize
|
||||
multiboot_start: usize, multiboot_end: usize
|
||||
memory_areas: MemoryAreaIter) -> AreaAllocator {
|
||||
let mut allocator = AreaAllocator {
|
||||
next_free_frame: Frame::containing_address(0),
|
||||
current_area: None,
|
||||
areas: memory_areas,
|
||||
kernel_start: Frame::containing_address(kernel_start),
|
||||
kernel_end: Frame::containing_address(kernel_end),
|
||||
multiboot_start: Frame::containing_address(multiboot_start),
|
||||
multiboot_end: Frame::containing_address(multiboot_end),
|
||||
}
|
||||
allocator.choose_next_area();
|
||||
allocator
|
||||
}
|
||||
|
||||
fn choose_next_area(&mut self) {
|
||||
// get next area with free frames
|
||||
self.current_area = self.areas.clone().filter(|area| {
|
||||
Frame::containing_address(area.end_address()) >= self.next_free_frame
|
||||
}).min_by_key(|area| area.start_addr());
|
||||
|
||||
if let Some(area) = self.current_area {
|
||||
let start_frame = Frame::containing_address(area.start_addr());
|
||||
if self.next_free_frame < start_frame {
|
||||
self.next_free_frame = start_frame;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FrameAllocator for AreaFrameAllocator {
|
||||
fn allocate_frame(&mut self) -> Option<Frame> {
|
||||
if let Some(area) = sef.current_area {
|
||||
let frame = Frame { number: self.next_free_frame.number },
|
||||
let current_area_last_frame = Frame::containing_address(area.end_address());
|
||||
if frame > current_area_last_frame {
|
||||
// all frames are taken in this area
|
||||
self.choose_next_area();
|
||||
} else if frame >= self.kernel_start && frame <= kernel_end {
|
||||
// frame used by kernel
|
||||
self.next_free_frame = Frame {
|
||||
number: self.kernel_end.number + 1;
|
||||
}
|
||||
} else if frame >= self.multiboot_start && frame <= multiboot_end {
|
||||
// frame used by multiboot
|
||||
self.next_free_frame = Frame {
|
||||
number: self.multiboot_end.number + 1;
|
||||
}
|
||||
} else {
|
||||
self.next_free_frame_number += 1;
|
||||
return Some(Frame);
|
||||
}
|
||||
} else { None }
|
||||
}
|
||||
|
||||
fn deallocate_frame(&mut self, frame: Frame) {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
19
kernel-rs/src/memory/mod.rs
Normal file
19
kernel-rs/src/memory/mod.rs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
pub const PAGE_SIZE: usize = 4096;
|
||||
|
||||
// pub use self::area_allocator::*;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct Frame {
|
||||
number: usize,
|
||||
}
|
||||
|
||||
impl Frame {
|
||||
fn containing_address(address: usize) -> Frame {
|
||||
Frame{ number: address / PAGE_SIZE }
|
||||
}
|
||||
}
|
||||
|
||||
pub trait FrameAllocator {
|
||||
fn allocate_frame(&mut self) -> Option<Frame>;
|
||||
fn deallocate_frame(&mut self, frame: Frame);
|
||||
}
|
||||
Loading…
Reference in a new issue