mirror of
https://github.com/phil-opp/blog_os.git
synced 2025-12-16 22:37:49 +00:00
Add a FrameAllocator trait
This commit is contained in:
@@ -200,6 +200,16 @@ impl Frame {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
We also add a `FrameAllocator` trait:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
pub trait FrameAllocator {
|
||||||
|
fn allocate_frame(&mut self) -> Option<Frame>;
|
||||||
|
fn deallocate_frame(&mut self, frame: Frame);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
This allows us to create another, more advanced frame allocator in the future.
|
||||||
|
|
||||||
### The Allocator
|
### The Allocator
|
||||||
Now we can put everything together and create the frame allocator. It looks like this:
|
Now we can put everything together and create the frame allocator. It looks like this:
|
||||||
|
|
||||||
@@ -248,7 +258,7 @@ fn choose_next_area(&mut self) {
|
|||||||
```
|
```
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
pub fn allocate_frame(&mut self) -> Option<Frame> {
|
fn allocate_frame(&mut self) -> Option<Frame> {
|
||||||
match self.current_area {
|
match self.current_area {
|
||||||
None => None,
|
None => None,
|
||||||
Some(area) => {
|
Some(area) => {
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ pub extern fn rust_main(multiboot_information_address: usize) {
|
|||||||
kernel_end as usize, multiboot_start, multiboot_end, memory_map_tag.memory_areas());
|
kernel_end as usize, multiboot_start, multiboot_end, memory_map_tag.memory_areas());
|
||||||
|
|
||||||
for i in 0.. {
|
for i in 0.. {
|
||||||
|
use memory::FrameAllocator;
|
||||||
if let None = frame_allocator.allocate_frame() {
|
if let None = frame_allocator.allocate_frame() {
|
||||||
println!("allocated {} frames", i);
|
println!("allocated {} frames", i);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use memory::Frame;
|
use memory::{Frame, FrameAllocator};
|
||||||
use multiboot2::{MemoryAreaIter, MemoryArea};
|
use multiboot2::{MemoryAreaIter, MemoryArea};
|
||||||
|
|
||||||
/// A frame allocator that uses the memory areas from the multiboot information structure as
|
/// A frame allocator that uses the memory areas from the multiboot information structure as
|
||||||
@@ -33,7 +33,16 @@ impl AreaFrameAllocator {
|
|||||||
allocator
|
allocator
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn allocate_frame(&mut self) -> Option<Frame> {
|
fn choose_next_area(&mut self) {
|
||||||
|
self.current_area = self.areas.clone().filter(|area| {
|
||||||
|
let address = area.base_addr + area.length - 1;
|
||||||
|
Frame::containing_address(address as usize) >= self.next_free_frame
|
||||||
|
}).min_by(|area| area.base_addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FrameAllocator for AreaFrameAllocator {
|
||||||
|
fn allocate_frame(&mut self) -> Option<Frame> {
|
||||||
match self.current_area {
|
match self.current_area {
|
||||||
None => None,
|
None => None,
|
||||||
Some(area) => {
|
Some(area) => {
|
||||||
@@ -58,10 +67,5 @@ impl AreaFrameAllocator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn choose_next_area(&mut self) {
|
fn deallocate_frame(&mut self, _frame: Frame) {unimplemented!()}
|
||||||
self.current_area = self.areas.clone().filter(|area| {
|
|
||||||
let address = area.base_addr + area.length - 1;
|
|
||||||
Frame::containing_address(address as usize) >= self.next_free_frame
|
|
||||||
}).min_by(|area| area.base_addr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,3 +14,8 @@ impl Frame {
|
|||||||
Frame{ number: address / PAGE_SIZE }
|
Frame{ number: address / PAGE_SIZE }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait FrameAllocator {
|
||||||
|
fn allocate_frame(&mut self) -> Option<Frame>;
|
||||||
|
fn deallocate_frame(&mut self, frame: Frame);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user