allocator.rs
1 use alloc::alloc::{GlobalAlloc, Layout}; 2 use core::ptr::null_mut; 3 use x86_64::{ 4 structures::paging::{ 5 mapper::MapToError, FrameAllocator, Mapper, Page, PageTableFlags, Size4KiB, 6 }, 7 VirtAddr, 8 }; 9 use fixed_size_block::FixedSizeBlockAllocator; 10 11 pub mod bump; 12 pub mod linked_list; 13 pub mod fixed_size_block; 14 15 pub const HEAP_START: usize = 0x_4444_4444_0000; 16 pub const HEAP_SIZE: usize = 100 * 1024; 17 18 pub fn init_heap( 19 mapper: &mut impl Mapper<Size4KiB>, 20 frame_allocator: &mut impl FrameAllocator<Size4KiB>, 21 ) -> Result<(), MapToError<Size4KiB>> { 22 let page_range = { 23 let heap_start = VirtAddr::new(HEAP_START as u64); 24 let heap_end = heap_start + HEAP_SIZE - 1u64; 25 let heap_start_page = Page::containing_address(heap_start); 26 let heap_end_page = Page::containing_address(heap_end); 27 Page::range_inclusive(heap_start_page, heap_end_page) 28 }; 29 30 for page in page_range { 31 let frame = frame_allocator 32 .allocate_frame() 33 .ok_or(MapToError::FrameAllocationFailed)?; 34 let flags = PageTableFlags::PRESENT | PageTableFlags::WRITABLE; 35 unsafe { 36 mapper.map_to(page, frame, flags, frame_allocator)?.flush() 37 }; 38 } 39 40 unsafe { 41 ALLOCATOR.lock().init(HEAP_START, HEAP_SIZE); 42 } 43 44 Ok(()) 45 } 46 47 48 pub struct Dummy; 49 50 unsafe impl GlobalAlloc for Dummy { 51 unsafe fn alloc(&self, _layout: Layout) -> *mut u8 { 52 null_mut() 53 } 54 55 unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) { 56 panic!("dealloc should be never called") 57 } 58 } 59 60 pub struct Locked<A> { 61 inner: spin::Mutex<A>, 62 } 63 64 impl<A> Locked<A> { 65 pub const fn new(inner: A) -> Self { 66 Locked { 67 inner: spin::Mutex::new(inner), 68 } 69 } 70 71 pub fn lock(&self) -> spin::MutexGuard<A> { 72 self.inner.lock() 73 } 74 } 75 76 fn align_up(addr: usize, align: usize) -> usize { 77 let remainder = addr % align; 78 if remainder == 0 { 79 addr 80 } else { 81 addr - remainder + align 82 } 83 } 84 85 #[global_allocator] 86 static ALLOCATOR: Locked<FixedSizeBlockAllocator> = Locked::new( 87 FixedSizeBlockAllocator::new());