17b32f508SLoGin use klog_types::AllocLogItem; 27b32f508SLoGin 340fe15e0SLoGin use crate::{ 440fe15e0SLoGin arch::mm::LockedFrameAllocator, 57b32f508SLoGin 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 59453452ccSLoGin /// 为内核分配器实现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) 64*b5b571e0SLoGin .map(|x| x.as_mut_ptr()) 65*b5b571e0SLoGin .unwrap_or(core::ptr::null_mut()); 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 }) 76*b5b571e0SLoGin .unwrap_or(core::ptr::null_mut()); 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 { 87453452ccSLoGin let r = self.local_alloc_zeroed(layout); 887b32f508SLoGin mm_debug_log( 89*b5b571e0SLoGin klog_types::AllocatorLogType::Alloc(AllocLogItem::new(layout, Some(r as usize), None)), 907b32f508SLoGin klog_types::LogSource::Buddy, 917b32f508SLoGin ); 927b32f508SLoGin 937b32f508SLoGin return r; 947b32f508SLoGin 9540fe15e0SLoGin // self.local_alloc_zeroed(layout, 0) 9640fe15e0SLoGin } 9740fe15e0SLoGin 9840fe15e0SLoGin unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { 997b32f508SLoGin let r = self.local_alloc_zeroed(layout); 1007b32f508SLoGin 1017b32f508SLoGin mm_debug_log( 1027b32f508SLoGin klog_types::AllocatorLogType::AllocZeroed(AllocLogItem::new( 103*b5b571e0SLoGin layout, 1047b32f508SLoGin Some(r as usize), 1057b32f508SLoGin None, 1067b32f508SLoGin )), 1077b32f508SLoGin klog_types::LogSource::Buddy, 1087b32f508SLoGin ); 1097b32f508SLoGin 1107b32f508SLoGin return r; 11140fe15e0SLoGin } 11240fe15e0SLoGin 11340fe15e0SLoGin unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { 1147b32f508SLoGin mm_debug_log( 115*b5b571e0SLoGin klog_types::AllocatorLogType::Free(AllocLogItem::new(layout, Some(ptr as usize), None)), 1167b32f508SLoGin klog_types::LogSource::Buddy, 1177b32f508SLoGin ); 1187b32f508SLoGin 11940fe15e0SLoGin self.local_dealloc(ptr, layout); 12040fe15e0SLoGin } 12140fe15e0SLoGin } 12240fe15e0SLoGin 12340314b30SXiaoye Zheng /// 为内核slab分配器实现Allocator特性 12440314b30SXiaoye Zheng // unsafe impl Allocator for KernelAllocator { 12540314b30SXiaoye Zheng // fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> { 12640314b30SXiaoye Zheng // let memory = unsafe {self.local_alloc(layout)}; 12740314b30SXiaoye Zheng // if memory.is_null() { 12840314b30SXiaoye Zheng // Err(AllocError) 12940314b30SXiaoye Zheng // } else { 13040314b30SXiaoye Zheng // let slice = unsafe { core::slice::from_raw_parts_mut(memory, layout.size()) }; 13140314b30SXiaoye Zheng // Ok(unsafe { NonNull::new_unchecked(slice) }) 13240314b30SXiaoye Zheng // } 13340314b30SXiaoye Zheng // } 13440314b30SXiaoye Zheng 13540314b30SXiaoye Zheng // fn allocate_zeroed(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> { 13640314b30SXiaoye Zheng // let memory = unsafe {self.local_alloc_zeroed(layout)}; 13740314b30SXiaoye Zheng // if memory.is_null() { 13840314b30SXiaoye Zheng // Err(AllocError) 13940314b30SXiaoye Zheng // } else { 14040314b30SXiaoye Zheng // let slice = unsafe { core::slice::from_raw_parts_mut(memory, layout.size()) }; 14140314b30SXiaoye Zheng // Ok(unsafe { NonNull::new_unchecked(slice) }) 14240314b30SXiaoye Zheng // } 14340314b30SXiaoye Zheng // } 14440314b30SXiaoye Zheng 14540314b30SXiaoye Zheng // unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) { 14640314b30SXiaoye Zheng // self.local_dealloc(ptr.cast().as_ptr(), layout); 14740314b30SXiaoye Zheng // } 14840314b30SXiaoye Zheng // } 14940314b30SXiaoye Zheng 15040fe15e0SLoGin /// 内存分配错误处理函数 151fba56231SLoGin #[cfg(target_os = "none")] 15240fe15e0SLoGin #[alloc_error_handler] 15340fe15e0SLoGin pub fn global_alloc_err_handler(layout: Layout) -> ! { 15440fe15e0SLoGin panic!("global_alloc_error, layout: {:?}", layout); 15540fe15e0SLoGin } 156