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