#page-table #virtual-memory #paging #arceos #physical-memory

nightly no-std page_table_multiarch

针对各种硬件架构的通用页面表结构

7个版本

0.3.3 2024年8月9日
0.3.2 2024年8月2日
0.3.1 2024年7月31日
0.2.0 2024年7月25日
0.1.2 2024年7月17日

311硬件支持 中排名

Download history 344/week @ 2024-07-15 493/week @ 2024-07-22 1059/week @ 2024-07-29 361/week @ 2024-08-05 291/week @ 2024-08-12

2,232 每月下载量

GPL-3.0-or-later OR Apache-2…

57KB
1K SLoC

page_table_multiarch

Crates.io Docs.rs CI

此crate提供了针对各种硬件架构的通用、统一、架构无关和操作系统无关的页面表结构。

核心结构是 PageTable64<M, PTE, H>。通过泛型参数提供操作系统函数和架构相关类型

  • M: 架构相关的元数据,需要实现 PagingMetaData 特性。
  • PTE: 架构相关的页面表条目,需要实现 GenericPTE 特性。
  • H: 操作系统函数,如物理内存分配,需要实现 PagingHandler 特性。

当前支持的架构和页面表结构

示例(x86_64)

use memory_addr::{PhysAddr, VirtAddr};
use page_table_multiarch::x86_64::{X64PageTable};
use page_table_multiarch::{MappingFlags, PagingHandler, PageSize};

use core::alloc::Layout;

extern crate alloc;

struct PagingHandlerImpl;

impl PagingHandler for PagingHandlerImpl {
    fn alloc_frame() -> Option<PhysAddr> {
        let layout = Layout::from_size_align(0x1000, 0x1000).unwrap();
        let ptr = unsafe { alloc::alloc::alloc(layout) };
        Some(PhysAddr::from(ptr as usize))
    }

    fn dealloc_frame(paddr: PhysAddr) {
        let layout = Layout::from_size_align(0x1000, 0x1000).unwrap();
        let ptr = paddr.as_usize() as *mut u8;
        unsafe { alloc::alloc::dealloc(ptr, layout) };
    }

    fn phys_to_virt(paddr: PhysAddr) -> VirtAddr {
        VirtAddr::from(paddr.as_usize())
    }
}

let vaddr = VirtAddr::from(0xdead_beef_000);
let paddr = PhysAddr::from(0x2000);
let flags = MappingFlags::READ | MappingFlags::WRITE;
let mut pt = X64PageTable::<PagingHandlerImpl>::try_new().unwrap();

assert!(pt.root_paddr().is_aligned_4k());
assert!(pt.map(vaddr, paddr, PageSize::Size4K, flags).is_ok());
assert_eq!(pt.query(vaddr), Ok((paddr, flags, PageSize::Size4K)));

依赖项

~3MB
~31K SLoC