no_init.rs 2.8 KB

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