1*7b32f508SLoGin use klog_types::AllocLogItem; 2*7b32f508SLoGin 340fe15e0SLoGin use crate::{ 440fe15e0SLoGin arch::mm::LockedFrameAllocator, 5*7b32f508SLoGin debug::klog::mm::mm_debug_log, 640fe15e0SLoGin libs::align::page_align_up, 740fe15e0SLoGin mm::{MMArch, MemoryManagementArch, VirtAddr}, 840fe15e0SLoGin }; 940fe15e0SLoGin 1040fe15e0SLoGin use core::{ 1140fe15e0SLoGin alloc::{AllocError, GlobalAlloc, Layout}, 1240fe15e0SLoGin intrinsics::unlikely, 1340fe15e0SLoGin ptr::NonNull, 1440fe15e0SLoGin }; 1540fe15e0SLoGin 1640fe15e0SLoGin use super::page_frame::{FrameAllocator, PageFrameCount}; 1740fe15e0SLoGin 1840fe15e0SLoGin /// 类kmalloc的分配器应当实现的trait 1940fe15e0SLoGin pub trait LocalAlloc { 2040fe15e0SLoGin unsafe fn local_alloc(&self, layout: Layout) -> *mut u8; 2140fe15e0SLoGin unsafe fn local_alloc_zeroed(&self, layout: Layout) -> *mut u8; 2240fe15e0SLoGin unsafe fn local_dealloc(&self, ptr: *mut u8, layout: Layout); 2340fe15e0SLoGin } 2440fe15e0SLoGin 2540fe15e0SLoGin pub struct KernelAllocator; 2640fe15e0SLoGin 2740fe15e0SLoGin impl KernelAllocator { 2840fe15e0SLoGin unsafe fn alloc_in_buddy(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> { 2940fe15e0SLoGin // 计算需要申请的页数,向上取整 3040fe15e0SLoGin let count = (page_align_up(layout.size()) / MMArch::PAGE_SIZE).next_power_of_two(); 3140fe15e0SLoGin let page_frame_count = PageFrameCount::new(count); 3240fe15e0SLoGin let (phy_addr, allocated_frame_count) = LockedFrameAllocator 3340fe15e0SLoGin .allocate(page_frame_count) 3440fe15e0SLoGin .ok_or(AllocError)?; 3540fe15e0SLoGin 3640fe15e0SLoGin let virt_addr = unsafe { MMArch::phys_2_virt(phy_addr).ok_or(AllocError)? }; 3740fe15e0SLoGin if unlikely(virt_addr.is_null()) { 3840fe15e0SLoGin return Err(AllocError); 3940fe15e0SLoGin } 4040fe15e0SLoGin 4140fe15e0SLoGin let slice = unsafe { 4240fe15e0SLoGin core::slice::from_raw_parts_mut( 4340fe15e0SLoGin virt_addr.data() as *mut u8, 4440fe15e0SLoGin allocated_frame_count.data() * MMArch::PAGE_SIZE, 4540fe15e0SLoGin ) 4640fe15e0SLoGin }; 4740fe15e0SLoGin return Ok(NonNull::from(slice)); 4840fe15e0SLoGin } 4940fe15e0SLoGin 5040fe15e0SLoGin unsafe fn free_in_buddy(&self, ptr: *mut u8, layout: Layout) { 5140fe15e0SLoGin // 由于buddy分配的页数量是2的幂,因此释放的时候也需要按照2的幂向上取整。 5240fe15e0SLoGin let count = (page_align_up(layout.size()) / MMArch::PAGE_SIZE).next_power_of_two(); 5340fe15e0SLoGin let page_frame_count = PageFrameCount::new(count); 5440fe15e0SLoGin let phy_addr = MMArch::virt_2_phys(VirtAddr::new(ptr as usize)).unwrap(); 5540fe15e0SLoGin LockedFrameAllocator.free(phy_addr, page_frame_count); 5640fe15e0SLoGin } 5740fe15e0SLoGin } 5840fe15e0SLoGin 5940fe15e0SLoGin /// 为内核SLAB分配器实现LocalAlloc的trait 6040fe15e0SLoGin impl LocalAlloc for KernelAllocator { 6140fe15e0SLoGin unsafe fn local_alloc(&self, layout: Layout) -> *mut u8 { 6240fe15e0SLoGin return self 6340fe15e0SLoGin .alloc_in_buddy(layout) 6440fe15e0SLoGin .map(|x| x.as_mut_ptr() as *mut u8) 6540fe15e0SLoGin .unwrap_or(core::ptr::null_mut() as *mut u8); 6640fe15e0SLoGin } 6740fe15e0SLoGin 6840fe15e0SLoGin unsafe fn local_alloc_zeroed(&self, layout: Layout) -> *mut u8 { 6940fe15e0SLoGin return self 7040fe15e0SLoGin .alloc_in_buddy(layout) 7140fe15e0SLoGin .map(|x| { 7240fe15e0SLoGin let ptr: *mut u8 = x.as_mut_ptr(); 7340fe15e0SLoGin core::ptr::write_bytes(ptr, 0, x.len()); 7440fe15e0SLoGin ptr 7540fe15e0SLoGin }) 7640fe15e0SLoGin .unwrap_or(core::ptr::null_mut() as *mut u8); 7740fe15e0SLoGin } 7840fe15e0SLoGin 7940fe15e0SLoGin unsafe fn local_dealloc(&self, ptr: *mut u8, layout: Layout) { 8040fe15e0SLoGin self.free_in_buddy(ptr, layout); 8140fe15e0SLoGin } 8240fe15e0SLoGin } 8340fe15e0SLoGin 8440fe15e0SLoGin /// 为内核slab分配器实现GlobalAlloc特性 8540fe15e0SLoGin unsafe impl GlobalAlloc for KernelAllocator { 8640fe15e0SLoGin unsafe fn alloc(&self, layout: Layout) -> *mut u8 { 87*7b32f508SLoGin let r = self.local_alloc(layout); 88*7b32f508SLoGin mm_debug_log( 89*7b32f508SLoGin klog_types::AllocatorLogType::Alloc(AllocLogItem::new( 90*7b32f508SLoGin layout.clone(), 91*7b32f508SLoGin Some(r as usize), 92*7b32f508SLoGin None, 93*7b32f508SLoGin )), 94*7b32f508SLoGin klog_types::LogSource::Buddy, 95*7b32f508SLoGin ); 96*7b32f508SLoGin 97*7b32f508SLoGin return r; 98*7b32f508SLoGin 9940fe15e0SLoGin // self.local_alloc_zeroed(layout, 0) 10040fe15e0SLoGin } 10140fe15e0SLoGin 10240fe15e0SLoGin unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { 103*7b32f508SLoGin let r = self.local_alloc_zeroed(layout); 104*7b32f508SLoGin 105*7b32f508SLoGin mm_debug_log( 106*7b32f508SLoGin klog_types::AllocatorLogType::AllocZeroed(AllocLogItem::new( 107*7b32f508SLoGin layout.clone(), 108*7b32f508SLoGin Some(r as usize), 109*7b32f508SLoGin None, 110*7b32f508SLoGin )), 111*7b32f508SLoGin klog_types::LogSource::Buddy, 112*7b32f508SLoGin ); 113*7b32f508SLoGin 114*7b32f508SLoGin return r; 11540fe15e0SLoGin } 11640fe15e0SLoGin 11740fe15e0SLoGin unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { 118*7b32f508SLoGin mm_debug_log( 119*7b32f508SLoGin klog_types::AllocatorLogType::Free(AllocLogItem::new( 120*7b32f508SLoGin layout.clone(), 121*7b32f508SLoGin Some(ptr as usize), 122*7b32f508SLoGin None, 123*7b32f508SLoGin )), 124*7b32f508SLoGin klog_types::LogSource::Buddy, 125*7b32f508SLoGin ); 126*7b32f508SLoGin 12740fe15e0SLoGin self.local_dealloc(ptr, layout); 12840fe15e0SLoGin } 12940fe15e0SLoGin } 13040fe15e0SLoGin 13140314b30SXiaoye Zheng /// 为内核slab分配器实现Allocator特性 13240314b30SXiaoye Zheng // unsafe impl Allocator for KernelAllocator { 13340314b30SXiaoye Zheng // fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> { 13440314b30SXiaoye Zheng // let memory = unsafe {self.local_alloc(layout)}; 13540314b30SXiaoye Zheng // if memory.is_null() { 13640314b30SXiaoye Zheng // Err(AllocError) 13740314b30SXiaoye Zheng // } else { 13840314b30SXiaoye Zheng // let slice = unsafe { core::slice::from_raw_parts_mut(memory, layout.size()) }; 13940314b30SXiaoye Zheng // Ok(unsafe { NonNull::new_unchecked(slice) }) 14040314b30SXiaoye Zheng // } 14140314b30SXiaoye Zheng // } 14240314b30SXiaoye Zheng 14340314b30SXiaoye Zheng // fn allocate_zeroed(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> { 14440314b30SXiaoye Zheng // let memory = unsafe {self.local_alloc_zeroed(layout)}; 14540314b30SXiaoye Zheng // if memory.is_null() { 14640314b30SXiaoye Zheng // Err(AllocError) 14740314b30SXiaoye Zheng // } else { 14840314b30SXiaoye Zheng // let slice = unsafe { core::slice::from_raw_parts_mut(memory, layout.size()) }; 14940314b30SXiaoye Zheng // Ok(unsafe { NonNull::new_unchecked(slice) }) 15040314b30SXiaoye Zheng // } 15140314b30SXiaoye Zheng // } 15240314b30SXiaoye Zheng 15340314b30SXiaoye Zheng // unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) { 15440314b30SXiaoye Zheng // self.local_dealloc(ptr.cast().as_ptr(), layout); 15540314b30SXiaoye Zheng // } 15640314b30SXiaoye Zheng // } 15740314b30SXiaoye Zheng 15840fe15e0SLoGin /// 内存分配错误处理函数 159fba56231SLoGin #[cfg(target_os = "none")] 16040fe15e0SLoGin #[alloc_error_handler] 16140fe15e0SLoGin pub fn global_alloc_err_handler(layout: Layout) -> ! { 16240fe15e0SLoGin panic!("global_alloc_error, layout: {:?}", layout); 16340fe15e0SLoGin } 164