Initialize the memory system ## Returns The memory controller that servers a simple interface to manage the memory allocation.
(boot_info: &BootInformation)
| 19 | /// |
| 20 | /// The memory controller that servers a simple interface to manage the memory allocation. |
| 21 | pub fn init(boot_info: &BootInformation) -> MemoryController { |
| 22 | // insure that this function is only called once |
| 23 | assert_has_not_been_called!("memory::init must be called only once"); |
| 24 | |
| 25 | // get the bootloader memory tag |
| 26 | let memory_map_tag = boot_info.memory_map_tag().expect("Memory map tag required"); |
| 27 | |
| 28 | // get the elf sections bootloader tag |
| 29 | let elf_sections_tag = boot_info.elf_sections_tag().expect("Elf sections tag required"); |
| 30 | |
| 31 | // get the kernel start address |
| 32 | let kernel_start = elf_sections_tag.sections().map(|s| s.addr).min().unwrap(); |
| 33 | |
| 34 | // get the kernel end address |
| 35 | let kernel_end = elf_sections_tag.sections().map(|s| s.addr + s.size).max().unwrap(); |
| 36 | |
| 37 | // initialize the frame allocator |
| 38 | let mut frame_allocator = AreaFrameAllocator::new(kernel_start as usize, |
| 39 | kernel_end as usize, |
| 40 | boot_info.start_address(), |
| 41 | boot_info.end_address(), |
| 42 | memory_map_tag.memory_areas()); |
| 43 | // remap the kernel |
| 44 | let mut active_table = remap_the_kernel(&mut frame_allocator, boot_info); |
| 45 | |
| 46 | // remap heap |
| 47 | use self::paging::Page; |
| 48 | use hole_list_allocator::{HEAP_START, HEAP_SIZE}; |
| 49 | |
| 50 | let heap_start_page = Page::containing_address(HEAP_START); |
| 51 | let heap_end_page = Page::containing_address(HEAP_START + HEAP_SIZE - 1); |
| 52 | |
| 53 | for page in Page::range_inclusive(heap_start_page, heap_end_page) { |
| 54 | active_table.map(page, paging::WRITABLE, &mut frame_allocator); |
| 55 | } |
| 56 | |
| 57 | // remap Stack |
| 58 | let stack_allocator = { |
| 59 | // calculate the start and end address of the stack |
| 60 | let stack_alloc_start = heap_end_page + 1; |
| 61 | let stack_alloc_end = stack_alloc_start + 100; |
| 62 | |
| 63 | // create a new page range with the stack start address and end address |
| 64 | let stack_alloc_range = Page::range_inclusive(stack_alloc_start, stack_alloc_end); |
| 65 | |
| 66 | // create a StackAllocator instance |
| 67 | stack_allocator::StackAllocator::new(stack_alloc_range) |
| 68 | }; |
| 69 | |
| 70 | MemoryController { |
| 71 | active_table: active_table, |
| 72 | frame_allocator: frame_allocator, |
| 73 | stack_allocator: stack_allocator |
| 74 | } |
| 75 | } |
| 76 | |
| 77 | #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)] |
| 78 | pub struct Frame { |
no test coverage detected