140fe15e0SLoGin use crate::{ 240fe15e0SLoGin arch::mm::LockedFrameAllocator, 340fe15e0SLoGin libs::align::page_align_up, 440fe15e0SLoGin mm::{MMArch, MemoryManagementArch, VirtAddr}, 540fe15e0SLoGin }; 640fe15e0SLoGin 740fe15e0SLoGin use core::{ 840fe15e0SLoGin alloc::{AllocError, GlobalAlloc, Layout}, 940fe15e0SLoGin intrinsics::unlikely, 1040fe15e0SLoGin ptr::NonNull, 1140fe15e0SLoGin }; 1240fe15e0SLoGin 1340fe15e0SLoGin use super::page_frame::{FrameAllocator, PageFrameCount}; 1440fe15e0SLoGin 1540fe15e0SLoGin /// 类kmalloc的分配器应当实现的trait 1640fe15e0SLoGin pub trait LocalAlloc { 1740fe15e0SLoGin unsafe fn local_alloc(&self, layout: Layout) -> *mut u8; 1840fe15e0SLoGin unsafe fn local_alloc_zeroed(&self, layout: Layout) -> *mut u8; 1940fe15e0SLoGin unsafe fn local_dealloc(&self, ptr: *mut u8, layout: Layout); 2040fe15e0SLoGin } 2140fe15e0SLoGin 2240fe15e0SLoGin pub struct KernelAllocator; 2340fe15e0SLoGin 2440fe15e0SLoGin impl KernelAllocator { 2540fe15e0SLoGin unsafe fn alloc_in_buddy(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> { 2640fe15e0SLoGin // 计算需要申请的页数,向上取整 2740fe15e0SLoGin let count = (page_align_up(layout.size()) / MMArch::PAGE_SIZE).next_power_of_two(); 2840fe15e0SLoGin let page_frame_count = PageFrameCount::new(count); 2940fe15e0SLoGin let (phy_addr, allocated_frame_count) = LockedFrameAllocator 3040fe15e0SLoGin .allocate(page_frame_count) 3140fe15e0SLoGin .ok_or(AllocError)?; 3240fe15e0SLoGin 3340fe15e0SLoGin let virt_addr = unsafe { MMArch::phys_2_virt(phy_addr).ok_or(AllocError)? }; 3440fe15e0SLoGin if unlikely(virt_addr.is_null()) { 3540fe15e0SLoGin return Err(AllocError); 3640fe15e0SLoGin } 3740fe15e0SLoGin 3840fe15e0SLoGin let slice = unsafe { 3940fe15e0SLoGin core::slice::from_raw_parts_mut( 4040fe15e0SLoGin virt_addr.data() as *mut u8, 4140fe15e0SLoGin allocated_frame_count.data() * MMArch::PAGE_SIZE, 4240fe15e0SLoGin ) 4340fe15e0SLoGin }; 4440fe15e0SLoGin return Ok(NonNull::from(slice)); 4540fe15e0SLoGin } 4640fe15e0SLoGin 4740fe15e0SLoGin unsafe fn free_in_buddy(&self, ptr: *mut u8, layout: Layout) { 4840fe15e0SLoGin // 由于buddy分配的页数量是2的幂,因此释放的时候也需要按照2的幂向上取整。 4940fe15e0SLoGin let count = (page_align_up(layout.size()) / MMArch::PAGE_SIZE).next_power_of_two(); 5040fe15e0SLoGin let page_frame_count = PageFrameCount::new(count); 5140fe15e0SLoGin let phy_addr = MMArch::virt_2_phys(VirtAddr::new(ptr as usize)).unwrap(); 5240fe15e0SLoGin LockedFrameAllocator.free(phy_addr, page_frame_count); 5340fe15e0SLoGin } 5440fe15e0SLoGin } 5540fe15e0SLoGin 5640fe15e0SLoGin /// 为内核SLAB分配器实现LocalAlloc的trait 5740fe15e0SLoGin impl LocalAlloc for KernelAllocator { 5840fe15e0SLoGin unsafe fn local_alloc(&self, layout: Layout) -> *mut u8 { 5940fe15e0SLoGin return self 6040fe15e0SLoGin .alloc_in_buddy(layout) 6140fe15e0SLoGin .map(|x| x.as_mut_ptr() as *mut u8) 6240fe15e0SLoGin .unwrap_or(core::ptr::null_mut() as *mut u8); 6340fe15e0SLoGin } 6440fe15e0SLoGin 6540fe15e0SLoGin unsafe fn local_alloc_zeroed(&self, layout: Layout) -> *mut u8 { 6640fe15e0SLoGin return self 6740fe15e0SLoGin .alloc_in_buddy(layout) 6840fe15e0SLoGin .map(|x| { 6940fe15e0SLoGin let ptr: *mut u8 = x.as_mut_ptr(); 7040fe15e0SLoGin core::ptr::write_bytes(ptr, 0, x.len()); 7140fe15e0SLoGin ptr 7240fe15e0SLoGin }) 7340fe15e0SLoGin .unwrap_or(core::ptr::null_mut() as *mut u8); 7440fe15e0SLoGin } 7540fe15e0SLoGin 7640fe15e0SLoGin unsafe fn local_dealloc(&self, ptr: *mut u8, layout: Layout) { 7740fe15e0SLoGin self.free_in_buddy(ptr, layout); 7840fe15e0SLoGin } 7940fe15e0SLoGin } 8040fe15e0SLoGin 8140fe15e0SLoGin /// 为内核slab分配器实现GlobalAlloc特性 8240fe15e0SLoGin unsafe impl GlobalAlloc for KernelAllocator { 8340fe15e0SLoGin unsafe fn alloc(&self, layout: Layout) -> *mut u8 { 8440fe15e0SLoGin return self.local_alloc(layout); 8540fe15e0SLoGin // self.local_alloc_zeroed(layout, 0) 8640fe15e0SLoGin } 8740fe15e0SLoGin 8840fe15e0SLoGin unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { 8940fe15e0SLoGin self.local_alloc_zeroed(layout) 9040fe15e0SLoGin } 9140fe15e0SLoGin 9240fe15e0SLoGin unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { 9340fe15e0SLoGin self.local_dealloc(ptr, layout); 9440fe15e0SLoGin } 9540fe15e0SLoGin } 9640fe15e0SLoGin 97*40314b30SXiaoye Zheng /// 为内核slab分配器实现Allocator特性 98*40314b30SXiaoye Zheng // unsafe impl Allocator for KernelAllocator { 99*40314b30SXiaoye Zheng // fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> { 100*40314b30SXiaoye Zheng // let memory = unsafe {self.local_alloc(layout)}; 101*40314b30SXiaoye Zheng // if memory.is_null() { 102*40314b30SXiaoye Zheng // Err(AllocError) 103*40314b30SXiaoye Zheng // } else { 104*40314b30SXiaoye Zheng // let slice = unsafe { core::slice::from_raw_parts_mut(memory, layout.size()) }; 105*40314b30SXiaoye Zheng // Ok(unsafe { NonNull::new_unchecked(slice) }) 106*40314b30SXiaoye Zheng // } 107*40314b30SXiaoye Zheng // } 108*40314b30SXiaoye Zheng 109*40314b30SXiaoye Zheng // fn allocate_zeroed(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> { 110*40314b30SXiaoye Zheng // let memory = unsafe {self.local_alloc_zeroed(layout)}; 111*40314b30SXiaoye Zheng // if memory.is_null() { 112*40314b30SXiaoye Zheng // Err(AllocError) 113*40314b30SXiaoye Zheng // } else { 114*40314b30SXiaoye Zheng // let slice = unsafe { core::slice::from_raw_parts_mut(memory, layout.size()) }; 115*40314b30SXiaoye Zheng // Ok(unsafe { NonNull::new_unchecked(slice) }) 116*40314b30SXiaoye Zheng // } 117*40314b30SXiaoye Zheng // } 118*40314b30SXiaoye Zheng 119*40314b30SXiaoye Zheng // unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) { 120*40314b30SXiaoye Zheng // self.local_dealloc(ptr.cast().as_ptr(), layout); 121*40314b30SXiaoye Zheng // } 122*40314b30SXiaoye Zheng // } 123*40314b30SXiaoye Zheng 12440fe15e0SLoGin /// 内存分配错误处理函数 125fba56231SLoGin #[cfg(target_os = "none")] 12640fe15e0SLoGin #[alloc_error_handler] 12740fe15e0SLoGin pub fn global_alloc_err_handler(layout: Layout) -> ! { 12840fe15e0SLoGin panic!("global_alloc_error, layout: {:?}", layout); 12940fe15e0SLoGin } 130