diff --git a/src/memory/mod.rs b/src/memory/mod.rs index d902d17a..e1355735 100644 --- a/src/memory/mod.rs +++ b/src/memory/mod.rs @@ -9,6 +9,7 @@ pub use self::area_frame_allocator::AreaFrameAllocator; pub use self::paging::remap_the_kernel; +pub use self::stack_allocator::Stack; use self::paging::PhysicalAddress; use multiboot2::BootInformation; @@ -18,7 +19,7 @@ mod stack_allocator; pub const PAGE_SIZE: usize = 4096; -pub fn init(boot_info: &BootInformation) { +pub fn init(boot_info: &BootInformation) -> MemoryController { assert_has_not_been_called!("memory::init must be called only once"); let memory_map_tag = boot_info.memory_map_tag().expect("Memory map tag required"); @@ -59,6 +60,34 @@ pub fn init(boot_info: &BootInformation) { for page in Page::range_inclusive(heap_start_page, heap_end_page) { active_table.map(page, paging::WRITABLE, &mut frame_allocator); } + + let stack_allocator = { + let stack_alloc_start = heap_end_page + 1; + let stack_alloc_end = stack_alloc_start + 100; + let stack_alloc_range = Page::range_inclusive(stack_alloc_start, stack_alloc_end); + stack_allocator::StackAllocator::new(stack_alloc_range) + }; + + MemoryController { + active_table: active_table, + frame_allocator: frame_allocator, + stack_allocator: stack_allocator, + } +} + +pub struct MemoryController { + active_table: paging::ActivePageTable, + frame_allocator: AreaFrameAllocator, + stack_allocator: stack_allocator::StackAllocator, +} + +impl MemoryController { + pub fn alloc_stack(&mut self, size_in_pages: usize) -> Option { + let &mut MemoryController { ref mut active_table, + ref mut frame_allocator, + ref mut stack_allocator } = self; + stack_allocator.alloc_stack(active_table, frame_allocator, size_in_pages) + } } #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)] diff --git a/src/memory/paging/mod.rs b/src/memory/paging/mod.rs index fc09945b..bd6dd6b2 100644 --- a/src/memory/paging/mod.rs +++ b/src/memory/paging/mod.rs @@ -11,7 +11,7 @@ pub use self::entry::*; use memory::{PAGE_SIZE, Frame, FrameAllocator}; use self::temporary_page::TemporaryPage; pub use self::mapper::Mapper; -use core::ops::{Deref, DerefMut}; +use core::ops::{Add, Deref, DerefMut}; use multiboot2::BootInformation; mod entry; @@ -62,6 +62,14 @@ impl Page { } } +impl Add for Page { + type Output = Page; + + fn add(self, rhs: usize) -> Page { + Page { number: self.number + rhs } + } +} + #[derive(Clone)] pub struct PageIter { start: Page,