1*40fe15e0SLoGin use alloc::sync::Arc; 2*40fe15e0SLoGin 3*40fe15e0SLoGin use crate::{ 4*40fe15e0SLoGin arch::MMArch, 5*40fe15e0SLoGin include::bindings::bindings::{process_control_block, PAGE_OFFSET}, 6*40fe15e0SLoGin syscall::SystemError, 7*40fe15e0SLoGin }; 8*40fe15e0SLoGin 9*40fe15e0SLoGin use core::{ 10*40fe15e0SLoGin cmp, 11*40fe15e0SLoGin fmt::Debug, 12*40fe15e0SLoGin intrinsics::unlikely, 13*40fe15e0SLoGin ops::{Add, AddAssign, Sub, SubAssign}, 14*40fe15e0SLoGin ptr, 15*40fe15e0SLoGin sync::atomic::{AtomicBool, Ordering}, 16*40fe15e0SLoGin }; 17*40fe15e0SLoGin 18*40fe15e0SLoGin use self::{ 19*40fe15e0SLoGin allocator::page_frame::{VirtPageFrame, VirtPageFrameIter}, 20*40fe15e0SLoGin page::round_up_to_page_size, 21*40fe15e0SLoGin ucontext::{AddressSpace, UserMapper}, 22*40fe15e0SLoGin }; 23004e86ffSlogin 2482d2e446Slogin pub mod allocator; 25*40fe15e0SLoGin pub mod c_adapter; 266cb769c4Slogin pub mod gfp; 27*40fe15e0SLoGin pub mod kernel_mapper; 28c2481452Shoumkh pub mod mmio_buddy; 29*40fe15e0SLoGin pub mod no_init; 30*40fe15e0SLoGin pub mod page; 31ab5c8ca4Slogin pub mod syscall; 32*40fe15e0SLoGin pub mod ucontext; 33*40fe15e0SLoGin 34*40fe15e0SLoGin /// 内核INIT进程的用户地址空间结构体(仅在process_init中初始化) 35*40fe15e0SLoGin static mut __INITIAL_PROCESS_ADDRESS_SPACE: Option<Arc<AddressSpace>> = None; 36*40fe15e0SLoGin 37*40fe15e0SLoGin /// 获取内核INIT进程的用户地址空间结构体 38*40fe15e0SLoGin #[allow(non_snake_case)] 39*40fe15e0SLoGin #[inline(always)] 40*40fe15e0SLoGin pub fn INITIAL_PROCESS_ADDRESS_SPACE() -> Arc<AddressSpace> { 41*40fe15e0SLoGin unsafe { 42*40fe15e0SLoGin return __INITIAL_PROCESS_ADDRESS_SPACE 43*40fe15e0SLoGin .as_ref() 44*40fe15e0SLoGin .expect("INITIAL_PROCESS_ADDRESS_SPACE is null") 45*40fe15e0SLoGin .clone(); 46*40fe15e0SLoGin } 47*40fe15e0SLoGin } 48*40fe15e0SLoGin 49*40fe15e0SLoGin /// 设置内核INIT进程的用户地址空间结构体全局变量 50*40fe15e0SLoGin #[allow(non_snake_case)] 51*40fe15e0SLoGin pub unsafe fn set_INITIAL_PROCESS_ADDRESS_SPACE(address_space: Arc<AddressSpace>) { 52*40fe15e0SLoGin static INITIALIZED: AtomicBool = AtomicBool::new(false); 53*40fe15e0SLoGin if INITIALIZED 54*40fe15e0SLoGin .compare_exchange(false, true, Ordering::SeqCst, Ordering::Acquire) 55*40fe15e0SLoGin .is_err() 56*40fe15e0SLoGin { 57*40fe15e0SLoGin panic!("INITIAL_PROCESS_ADDRESS_SPACE is already initialized"); 58*40fe15e0SLoGin } 59*40fe15e0SLoGin __INITIAL_PROCESS_ADDRESS_SPACE = Some(address_space); 60*40fe15e0SLoGin } 61004e86ffSlogin 62004e86ffSlogin /// @brief 将内核空间的虚拟地址转换为物理地址 63004e86ffSlogin #[inline(always)] 64004e86ffSlogin pub fn virt_2_phys(addr: usize) -> usize { 65004e86ffSlogin addr - PAGE_OFFSET as usize 66004e86ffSlogin } 67004e86ffSlogin 68004e86ffSlogin /// @brief 将物理地址转换为内核空间的虚拟地址 69004e86ffSlogin #[inline(always)] 70004e86ffSlogin pub fn phys_2_virt(addr: usize) -> usize { 71004e86ffSlogin addr + PAGE_OFFSET as usize 72004e86ffSlogin } 73bacd691cSlogin 74*40fe15e0SLoGin #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)] 75*40fe15e0SLoGin pub enum PageTableKind { 76*40fe15e0SLoGin /// 用户可访问的页表 77*40fe15e0SLoGin User, 78*40fe15e0SLoGin /// 内核页表 79*40fe15e0SLoGin Kernel, 80*40fe15e0SLoGin } 81*40fe15e0SLoGin 82*40fe15e0SLoGin /// 物理内存地址 83*40fe15e0SLoGin #[derive(Clone, Copy, Eq, Ord, PartialEq, PartialOrd, Hash)] 84*40fe15e0SLoGin #[repr(transparent)] 85*40fe15e0SLoGin pub struct PhysAddr(usize); 86*40fe15e0SLoGin 87*40fe15e0SLoGin impl PhysAddr { 88*40fe15e0SLoGin #[inline(always)] 89*40fe15e0SLoGin pub const fn new(address: usize) -> Self { 90*40fe15e0SLoGin Self(address) 91*40fe15e0SLoGin } 92*40fe15e0SLoGin 93*40fe15e0SLoGin /// @brief 获取物理地址的值 94*40fe15e0SLoGin #[inline(always)] 95*40fe15e0SLoGin pub fn data(&self) -> usize { 96*40fe15e0SLoGin self.0 97*40fe15e0SLoGin } 98*40fe15e0SLoGin 99*40fe15e0SLoGin /// @brief 将物理地址加上一个偏移量 100*40fe15e0SLoGin #[inline(always)] 101*40fe15e0SLoGin pub fn add(self, offset: usize) -> Self { 102*40fe15e0SLoGin Self(self.0 + offset) 103*40fe15e0SLoGin } 104*40fe15e0SLoGin 105*40fe15e0SLoGin /// @brief 判断物理地址是否按照指定要求对齐 106*40fe15e0SLoGin #[inline(always)] 107*40fe15e0SLoGin pub fn check_aligned(&self, align: usize) -> bool { 108*40fe15e0SLoGin return self.0 & (align - 1) == 0; 109*40fe15e0SLoGin } 110*40fe15e0SLoGin 111*40fe15e0SLoGin #[inline(always)] 112*40fe15e0SLoGin pub fn is_null(&self) -> bool { 113*40fe15e0SLoGin return self.0 == 0; 114*40fe15e0SLoGin } 115*40fe15e0SLoGin } 116*40fe15e0SLoGin 117*40fe15e0SLoGin impl Debug for PhysAddr { 118*40fe15e0SLoGin fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 119*40fe15e0SLoGin write!(f, "PhysAddr({:#x})", self.0) 120*40fe15e0SLoGin } 121*40fe15e0SLoGin } 122*40fe15e0SLoGin 123*40fe15e0SLoGin impl core::ops::Add<usize> for PhysAddr { 124*40fe15e0SLoGin type Output = Self; 125*40fe15e0SLoGin 126*40fe15e0SLoGin #[inline(always)] 127*40fe15e0SLoGin fn add(self, rhs: usize) -> Self::Output { 128*40fe15e0SLoGin return Self(self.0 + rhs); 129*40fe15e0SLoGin } 130*40fe15e0SLoGin } 131*40fe15e0SLoGin 132*40fe15e0SLoGin impl core::ops::AddAssign<usize> for PhysAddr { 133*40fe15e0SLoGin #[inline(always)] 134*40fe15e0SLoGin fn add_assign(&mut self, rhs: usize) { 135*40fe15e0SLoGin self.0 += rhs; 136*40fe15e0SLoGin } 137*40fe15e0SLoGin } 138*40fe15e0SLoGin 139*40fe15e0SLoGin impl core::ops::Add<PhysAddr> for PhysAddr { 140*40fe15e0SLoGin type Output = Self; 141*40fe15e0SLoGin 142*40fe15e0SLoGin #[inline(always)] 143*40fe15e0SLoGin fn add(self, rhs: PhysAddr) -> Self::Output { 144*40fe15e0SLoGin return Self(self.0 + rhs.0); 145*40fe15e0SLoGin } 146*40fe15e0SLoGin } 147*40fe15e0SLoGin 148*40fe15e0SLoGin impl core::ops::AddAssign<PhysAddr> for PhysAddr { 149*40fe15e0SLoGin #[inline(always)] 150*40fe15e0SLoGin fn add_assign(&mut self, rhs: PhysAddr) { 151*40fe15e0SLoGin self.0 += rhs.0; 152*40fe15e0SLoGin } 153*40fe15e0SLoGin } 154*40fe15e0SLoGin 155*40fe15e0SLoGin impl core::ops::Sub<usize> for PhysAddr { 156*40fe15e0SLoGin type Output = Self; 157*40fe15e0SLoGin 158*40fe15e0SLoGin #[inline(always)] 159*40fe15e0SLoGin fn sub(self, rhs: usize) -> Self::Output { 160*40fe15e0SLoGin return Self(self.0 - rhs); 161*40fe15e0SLoGin } 162*40fe15e0SLoGin } 163*40fe15e0SLoGin 164*40fe15e0SLoGin impl core::ops::SubAssign<usize> for PhysAddr { 165*40fe15e0SLoGin #[inline(always)] 166*40fe15e0SLoGin fn sub_assign(&mut self, rhs: usize) { 167*40fe15e0SLoGin self.0 -= rhs; 168*40fe15e0SLoGin } 169*40fe15e0SLoGin } 170*40fe15e0SLoGin 171*40fe15e0SLoGin impl core::ops::Sub<PhysAddr> for PhysAddr { 172*40fe15e0SLoGin type Output = usize; 173*40fe15e0SLoGin 174*40fe15e0SLoGin #[inline(always)] 175*40fe15e0SLoGin fn sub(self, rhs: PhysAddr) -> Self::Output { 176*40fe15e0SLoGin return self.0 - rhs.0; 177*40fe15e0SLoGin } 178*40fe15e0SLoGin } 179*40fe15e0SLoGin 180*40fe15e0SLoGin impl core::ops::SubAssign<PhysAddr> for PhysAddr { 181*40fe15e0SLoGin #[inline(always)] 182*40fe15e0SLoGin fn sub_assign(&mut self, rhs: PhysAddr) { 183*40fe15e0SLoGin self.0 -= rhs.0; 184*40fe15e0SLoGin } 185*40fe15e0SLoGin } 186*40fe15e0SLoGin 187*40fe15e0SLoGin /// 虚拟内存地址 188*40fe15e0SLoGin #[derive(Clone, Copy, Eq, Ord, PartialEq, PartialOrd, Hash)] 189*40fe15e0SLoGin #[repr(transparent)] 190*40fe15e0SLoGin pub struct VirtAddr(usize); 191*40fe15e0SLoGin 192*40fe15e0SLoGin impl VirtAddr { 193*40fe15e0SLoGin #[inline(always)] 194*40fe15e0SLoGin pub const fn new(address: usize) -> Self { 195*40fe15e0SLoGin return Self(address); 196*40fe15e0SLoGin } 197*40fe15e0SLoGin 198*40fe15e0SLoGin /// @brief 获取虚拟地址的值 199*40fe15e0SLoGin #[inline(always)] 200*40fe15e0SLoGin pub fn data(&self) -> usize { 201*40fe15e0SLoGin return self.0; 202*40fe15e0SLoGin } 203*40fe15e0SLoGin 204*40fe15e0SLoGin /// @brief 判断虚拟地址的类型 205*40fe15e0SLoGin #[inline(always)] 206*40fe15e0SLoGin pub fn kind(&self) -> PageTableKind { 207*40fe15e0SLoGin if self.check_user() { 208*40fe15e0SLoGin return PageTableKind::User; 209*40fe15e0SLoGin } else { 210*40fe15e0SLoGin return PageTableKind::Kernel; 211*40fe15e0SLoGin } 212*40fe15e0SLoGin } 213*40fe15e0SLoGin 214*40fe15e0SLoGin /// @brief 判断虚拟地址是否按照指定要求对齐 215*40fe15e0SLoGin #[inline(always)] 216*40fe15e0SLoGin pub fn check_aligned(&self, align: usize) -> bool { 217*40fe15e0SLoGin return self.0 & (align - 1) == 0; 218*40fe15e0SLoGin } 219*40fe15e0SLoGin 220*40fe15e0SLoGin /// @brief 判断虚拟地址是否在用户空间 221*40fe15e0SLoGin #[inline(always)] 222*40fe15e0SLoGin pub fn check_user(&self) -> bool { 223*40fe15e0SLoGin if self < &MMArch::USER_END_VADDR { 224*40fe15e0SLoGin return true; 225*40fe15e0SLoGin } else { 226*40fe15e0SLoGin return false; 227*40fe15e0SLoGin } 228*40fe15e0SLoGin } 229*40fe15e0SLoGin 230*40fe15e0SLoGin #[inline(always)] 231*40fe15e0SLoGin pub fn as_ptr<T>(self) -> *mut T { 232*40fe15e0SLoGin return self.0 as *mut T; 233*40fe15e0SLoGin } 234*40fe15e0SLoGin 235*40fe15e0SLoGin #[inline(always)] 236*40fe15e0SLoGin pub fn is_null(&self) -> bool { 237*40fe15e0SLoGin return self.0 == 0; 238*40fe15e0SLoGin } 239*40fe15e0SLoGin } 240*40fe15e0SLoGin 241*40fe15e0SLoGin impl Add<VirtAddr> for VirtAddr { 242*40fe15e0SLoGin type Output = Self; 243*40fe15e0SLoGin 244*40fe15e0SLoGin #[inline(always)] 245*40fe15e0SLoGin fn add(self, rhs: VirtAddr) -> Self::Output { 246*40fe15e0SLoGin return Self(self.0 + rhs.0); 247*40fe15e0SLoGin } 248*40fe15e0SLoGin } 249*40fe15e0SLoGin 250*40fe15e0SLoGin impl Add<usize> for VirtAddr { 251*40fe15e0SLoGin type Output = Self; 252*40fe15e0SLoGin 253*40fe15e0SLoGin #[inline(always)] 254*40fe15e0SLoGin fn add(self, rhs: usize) -> Self::Output { 255*40fe15e0SLoGin return Self(self.0 + rhs); 256*40fe15e0SLoGin } 257*40fe15e0SLoGin } 258*40fe15e0SLoGin 259*40fe15e0SLoGin impl Sub<VirtAddr> for VirtAddr { 260*40fe15e0SLoGin type Output = usize; 261*40fe15e0SLoGin 262*40fe15e0SLoGin #[inline(always)] 263*40fe15e0SLoGin fn sub(self, rhs: VirtAddr) -> Self::Output { 264*40fe15e0SLoGin return self.0 - rhs.0; 265*40fe15e0SLoGin } 266*40fe15e0SLoGin } 267*40fe15e0SLoGin 268*40fe15e0SLoGin impl Sub<usize> for VirtAddr { 269*40fe15e0SLoGin type Output = Self; 270*40fe15e0SLoGin 271*40fe15e0SLoGin #[inline(always)] 272*40fe15e0SLoGin fn sub(self, rhs: usize) -> Self::Output { 273*40fe15e0SLoGin return Self(self.0 - rhs); 274*40fe15e0SLoGin } 275*40fe15e0SLoGin } 276*40fe15e0SLoGin 277*40fe15e0SLoGin impl AddAssign<usize> for VirtAddr { 278*40fe15e0SLoGin #[inline(always)] 279*40fe15e0SLoGin fn add_assign(&mut self, rhs: usize) { 280*40fe15e0SLoGin self.0 += rhs; 281*40fe15e0SLoGin } 282*40fe15e0SLoGin } 283*40fe15e0SLoGin 284*40fe15e0SLoGin impl AddAssign<VirtAddr> for VirtAddr { 285*40fe15e0SLoGin #[inline(always)] 286*40fe15e0SLoGin fn add_assign(&mut self, rhs: VirtAddr) { 287*40fe15e0SLoGin self.0 += rhs.0; 288*40fe15e0SLoGin } 289*40fe15e0SLoGin } 290*40fe15e0SLoGin 291*40fe15e0SLoGin impl SubAssign<usize> for VirtAddr { 292*40fe15e0SLoGin #[inline(always)] 293*40fe15e0SLoGin fn sub_assign(&mut self, rhs: usize) { 294*40fe15e0SLoGin self.0 -= rhs; 295*40fe15e0SLoGin } 296*40fe15e0SLoGin } 297*40fe15e0SLoGin 298*40fe15e0SLoGin impl SubAssign<VirtAddr> for VirtAddr { 299*40fe15e0SLoGin #[inline(always)] 300*40fe15e0SLoGin fn sub_assign(&mut self, rhs: VirtAddr) { 301*40fe15e0SLoGin self.0 -= rhs.0; 302*40fe15e0SLoGin } 303*40fe15e0SLoGin } 304*40fe15e0SLoGin 305*40fe15e0SLoGin impl Debug for VirtAddr { 306*40fe15e0SLoGin fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 307*40fe15e0SLoGin write!(f, "VirtAddr({:#x})", self.0) 308*40fe15e0SLoGin } 309*40fe15e0SLoGin } 310*40fe15e0SLoGin 311*40fe15e0SLoGin /// @brief 物理内存区域 312*40fe15e0SLoGin #[derive(Clone, Copy, Debug)] 313*40fe15e0SLoGin pub struct PhysMemoryArea { 314*40fe15e0SLoGin /// 物理基地址 315*40fe15e0SLoGin pub base: PhysAddr, 316*40fe15e0SLoGin /// 该区域的物理内存大小 317*40fe15e0SLoGin pub size: usize, 318*40fe15e0SLoGin } 319*40fe15e0SLoGin 320*40fe15e0SLoGin pub trait MemoryManagementArch: Clone + Copy + Debug { 321*40fe15e0SLoGin /// 页面大小的shift(假如页面4K,那么这个值就是12,因为2^12=4096) 322*40fe15e0SLoGin const PAGE_SHIFT: usize; 323*40fe15e0SLoGin /// 每个页表的页表项数目。(以2^n次幂来表示)假如有512个页表项,那么这个值就是9 324*40fe15e0SLoGin const PAGE_ENTRY_SHIFT: usize; 325*40fe15e0SLoGin /// 页表层级数量 326*40fe15e0SLoGin const PAGE_LEVELS: usize; 327*40fe15e0SLoGin 328*40fe15e0SLoGin /// 页表项的有效位的index(假如页表项的第0-51位有效,那么这个值就是52) 329*40fe15e0SLoGin const ENTRY_ADDRESS_SHIFT: usize; 330*40fe15e0SLoGin /// 页面的页表项的默认值 331*40fe15e0SLoGin const ENTRY_FLAG_DEFAULT_PAGE: usize; 332*40fe15e0SLoGin /// 页表的页表项的默认值 333*40fe15e0SLoGin const ENTRY_FLAG_DEFAULT_TABLE: usize; 334*40fe15e0SLoGin /// 页表项的present位被置位之后的值 335*40fe15e0SLoGin const ENTRY_FLAG_PRESENT: usize; 336*40fe15e0SLoGin /// 页表项为read only时的值 337*40fe15e0SLoGin const ENTRY_FLAG_READONLY: usize; 338*40fe15e0SLoGin /// 页表项为可读写状态的值 339*40fe15e0SLoGin const ENTRY_FLAG_READWRITE: usize; 340*40fe15e0SLoGin /// 页面项标记页面为user page的值 341*40fe15e0SLoGin const ENTRY_FLAG_USER: usize; 342*40fe15e0SLoGin /// 页面项标记页面为write through的值 343*40fe15e0SLoGin const ENTRY_FLAG_WRITE_THROUGH: usize; 344*40fe15e0SLoGin /// 页面项标记页面为cache disable的值 345*40fe15e0SLoGin const ENTRY_FLAG_CACHE_DISABLE: usize; 346*40fe15e0SLoGin /// 标记当前页面不可执行的标志位(Execute disable)(也就是说,不能从这段内存里面获取处理器指令) 347*40fe15e0SLoGin const ENTRY_FLAG_NO_EXEC: usize; 348*40fe15e0SLoGin /// 标记当前页面可执行的标志位(Execute enable) 349*40fe15e0SLoGin const ENTRY_FLAG_EXEC: usize; 350*40fe15e0SLoGin 351*40fe15e0SLoGin /// 虚拟地址与物理地址的偏移量 352*40fe15e0SLoGin const PHYS_OFFSET: usize; 353*40fe15e0SLoGin 354*40fe15e0SLoGin /// 每个页面的大小 355*40fe15e0SLoGin const PAGE_SIZE: usize = 1 << Self::PAGE_SHIFT; 356*40fe15e0SLoGin /// 通过这个mask,获取地址的页内偏移量 357*40fe15e0SLoGin const PAGE_OFFSET_MASK: usize = Self::PAGE_SIZE - 1; 358*40fe15e0SLoGin /// 页表项的地址、数据部分的shift。 359*40fe15e0SLoGin /// 打个比方,如果这个值为52,那么意味着页表项的[0, 52)位,用于表示地址以及其他的标志位 360*40fe15e0SLoGin const PAGE_ADDRESS_SHIFT: usize = Self::PAGE_LEVELS * Self::PAGE_ENTRY_SHIFT + Self::PAGE_SHIFT; 361*40fe15e0SLoGin /// 最大的虚拟地址(对于不同的架构,由于上述PAGE_ADDRESS_SHIFT可能包括了reserved bits, 事实上能表示的虚拟地址应该比这个值要小) 362*40fe15e0SLoGin const PAGE_ADDRESS_SIZE: usize = 1 << Self::PAGE_ADDRESS_SHIFT; 363*40fe15e0SLoGin /// 页表项的值与这个常量进行与运算,得到的结果是所填写的物理地址 364*40fe15e0SLoGin const PAGE_ADDRESS_MASK: usize = Self::PAGE_ADDRESS_SIZE - Self::PAGE_SIZE; 365*40fe15e0SLoGin /// 每个页表项的大小 366*40fe15e0SLoGin const PAGE_ENTRY_SIZE: usize = 1 << (Self::PAGE_SHIFT - Self::PAGE_ENTRY_SHIFT); 367*40fe15e0SLoGin /// 每个页表的页表项数目 368*40fe15e0SLoGin const PAGE_ENTRY_NUM: usize = 1 << Self::PAGE_ENTRY_SHIFT; 369*40fe15e0SLoGin /// 该字段用于根据虚拟地址,获取该虚拟地址在对应的页表中是第几个页表项 370*40fe15e0SLoGin const PAGE_ENTRY_MASK: usize = Self::PAGE_ENTRY_NUM - 1; 371*40fe15e0SLoGin 372*40fe15e0SLoGin const PAGE_NEGATIVE_MASK: usize = !((Self::PAGE_ADDRESS_SIZE) - 1); 373*40fe15e0SLoGin 374*40fe15e0SLoGin const ENTRY_ADDRESS_SIZE: usize = 1 << Self::ENTRY_ADDRESS_SHIFT; 375*40fe15e0SLoGin /// 该mask用于获取页表项中地址字段 376*40fe15e0SLoGin const ENTRY_ADDRESS_MASK: usize = Self::ENTRY_ADDRESS_SIZE - Self::PAGE_SIZE; 377*40fe15e0SLoGin /// 这个mask用于获取页表项中的flags 378*40fe15e0SLoGin const ENTRY_FLAGS_MASK: usize = !Self::ENTRY_ADDRESS_MASK; 379*40fe15e0SLoGin 380*40fe15e0SLoGin /// 用户空间的最高地址 381*40fe15e0SLoGin const USER_END_VADDR: VirtAddr; 382*40fe15e0SLoGin /// 用户堆的起始地址 383*40fe15e0SLoGin const USER_BRK_START: VirtAddr; 384*40fe15e0SLoGin /// 用户栈起始地址(向下生长,不包含该值) 385*40fe15e0SLoGin const USER_STACK_START: VirtAddr; 386*40fe15e0SLoGin 387*40fe15e0SLoGin /// @brief 用于初始化内存管理模块与架构相关的信息。 388*40fe15e0SLoGin /// 该函数应调用其他模块的接口,生成内存区域结构体,提供给BumpAllocator使用 389*40fe15e0SLoGin unsafe fn init() -> &'static [PhysMemoryArea]; 390*40fe15e0SLoGin 391*40fe15e0SLoGin /// @brief 读取指定虚拟地址的值,并假设它是类型T的指针 392*40fe15e0SLoGin #[inline(always)] 393*40fe15e0SLoGin unsafe fn read<T>(address: VirtAddr) -> T { 394*40fe15e0SLoGin return ptr::read(address.data() as *const T); 395*40fe15e0SLoGin } 396*40fe15e0SLoGin 397*40fe15e0SLoGin /// @brief 将value写入到指定的虚拟地址 398*40fe15e0SLoGin #[inline(always)] 399*40fe15e0SLoGin unsafe fn write<T>(address: VirtAddr, value: T) { 400*40fe15e0SLoGin ptr::write(address.data() as *mut T, value); 401*40fe15e0SLoGin } 402*40fe15e0SLoGin 403*40fe15e0SLoGin #[inline(always)] 404*40fe15e0SLoGin unsafe fn write_bytes(address: VirtAddr, value: u8, count: usize) { 405*40fe15e0SLoGin ptr::write_bytes(address.data() as *mut u8, value, count); 406*40fe15e0SLoGin } 407*40fe15e0SLoGin 408*40fe15e0SLoGin /// @brief 刷新TLB中,关于指定虚拟地址的条目 409*40fe15e0SLoGin unsafe fn invalidate_page(address: VirtAddr); 410*40fe15e0SLoGin 411*40fe15e0SLoGin /// @brief 刷新TLB中,所有的条目 412*40fe15e0SLoGin unsafe fn invalidate_all(); 413*40fe15e0SLoGin 414*40fe15e0SLoGin /// @brief 获取顶级页表的物理地址 415*40fe15e0SLoGin unsafe fn table(table_kind: PageTableKind) -> PhysAddr; 416*40fe15e0SLoGin 417*40fe15e0SLoGin /// @brief 设置顶级页表的物理地址到处理器中 418*40fe15e0SLoGin unsafe fn set_table(table_kind: PageTableKind, table: PhysAddr); 419*40fe15e0SLoGin 420*40fe15e0SLoGin /// @brief 将物理地址转换为虚拟地址. 421*40fe15e0SLoGin /// 422*40fe15e0SLoGin /// @param phys 物理地址 423*40fe15e0SLoGin /// 424*40fe15e0SLoGin /// @return 转换后的虚拟地址。如果转换失败,返回None 425*40fe15e0SLoGin #[inline(always)] 426*40fe15e0SLoGin unsafe fn phys_2_virt(phys: PhysAddr) -> Option<VirtAddr> { 427*40fe15e0SLoGin if let Some(vaddr) = phys.data().checked_add(Self::PHYS_OFFSET) { 428*40fe15e0SLoGin return Some(VirtAddr::new(vaddr)); 429*40fe15e0SLoGin } else { 430*40fe15e0SLoGin return None; 431*40fe15e0SLoGin } 432*40fe15e0SLoGin } 433*40fe15e0SLoGin 434*40fe15e0SLoGin /// 将虚拟地址转换为物理地址 435*40fe15e0SLoGin /// 436*40fe15e0SLoGin /// ## 参数 437*40fe15e0SLoGin /// 438*40fe15e0SLoGin /// - `virt` 虚拟地址 439*40fe15e0SLoGin /// 440*40fe15e0SLoGin /// ## 返回值 441*40fe15e0SLoGin /// 442*40fe15e0SLoGin /// 转换后的物理地址。如果转换失败,返回None 443*40fe15e0SLoGin #[inline(always)] 444*40fe15e0SLoGin unsafe fn virt_2_phys(virt: VirtAddr) -> Option<PhysAddr> { 445*40fe15e0SLoGin if let Some(paddr) = virt.data().checked_sub(Self::PHYS_OFFSET) { 446*40fe15e0SLoGin return Some(PhysAddr::new(paddr)); 447*40fe15e0SLoGin } else { 448*40fe15e0SLoGin return None; 449*40fe15e0SLoGin } 450*40fe15e0SLoGin } 451*40fe15e0SLoGin 452*40fe15e0SLoGin /// @brief 判断指定的虚拟地址是否正确(符合规范) 453*40fe15e0SLoGin fn virt_is_valid(virt: VirtAddr) -> bool; 454*40fe15e0SLoGin 455*40fe15e0SLoGin /// 获取内存管理初始化时,创建的第一个内核页表的地址 456*40fe15e0SLoGin fn initial_page_table() -> PhysAddr; 457*40fe15e0SLoGin 458*40fe15e0SLoGin /// 初始化新的usermapper,为用户进程创建页表 459*40fe15e0SLoGin fn setup_new_usermapper() -> Result<UserMapper, SystemError>; 460*40fe15e0SLoGin } 461*40fe15e0SLoGin 462*40fe15e0SLoGin /// @brief 虚拟地址范围 463*40fe15e0SLoGin /// 该结构体用于表示一个虚拟地址范围,包括起始地址与大小 464*40fe15e0SLoGin /// 465*40fe15e0SLoGin /// 请注意与VMA进行区分,该结构体被VMA所包含 466*40fe15e0SLoGin #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 467*40fe15e0SLoGin pub struct VirtRegion { 468*40fe15e0SLoGin start: VirtAddr, 469*40fe15e0SLoGin size: usize, 470*40fe15e0SLoGin } 471*40fe15e0SLoGin 472*40fe15e0SLoGin #[allow(dead_code)] 473*40fe15e0SLoGin impl VirtRegion { 474*40fe15e0SLoGin /// # 创建一个新的虚拟地址范围 475*40fe15e0SLoGin pub fn new(start: VirtAddr, size: usize) -> Self { 476*40fe15e0SLoGin VirtRegion { start, size } 477*40fe15e0SLoGin } 478*40fe15e0SLoGin 479*40fe15e0SLoGin /// 获取虚拟地址范围的起始地址 480*40fe15e0SLoGin #[inline(always)] 481*40fe15e0SLoGin pub fn start(&self) -> VirtAddr { 482*40fe15e0SLoGin self.start 483*40fe15e0SLoGin } 484*40fe15e0SLoGin 485*40fe15e0SLoGin /// 获取虚拟地址范围的截止地址(不包括返回的地址) 486*40fe15e0SLoGin #[inline(always)] 487*40fe15e0SLoGin pub fn end(&self) -> VirtAddr { 488*40fe15e0SLoGin return self.start().add(self.size); 489*40fe15e0SLoGin } 490*40fe15e0SLoGin 491*40fe15e0SLoGin /// # Create a new VirtRegion from a range [start, end) 492*40fe15e0SLoGin /// 493*40fe15e0SLoGin /// If end <= start, return None 494*40fe15e0SLoGin pub fn between(start: VirtAddr, end: VirtAddr) -> Option<Self> { 495*40fe15e0SLoGin if unlikely(end.data() <= start.data()) { 496*40fe15e0SLoGin return None; 497*40fe15e0SLoGin } 498*40fe15e0SLoGin let size = end.data() - start.data(); 499*40fe15e0SLoGin return Some(VirtRegion::new(start, size)); 500*40fe15e0SLoGin } 501*40fe15e0SLoGin 502*40fe15e0SLoGin /// # 取两个虚拟地址范围的交集 503*40fe15e0SLoGin /// 504*40fe15e0SLoGin /// 如果两个虚拟地址范围没有交集,返回None 505*40fe15e0SLoGin pub fn intersect(&self, other: &VirtRegion) -> Option<VirtRegion> { 506*40fe15e0SLoGin let start = self.start.max(other.start); 507*40fe15e0SLoGin let end = self.end().min(other.end()); 508*40fe15e0SLoGin return VirtRegion::between(start, end); 509*40fe15e0SLoGin } 510*40fe15e0SLoGin 511*40fe15e0SLoGin /// 设置虚拟地址范围的起始地址 512*40fe15e0SLoGin #[inline(always)] 513*40fe15e0SLoGin pub fn set_start(&mut self, start: VirtAddr) { 514*40fe15e0SLoGin self.start = start; 515*40fe15e0SLoGin } 516*40fe15e0SLoGin 517*40fe15e0SLoGin #[inline(always)] 518*40fe15e0SLoGin pub fn size(&self) -> usize { 519*40fe15e0SLoGin self.size 520*40fe15e0SLoGin } 521*40fe15e0SLoGin 522*40fe15e0SLoGin /// 设置虚拟地址范围的大小 523*40fe15e0SLoGin #[inline(always)] 524*40fe15e0SLoGin pub fn set_size(&mut self, size: usize) { 525*40fe15e0SLoGin self.size = size; 526*40fe15e0SLoGin } 527*40fe15e0SLoGin 528*40fe15e0SLoGin /// 判断虚拟地址范围是否为空 529*40fe15e0SLoGin #[inline(always)] 530*40fe15e0SLoGin pub fn is_empty(&self) -> bool { 531*40fe15e0SLoGin self.size == 0 532*40fe15e0SLoGin } 533*40fe15e0SLoGin 534*40fe15e0SLoGin /// 将虚拟地址区域的大小向上对齐到页大小 535*40fe15e0SLoGin #[inline(always)] 536*40fe15e0SLoGin pub fn round_up_size_to_page(self) -> Self { 537*40fe15e0SLoGin return VirtRegion::new(self.start, round_up_to_page_size(self.size)); 538*40fe15e0SLoGin } 539*40fe15e0SLoGin 540*40fe15e0SLoGin /// 判断两个虚拟地址范围是否由于具有交集而导致冲突 541*40fe15e0SLoGin #[inline(always)] 542*40fe15e0SLoGin pub fn collide(&self, other: &VirtRegion) -> bool { 543*40fe15e0SLoGin return self.intersect(other).is_some(); 544*40fe15e0SLoGin } 545*40fe15e0SLoGin 546*40fe15e0SLoGin pub fn iter_pages(&self) -> VirtPageFrameIter { 547*40fe15e0SLoGin return VirtPageFrame::iter_range( 548*40fe15e0SLoGin VirtPageFrame::new(self.start), 549*40fe15e0SLoGin VirtPageFrame::new(self.end()), 550*40fe15e0SLoGin ); 551*40fe15e0SLoGin } 552*40fe15e0SLoGin 553*40fe15e0SLoGin /// 获取[self.start(), region.start())的虚拟地址范围 554*40fe15e0SLoGin /// 555*40fe15e0SLoGin /// 如果self.start() >= region.start(),返回None 556*40fe15e0SLoGin pub fn before(self, region: &VirtRegion) -> Option<Self> { 557*40fe15e0SLoGin return Self::between(self.start(), region.start()); 558*40fe15e0SLoGin } 559*40fe15e0SLoGin 560*40fe15e0SLoGin /// 获取[region.end(),self.end())的虚拟地址范围 561*40fe15e0SLoGin /// 562*40fe15e0SLoGin /// 如果 self.end() >= region.end() ,返回None 563*40fe15e0SLoGin pub fn after(self, region: &VirtRegion) -> Option<Self> { 564*40fe15e0SLoGin // if self.end() > region.end() none 565*40fe15e0SLoGin return Self::between(region.end(), self.end()); 566*40fe15e0SLoGin } 567*40fe15e0SLoGin 568*40fe15e0SLoGin /// 把当前虚拟地址范围内的某个虚拟地址,转换为另一个虚拟地址范围内的虚拟地址 569*40fe15e0SLoGin /// 570*40fe15e0SLoGin /// 如果vaddr不在当前虚拟地址范围内,返回None 571*40fe15e0SLoGin /// 572*40fe15e0SLoGin /// 如果vaddr在当前虚拟地址范围内,返回vaddr在new_base中的虚拟地址 573*40fe15e0SLoGin pub fn rebase(self, vaddr: VirtAddr, new_base: &VirtRegion) -> Option<VirtAddr> { 574*40fe15e0SLoGin if !self.contains(vaddr) { 575*40fe15e0SLoGin return None; 576*40fe15e0SLoGin } 577*40fe15e0SLoGin let offset = vaddr.data() - self.start().data(); 578*40fe15e0SLoGin let new_start = new_base.start().data() + offset; 579*40fe15e0SLoGin return Some(VirtAddr::new(new_start)); 580*40fe15e0SLoGin } 581*40fe15e0SLoGin 582*40fe15e0SLoGin /// 判断虚拟地址范围是否包含指定的虚拟地址 583*40fe15e0SLoGin pub fn contains(&self, addr: VirtAddr) -> bool { 584*40fe15e0SLoGin return self.start() <= addr && addr < self.end(); 585*40fe15e0SLoGin } 586*40fe15e0SLoGin 587*40fe15e0SLoGin /// 创建当前虚拟地址范围的页面迭代器 588*40fe15e0SLoGin pub fn pages(&self) -> VirtPageFrameIter { 589*40fe15e0SLoGin return VirtPageFrame::iter_range( 590*40fe15e0SLoGin VirtPageFrame::new(self.start()), 591*40fe15e0SLoGin VirtPageFrame::new(self.end()), 592*40fe15e0SLoGin ); 593*40fe15e0SLoGin } 594*40fe15e0SLoGin } 595*40fe15e0SLoGin 596*40fe15e0SLoGin impl PartialOrd for VirtRegion { 597*40fe15e0SLoGin fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> { 598*40fe15e0SLoGin return self.start.partial_cmp(&other.start); 599*40fe15e0SLoGin } 600*40fe15e0SLoGin } 601*40fe15e0SLoGin 602*40fe15e0SLoGin impl Ord for VirtRegion { 603*40fe15e0SLoGin fn cmp(&self, other: &Self) -> cmp::Ordering { 604*40fe15e0SLoGin return self.start.cmp(&other.start); 605*40fe15e0SLoGin } 606*40fe15e0SLoGin } 607*40fe15e0SLoGin 608*40fe15e0SLoGin /// ## 判断虚拟地址是否超出了用户空间 609*40fe15e0SLoGin /// 610*40fe15e0SLoGin /// 如果虚拟地址超出了用户空间,返回Err(SystemError::EFAULT). 611*40fe15e0SLoGin /// 如果end < start,返回Err(SystemError::EOVERFLOW) 612*40fe15e0SLoGin /// 613*40fe15e0SLoGin /// 否则返回Ok(()) 614*40fe15e0SLoGin pub fn verify_area(addr: VirtAddr, size: usize) -> Result<(), SystemError> { 615*40fe15e0SLoGin let end = addr.add(size); 616*40fe15e0SLoGin if unlikely(end.data() < addr.data()) { 617*40fe15e0SLoGin return Err(SystemError::EOVERFLOW); 618*40fe15e0SLoGin } 619*40fe15e0SLoGin 620*40fe15e0SLoGin if !addr.check_user() || !end.check_user() { 621*40fe15e0SLoGin return Err(SystemError::EFAULT); 622*40fe15e0SLoGin } 623*40fe15e0SLoGin 624*40fe15e0SLoGin return Ok(()); 625*40fe15e0SLoGin } 626*40fe15e0SLoGin // ====== 重构内存管理、进程管理后,请删除这几行 BEGIN ====== 627bacd691cSlogin //BUG pcb问题 628bacd691cSlogin unsafe impl Send for process_control_block {} 629bacd691cSlogin unsafe impl Sync for process_control_block {} 630bacd691cSlogin 631*40fe15e0SLoGin // ====== 重构内存管理后,请删除这几行 END ======= 632