use linked_list_allocator::LockedHeap; use x86_64::{ structures::paging::{ mapper::MapToError, FrameAllocator, Mapper, Page, PageTableFlags, Size4KiB, }, VirtAddr, }; /// We are currently using a linked list heap allocator which uses our underlying page allocator. pub type FoundryAllocator = LockedHeap; #[global_allocator] /// This is now Rust's global allocator, so we can use stuff requiring heap allocations. static ALLOCATOR: FoundryAllocator = FoundryAllocator::empty(); pub const HEAP_START: usize = 0x4444_4444_0000; pub const HEAP_SIZE: usize = 1000 * 1024; /// Sets up the heap using the backing page frame allocator. pub fn init_heap( mapper: &mut impl Mapper, frame_allocator: &mut impl FrameAllocator, ) -> Result<(), MapToError> { let range = { let heap_start = VirtAddr::new(HEAP_START as u64); let heap_end = heap_start + HEAP_SIZE as u64 - 1u64; let heap_start_page = Page::::containing_address(heap_start); let heap_end_page = Page::::containing_address(heap_end); Page::range_inclusive(heap_start_page, heap_end_page) }; for page in range { let frame = frame_allocator .allocate_frame() .ok_or(MapToError::FrameAllocationFailed)?; let flags = PageTableFlags::PRESENT | PageTableFlags::WRITABLE; unsafe { mapper.map_to(page, frame, flags, frame_allocator)?.flush() }; } unsafe { ALLOCATOR.lock().init(HEAP_START as *mut u8, HEAP_SIZE); } Ok(()) }