1 //! 该文件用于系统启动早期,内存管理器初始化之前,提供一些简单的内存映射功能 2 //! 3 //! 这里假设在内核引导文件中,已经填写了前100M的内存映射关系,因此这里不需要任何动态分配。 4 //! 5 //! 映射关系为: 6 //! 7 //! 虚拟地址 0-100M与虚拟地址 0x8000_0000_0000 - 0x8000_0640_0000 之间具有重映射关系。 8 //! 也就是说,他们的第二级页表在最顶级页表中,占用了第0和第256个页表项。 9 //! 10 11 use crate::mm::{MMArch, MemoryManagementArch, PhysAddr}; 12 use core::marker::PhantomData; 13 14 use super::{ 15 allocator::page_frame::{FrameAllocator, PageFrameCount, PageFrameUsage}, 16 page::PageFlags, 17 PageTableKind, VirtAddr, 18 }; 19 20 /// 伪分配器 21 struct PseudoAllocator<MMA> { 22 phantom: PhantomData<MMA>, 23 } 24 25 impl<MMA: MemoryManagementArch> PseudoAllocator<MMA> { 26 pub const fn new() -> Self { 27 Self { 28 phantom: PhantomData, 29 } 30 } 31 } 32 33 /// 为NoInitAllocator实现FrameAllocator 34 impl<MMA: MemoryManagementArch> FrameAllocator for PseudoAllocator<MMA> { 35 unsafe fn allocate(&mut self, _count: PageFrameCount) -> Option<(PhysAddr, PageFrameCount)> { 36 panic!("NoInitAllocator can't allocate page frame"); 37 } 38 39 unsafe fn free(&mut self, _address: PhysAddr, _count: PageFrameCount) { 40 panic!("NoInitAllocator can't free page frame"); 41 } 42 /// @brief: 获取内存区域页帧的使用情况 43 /// @param self 44 /// @return 页帧的使用情况 45 unsafe fn usage(&self) -> PageFrameUsage { 46 panic!("NoInitAllocator can't get page frame usage"); 47 } 48 } 49 50 /// Use pseudo mapper to map physical memory to virtual memory. 51 /// 52 /// ## Safety 53 /// 54 /// 调用该函数时,必须保证内存管理器尚未初始化。否则将导致未定义的行为 55 /// 56 /// 并且,内核引导文件必须以4K页为粒度,填写了前100M的内存映射关系。(具体以本文件开头的注释为准) 57 pub unsafe fn pseudo_map_phys(vaddr: VirtAddr, paddr: PhysAddr, count: PageFrameCount) { 58 assert!(vaddr.check_aligned(MMArch::PAGE_SIZE)); 59 assert!(paddr.check_aligned(MMArch::PAGE_SIZE)); 60 61 let mut pseudo_allocator = PseudoAllocator::<MMArch>::new(); 62 63 let mut mapper = crate::mm::page::PageMapper::<MMArch, _>::new( 64 PageTableKind::Kernel, 65 MMArch::table(PageTableKind::Kernel), 66 &mut pseudo_allocator, 67 ); 68 69 let flags: PageFlags<MMArch> = PageFlags::new().set_write(true).set_execute(true); 70 71 for i in 0..count.data() { 72 let vaddr = vaddr + i * MMArch::PAGE_SIZE; 73 let paddr = paddr + i * MMArch::PAGE_SIZE; 74 let flusher = mapper.map_phys(vaddr, paddr, flags).unwrap(); 75 flusher.ignore(); 76 } 77 78 mapper.make_current(); 79 } 80