NTOSKRNL 内存管理器(MM)分析
NTOSKRNL 内存管理器MM分析概述ReactOS 内核的内存管理器Memory Manager简称 MM位于ntoskrnl\mm\目录。它由两套子系统组成旧版 MMntoskrnl\mm\*.c根目录ReactOS 早期实现的独立内存管理器ARM3 MMntoskrnl\mm\ARM3\*.c后来引入的、对齐 Windows NT 架构的新内存管理器目前是主力实现两套子系统并存部分功能由 ARM3 覆盖部分仍由旧版提供。架构相关代码分离在i386/、amd64/、arm/子目录中。1. 目录文件清单与作用1.1 根目录文件Legacy / 旧版 MM文件功能[balance.c](file:///d:/reactos/ntoskrnl/mm/balance.c)内存平衡器— 后台内核线程周期性修剪各内存消费者的页面回收物理页面到空闲列表。MmTrimUserMemory遍历用户 LRU 链表进行换出。[freelist.c](file:///d:/reactos/ntoskrnl/mm/freelist.c)空闲页面链表与统计— 管理 PFN 数据库、MmAvailablePages、MmTotalCommittedPages等全局物理内存账本。[marea.c](file:///d:/reactos/ntoskrnl/mm/marea.c)内存区域管理— 虚拟地址区域VAD的创建、插入 AVL 树、删除。提供MmCreateMemoryArea/MmInsertMemoryArea/MmFreeMemoryArea。[mmfault.c](file:///d:/reactos/ntoskrnl/mm/mmapfault.c)缺页异常处理旧版 —MmAccessFault根据错误码分派到MmNotPresentFault等处理程序。[mminit.c](file:///d:/reactos/ntoskrnl/mm/mminit.c)内存管理器初始化旧版 —MmInitSystem分 Phase0/Phase1 两阶段执行建立内核地址空间和系统内存区域。[pagefile.c](file:///d:/reactos/ntoskrnl/mm/pagefile.c)页面文件管理— 交换文件的读写 I/O、交换槽位的分配/释放。MmWriteToSwapPage/MmReadFromSwapPage。[region.c](file:///d:/reactos/ntoskrnl/mm/region.c)区域子划分— 在内存区域内进一步划分子区域支持按地址范围修改属性和查找。[rmap.c](file:///d:/reactos/ntoskrnl/mm/rmap.c)反向映射— 通过物理页面找到所有映射到它的虚拟地址。页面换出的关键前置步骤。[section.c](file:///d:/reactos/ntoskrnl/mm/section.c)段对象旧版 — 内存映射文件Section的创建、视图映射/取消映射。[shutdown.c](file:///d:/reactos/ntoskrnl/mm/shutdown.c)关闭清理— 系统关闭时释放页面文件资源、同步脏页面。1.2 ARM3 子系统ARM3/目录ARM3 是当前的主力内存管理器实现采用分层架构各文件职责如下初始化与基础设施文件功能[mminit.c](file:///d:/reactos/ntoskrnl/mm/ARM3/mminit.c)ARM3 初始化核心—MmArmInitSystem两阶段初始化。扫描 LoaderBlock 内存描述符、构建 PFN 数据库、映射 PFN 数据库、构建分页池、初始化颜色表、内存事件等。[miarm.h](file:///d:/reactos/ntoskrnl/mm/ARM3/miarm.h)主头文件— 核心数据结构定义、宏页面大小、PTE/PD 尺寸、最低 VAD 地址等。[miavl.h](file:///d:/reactos/ntoskrnl/mm/ARM3/miavl.h)AVL 树头文件— VAD 节点专用的 AVL 树算法宏和类型映射。[sysldr.c](file:///d:/reactos/ntoskrnl/mm/ARM3/sysldr.c)系统镜像加载器~3600行— PE 文件的加载/卸载、导入表解析、Thunk 修正、已加载模块链表管理、驱动程序可分页性控制。[procsup.c](file:///d:/reactos/ntoskrnl/mm/ARM3/procsup.c)进程内存空间管理— PEB/TEB 创建删除、内核栈管理、进程地址空间创建/清理/删除、AWEAddress Windowing Extensions支持。物理内存管理文件功能[pfnlist.c](file:///d:/reactos/ntoskrnl/mm/ARM3/pfnlist.c)PFN 列表操作— 页面在空闲/备用/已修改/置零列表间的移动、按颜色分配、引用计数/共享计数管理、页面清零。[freelist.c](file:///d:/reactos/ntoskrnl/mm/freelist.c)空闲页管理旧版— 提供全局物理页统计旧版 MM 仍在使用。[zeropage.c](file:///d:/reactos/ntoskrnl/mm/ARM3/zeropage.c)零页线程—MiZeroPageThread后台线程将已释放页面清零维护零页列表供应。[contmem.c](file:///d:/reactos/ntoskrnl/mm/ARM3/contmem.c)连续内存分配—MmAllocateContiguousMemorySpecifyCache等 API按最低/最高地址、边界对齐分配连续物理页。[dynamic.c](file:///d:/reactos/ntoskrnl/mm/ARM3/dynamic.c)动态物理内存— 热插拔内存支持MmAddPhysicalMemory等大部分尚未实现。[largepag.c](file:///d:/reactos/ntoskrnl/mm/ARM3/largepag.c)大页面支持— 2MB/4MB 页面分配、大页面范围管理、驱动大页面列表。虚拟内存管理文件功能[virtual.c](file:///d:/reactos/ntoskrnl/mm/ARM3/virtual.c)虚拟内存核心最大文件之一—NtAllocateVirtualMemory/NtFreeVirtualMemory/NtProtectVirtualMemory/NtQueryVirtualMemory、跨进程内存复制、物理地址↔虚拟地址转换、安全虚拟内存、写时监视。[vadnode.c](file:///d:/reactos/ntoskrnl/mm/ARM3/vadnode.c)VAD 树算法— AVL 树插入/删除/查找、空闲地址范围搜索、冲突检查。[syspte.c](file:///d:/reactos/ntoskrnl/mm/ARM3/syspte.c)系统 PTE 分配器— 系统 PTE 的预留/分配/释放/初始化支持对齐分配。[hypermap.c](file:///d:/reactos/ntoskrnl/mm/ARM3/hypermap.c)超空间映射— 物理页面的临时虚拟映射MiMapPageInHyperSpace/MiUnmapPageInHyperSpace用于 MM 内部操作。页面错误与工作集文件功能[pagfault.c](file:///d:/reactos/ntoskrnl/mm/ARM3/pagfault.c)页面错误处理ARM3—MmArmAccessFault入口、分派到 Demand Zero / PageFile / Transition / Proto PTE 各子处理、栈溢出检查、访问权限检查。[wslist.cpp](file:///d:/reactos/ntoskrnl/mm/ARM3/wslist.cpp)工作集列表管理— 进程工作集初始化、插入/移除页面、工作集管理器线程MmWorkingSetManager修剪逻辑。唯一 C 文件。[balance.c](file:///d:/reactos/ntoskrnl/mm/balance.c)内存平衡器旧版— 页面回收的后台线程。池分配器文件功能[expool.c](file:///d:/reactos/ntoskrnl/mm/ARM3/expool.c)Executive 池分配器—ExAllocatePoolWithTag/ExFreePoolWithTag、分页池/非分页池管理、大页表管理、池标签跟踪、热标签缓存、验证检查、配额管理。[pool.c](file:///d:/reactos/ntoskrnl/mm/ARM3/pool.c)池分配器底层页面管理— 池物理页面的分配/释放、非分页池初始化、已释放池页面保护、配额提升/归还。[special.c](file:///d:/reactos/ntoskrnl/mm/ARM3/special.c)特殊池Driver Verifier— 带填充模式的分配/释放、越界访问和 Use-After-Free 检测。[ncache.c](file:///d:/reactos/ntoskrnl/mm/ARM3/ncache.c)非缓存内存分配—MmAllocateNonCachedMemory/MmFreeNonCachedMemory。Section段对象与 Session文件功能[section.c](file:///d:/reactos/ntoskrnl/mm/ARM3/section.c)Section 对象ARM3~3500行—NtCreateSection/NtMapViewOfSection、数据文件和分页文件映射、系统空间/会话空间视图管理、Segment 生命周期。[session.c](file:///d:/reactos/ntoskrnl/mm/ARM3/session.c)Session 内存管理— Session 创建/删除/附加/分离、Session ID 位图管理、引用计数。I/O 与调试支持文件功能[iosup.c](file:///d:/reactos/ntoskrnl/mm/ARM3/iosup.c)I/O 空间映射—MmMapIoSpace/MmUnmapIoSpace、显示帧缓冲映射、平台缓存属性表。[mdlsup.c](file:///d:/reactos/ntoskrnl/mm/ARM3/mdlsup.c)MDL 管理— MDL 创建/大小计算/页面分配释放/锁定/缓存指定/预取/保护。[kdbg.c](file:///d:/reactos/ntoskrnl/mm/ARM3/kdbg.c)调试器支持— Pool 使用统计查询等 KD 扩展。[mmdbg.c](file:///d:/reactos/ntoskrnl/mm/ARM3/mmdbg.c)内存调试— 物理地址翻译、安全内存复制供内核调试器使用。[drvmgmt.c](file:///d:/reactos/ntoskrnl/mm/ARM3/drvmgmt.c)驱动管理— 可分页驱动节锁定/解锁、Driver Verifier 支持。[mmsup.c](file:///d:/reactos/ntoskrnl/mm/ARM3/mmsup.c)杂项支持例程— 地址有效性检查、工作集大小调整、递归 I/O 故障检测、系统大小查询。1.3 架构相关文件文件架构功能[i386/init.c](file:///d:/reactos/ntoskrnl/mm/ARM3/i386/init.c)x86-32 / ARM3定义 x86 模板 PTE/PDEValidKernelPde/Pte、DemandZeroPde、MiInitMachineDependent[i386/page.c](file:///d:/reactos/ntoskrnl/mm/i386/page.c)x86-32 / ARM3核心页管理映射创建/删除/查询、保护掩码表、PTE/PDE 操作、页面文件映射管理[i386/pagepae.c](file:///d:/reactos/ntoskrnl/mm/i386/pagepae.c)x86-32 PAE旧版PAE 模式页管理TLB 刷新、进程地址空间创建7页 vs 2页、页表分配/释放[i386/procsup.c](file:///d:/reactos/ntoskrnl/mm/ARM3/i386/procsup.c)x86-32 / ARM3MiArchCreateProcessAddressSpace— 创建进程地址空间2级页表、自映射 PDE 技巧[amd64/init.c](file:///d:/reactos/ntoskrnl/mm/amd64/init.c)x86-64 / ARM3MiInitMachineDependent— 定义 amd64 模板 PTE/PDE、初始化非分页池和系统 PTE 空间、构建 PFN 数据库4级页表PML4→PDPT→PD→PT[amd64/procsup.c](file:///d:/reactos/ntoskrnl/mm/amd64/procsup.c)x86-64 / ARM3MiArchCreateProcessAddressSpace— 创建 amd64 进程地址空间4级页表配置、自映射 PML4[arm/init.c](file:///d:/reactos/ntoskrnl/mm/ARM3/arm/init.c)ARM / ARM3MiInitMachineDependent— 初始化非分页池大小和系统内存布局边界[arm/page.c](file:///d:/reactos/ntoskrnl/mm/arm/page.c)ARM保护掩码表 大部分为 UNIMPLEMENTED 存根[arm/stubs.c](file:///d:/reactos/ntoskrnl/mm/arm/stubs.c)ARM页表辅助函数部分实现2. 内存管理流程图2.1 系统启动初始化流程Phase0 初始化MmArmInitSystem Phase0 │ ├─ MiScanMemoryDescriptors() │ 从 LoaderBlock-MemoryDescriptorList 读取物理内存布局 │ 分类可用 RAM、XIP ROM、坏块、固件保留等 │ ├─ MiComputeColorInformation() │ 计算 Cache ColorL2 Cache 大小 / 页面大小 │ 初始化颜色表 MiInitializeColorTables() │ ├─ MiBuildPfnDatabase() │ 为每个物理页创建 PFN 条目约 24 字节/页 │ → 非分页池中为 PFN 数据库预留空间 │ ├─ MiMapPfnDatabase() │ 将 PFN 数据库映射到虚拟地址空间 │ ├─ 初始化系统 PTE 空间MiInitializeSystemPtes / MiReserveSystemPtes │ ├─ MiBuildPagedPool() / MiInitializeNonPagedPool() │ 构建分页池和非分页池 │ ├─ MiInitializeMemoryEvents() │ 初始化低内存/高内存事件 │ └─ 初始化工作集管理器参数MiAdjustWorkingSetManagerParameters Phase1 初始化MmArmInitSystem Phase1 │ ├─ MmInitSystem旧版 MM 的 Phase1 初始化 │ ├─ MiInitializeLoadedModuleList() │ 建立已加载模块链表记录所有内核驱动和 DLL │ ├─ MiReloadBootLoadedDrivers() │ 重新处理引导时加载的驱动导入表 │ ├─ MiBuildImportsForBootDrivers() │ 构建导入表解析 │ ├─ MiInitializeLargePageSupport() │ 初始化大页面分配支持 │ ├─ MiInitializeSpecialPool() │ 初始化 Driver Verifier 特殊池 │ └─ MmInitBsmThread() 初始化后台交换元数据线程2.2 缺页异常处理流程CPU 触发 Page FaultCR2 故障地址 │ ▼ KiTrap0Ex86 缺页中断处理程序 │ ▼ MmAccessFault (旧版) / MmArmAccessFault (ARM3) │ ├─ 确定故障类型错误码分析 │ ├─ 页面不存在位00 │ ├─ 写操作违规位11 │ ├─ 用户模式位20 │ └─ 保留位违规位31 │ ├─ MiCheckForUserStackOverflow() │ 检查是否为用户栈溢出 → 自动扩展栈 VAD │ ├─ MiDispatchFault() │ │ │ ├─ MiResolveDemandZeroFault() │ │ 请求置零故障分配一个零页并映射 │ │ → 调用 MiRemoveZeroPage() 从零页列表取页 │ │ → 若空则从空闲列表取页并调用 MiZeroPhysicalPage() │ │ → 初始化 PFN 条目 │ │ → 填写 PTE │ │ │ ├─ MiResolvePageFileFault() │ │ 页面文件故障从交换文件读回页面 │ │ → 解析 PTE 中的交换条目页面文件号 槽位偏移 │ │ → MmReadFromSwapPage() → 发起磁盘 I/O │ │ → 等待 I/O 完成 │ │ → 将页面映射到虚拟地址 │ │ │ ├─ MiResolveTransitionFault() │ │ 转换故障页面在备用/已修改列表中 │ │ → 从列表中移除 │ │ → 重新映射并更新 PFN 状态 │ │ │ ├─ MiResolveProtoPteFault() │ │ 原型 PTE 故障多个进程共享的映射 │ │ → 复制原型 PTE │ │ → 若需写时复制COW分配新页面并复制内容 │ │ → 更新共享计数的 PFN │ │ │ └─ MiCompleteProtoPteFault() │ 完成原型 PTE 故障的后续处理 │ ├─ MiAccessCheck() │ 检查访问权限读/写/执行 │ └─ 返回 STATUS_SUCCESS 或 引发访问违规异常2.3 虚拟内存分配流程NtAllocateVirtualMemoryNtAllocateVirtualMemory(ProcessHandle, BaseAddress, ZeroBits, Size, AllocationType, Protect) │ ├─ 参数验证大小对齐、保护标志合法性 │ ├─ MmCheckForContiguousMemory() — 特殊池检查 │ ├─ 锁定工作集锁WorkingSetLock → AddressSpaceLock │ ├─ 查找空闲地址范围 │ MiFindEmptyAddressRangeInTree() │ → 遍历 VAD AVL 树查找满足大小和对齐的空闲区间 │ ├─ 预留MEM_RESERVE │ MiInsertVad() │ → 创建 VAD 节点记录起始地址、大小、保护属性 │ → 插入进程的 VAD AVL 树 │ ├─ 提交MEM_COMMIT │ MiCommitPages() │ → 预留系统 PTE如需要 │ → 更新已提交页面计数MmTotalCommittedPages │ → 创建或更新页表项填写 DemandZero PTE │ ├─ 释放工作集锁 │ └─ 返回 STATUS_SUCCESS2.4 页面回收流程内存平衡器内存压力触发MmAvailablePages 低于阈值 │ ▼ MmRebalanceMemoryConsumers() │ ▼ MiBalancerThread平衡器内核线程主循环 │ └─ 循环 │ ├─ 计算各消费者应修剪的页面数 │ → 根据消费者优先级和目标值分配配额 │ ├─ MiTrimMemoryConsumer(Consumer) │ │ │ ├─ 调消费者注册的 Trim 回调 │ │ → 对用户进程MmTrimUserMemory遍历 LRU 链表 │ │ → 对系统缓存调用缓存的修剪函数 │ │ │ ├─ 对每个被选中的页面 │ │ 1. MiUnlinkPageFromList() — 从工作集列表移除 │ │ 2. MmDeleteVirtualMapping() — 解除虚拟映射 │ │ 3. rmap 操作 — 删除反向映射记录 │ │ 4. MmWriteToSwapPage() — 将脏页写入交换文件 │ │ 5. MiInsertStandbyListAtFront() — 放入备用列表 │ │ │ └─ 更新可用页面计数 │ ├─ MiZeroPageThread后台零页线程 │ → 从备用列表取页 → 置零 → 放入零页列表 │ └─ 等待内存压力事件或定时唤醒2.5 池分配器流程ExAllocatePoolWithTag(PoolType, NumberOfBytes, Tag) │ ├─ MmDeterminePoolType() — 确定池类型 │ → 非分页池 / 分页池 / 会话池 / 特殊池 │ ├─ 若为特殊池 → MmAllocateSpecialPool() │ → 分配对齐系统 PTE │ → 在分配区域前后设置填充模式 │ → 返回地址并记录元数据 │ ├─ 若为普通池 │ │ │ ├─ 检查小/中/大页面分配 │ │ → 小 ~4KB从池描述符POOL_DESCRIPTOR列表分配 │ │ → 中从位图管理的池页分配 │ │ → 大调用 MiAllocatePoolPages() 分配整页 │ │ │ ├─ MiAllocatePoolPages() │ │ → 调 MmRequestPageMemoryConsumer() │ │ → 底层调 MiRemoveAnyPage() 或 MiRemoveZeroPage() │ │ → 若失败 → 触发 MiTrimMemoryConsumer() 回收 │ │ → 若仍失败 → 触发 MmRebalanceMemoryConsumers() │ │ │ ├─ 写入池头部Pool Header包含标签、大小、前/后填充模式 │ │ │ └─ 返回分配地址 Pool Header 大小偏移 │ └─ ExFreePoolWithTag(Ptr) ├─ 检查是否为特殊池 → MmFreeSpecialPool() ├─ 检查填充模式是否被覆盖越界检测 ├─ MiFreePoolPages() — 释放底层物理页 └─ 更新配额和统计3. 数据流图3.1 全局数据结构关系┌─────────────────────────────────────────────────────────────┐ │ EPROCESS进程对象 │ │ │ │ VadRoot (AVL 树根) ←────────────────── VAD 节点链表 │ │ ↓ ┌─────────────────┐ │ │ │ VAD 1: 0x00400000-0x00401000 │ StartingVpn │ │ │ │ VAD 2: 0x00402000-0x0040A000 │ EndingVpn │ │ │ │ VAD 3: ..... │ Protection │ │ │ │ │ ControlArea* ──┼──┐ │ │ │ └─────────────────┘ │ │ │ WorkingSetList工作集页面链表 │ │ │ [PFN1, PFN15, PFN32, ...] │ │ │ │ │ │ DirectoryTableBase页目录基址 PFN │ │ └─────────────────────────────────────────────────────────────┘ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ CONTROL_AREA控制区 │◄─┘ │ Segment段对象指针 │ │ FilePointer文件对象指针 ──→ 内存映射文件 │ │ TheaSegment原型 PTE 数组 │ │ NumberOfSectionReferences / NumberOfMappedViews │ └─────────────────────────────────────────────────────────────┘ │ ┌─────────────────────────────────────────────────────────────┐ │ │ PFN DATABASE页帧数据库 │ │ │ │ │ │ MmPfnDatabase[PhysicalPageNumber] │ │ │ ┌──────────────────────────────────────────────────┐ │ │ │ │ PFN Entry~24 字节 │ │ │ │ │ ├─ PageFrameIndex物理页号 │ │ │ │ │ ├─ PteAddress指向映射此页的 PTE ─────→ PTE │ │ │ │ │ ├─ ReferenceCount引用计数 │ │ │ │ │ ├─ ShareCount共享计数 │ │ │ │ │ ├─ Flags页面状态Modified/Dirty/Accessed/... │ │ │ │ │ └─ ListEntry指向所在列表Free/Standby/Mod/Zero│ │ │ │ └──────────────────────────────────────────────────┘ │ │ │ │ │ │ 页面列表链 │ │ │ FreeList[color] ←→ StandbyList[color] ←→ ModifiedList │ │ │ ↕ │ │ │ ZeroedList[color] │ │ └─────────────────────────────────────────────────────────────┘ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ PTE页表项 — 硬件页表 │ │ │ │ │ │ 有效 PTE │ │ │ ┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬──────────────────────────────────┐ │ │ │ │V│R│U│W│C│A│D│L│G│N│ PageFrameNumber │ │ │ │ └─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴──────────────────────────────────┘ │ │ │ 交换 PTE │ │ │ ┌─┬──────────────────────────────────────────────────────┐ │ │ │ │0│ PageFileNumber │ SwapSlotOffset │ │ │ │ └─┴──────────────────────────────────────────────────────┘ │ │ │ 原型 PTE │ │ │ ┌─┬──────────────────────────────────────────────────────┐ │ │ │ │0│ ProtoPteBit │ PageFileNum │ SwapSlotOffset │ │ │ │ └─┴──────────────────────────────────────────────────────┘ │ │ └─────────────────────────────────────────────────────────────┘ │3.2 关键数据流向应用层 │ │ NtAllocateVirtualMemory / NtFreeVirtualMemory / NtProtectVirtualMemory │ NtCreateSection / NtMapViewOfSection ▼ ┌───────────────────────────────────────────────────────────┐ │ virtual.c — 系统调用处理层 │ │ (参数验证、VAD 操作、页表操作) │ └───────────────────┬───────────────────────────────────────┘ │ ▼ ┌───────────────────────────────────────────────────────────┐ │ vadnode.c — VAD 树算法 │ │ (AVL 树插入/删除/查找/空闲区间搜索) │ └───────────────────┬───────────────────────────────────────┘ │ ▼ ┌───────────────────────────────────────────────────────────┐ │ pagfault.c — 缺页异常处理 │ │ (DemandZero / PageFile / Transition / ProtoPte) │ └───┬───────────────┬───────────────┬───────────────────────┘ │ │ │ ▼ ▼ ▼ ┌──────────┐ ┌──────────────┐ ┌──────────────────┐ │pfnlist.c │ │ pagefile.c │ │ rmap.c │ │PFN操作 │ │ 交换文件 I/O │ │ 反向映射管理 │ │页面链表 │ │ 槽位分配/释放│ │ 物理→虚拟查找 │ └────┬─────┘ └──────┬───────┘ └──────────────────┘ │ │ ▼ │ ┌──────────────┐ │ │ freelist.c │ │ │ 物理页统计 │ │ └──────────────┘ │ │ ▼ ┌───────────────────────────────────────────────────────────┐ │ balance.c — 内存平衡器 │ │ (回收策略、修剪消费者、工作集管理) │ └───────────────────────────────────────────────────────────┘ 池分配路径 ExAllocatePoolWithTag / ExFreePoolWithTag │ ▼ ┌───────────────────────────────────────────────────────────┐ │ expool.c — Executive 池分配器 │ │ (池描述符、标签跟踪、配额管理、大页表) │ └───────────────────┬───────────────────────────────────────┘ │ ▼ ┌───────────────────────────────────────────────────────────┐ │ pool.c — 池物理页管理 │ │ (MiAllocatePoolPages / MiFreePoolPages / 非分页池初始化) │ └───────────────────┬───────────────────────────────────────┘ │ ▼ ┌───────────────────────────────────────────────────────────┐ │ pfnlist.c — 底层物理页分配 │ │ (MiRemoveAnyPage / MiRemoveZeroPage / MiInsertPageInList) │ └───────────────────────────────────────────────────────────┘ Section 映射路径 NtCreateSection / NtMapViewOfSection │ ▼ ┌───────────────────────────────────────────────────────────┐ │ section.c — Section 对象管理 │ │ (控制区/段创建、视图映射、原型 PTE 管理、系统空间映射) │ └───┬───────────────┬───────────────────────────────────────┘ │ │ ▼ ▼ ┌──────────────┐ ┌──────────────┐ │ vadnode.c │ │ virtual.c │ │ VAD 插入 │ │ PTE 填充 │ └──────────────┘ └──────────────┘ 系统镜像加载路径 MmLoadSystemImage │ ▼ ┌───────────────────────────────────────────────────────────┐ │ sysldr.c — 系统加载器 │ │ (PE 解析、导入表解析、Thunk 修正、安全 Cookie、可分页性) │ └───┬───────────────┬───────────────────────────────────────┘ │ │ ▼ ▼ ┌──────────────┐ ┌──────────────────┐ │ section.c │ │ virtual.c │ │ 创建 Section │ │ 映射镜像视图 │ └──────────────┘ └──────────────────┘3.3 物理页面生命周期状态机┌──────────┐ ┌────────→│ Free │←────────┐ │ │ (空闲) │ │ │ └────┬─────┘ │ │ │ 分配 │ 释放 │ ▼ │ │ ┌──────────┐ │ │ │ Active │ │ │ │ (活跃) │ │ │ └────┬─────┘ │ │ │ 被换出 │ │ ▼ │ │ ┌──────────┐ │ │ │ Standby │ │ │ │ (备用) │ │ │ └────┬─────┘ │ │ │ 清零 │ │ ▼ │ │ ┌──────────┐ │ │ │ Zeroed │─────────┘ │ │ (已清零) │ │ └──────────┘ │ │ Active → Modified页面被修改 │ Modified → Standby修改写入交换文件后 │ Active → TransitionPFN 被其他进程共享但又暂时释放 │ Transition → Active再次被引用时 │ └── 可用页面总数 Free Zeroed Standby4. 文件大小与关键统计文件估算行数复杂度ARM3/sysldr.c~3600★★★★★ARM3/section.c~3500★★★★★ARM3/virtual.c~3500★★★★★ARM3/expool.c~2500★★★★ARM3/pagfault.c~2000★★★★ARM3/mdlsup.c~2000★★★★ARM3/procsup.c~1800★★★★ARM3/pfnlist.c~1500★★★ARM3/vadnode.c~1200★★★ARM3/mminit.c~1200★★★其余文件1000 各★★5. 关键设计决策5.1 ARM3 vs 旧版 MMARM3对齐 Windows NT 架构支持 x86-64、PAE、大页面、AWE 等特性。代码更结构化复用 Windows 的命名和接口约定。旧版 MMReactOS 原始实现部分功能freelist.c、balance.c、pagefile.c仍被 ARM3 调用。过渡策略ARM3 逐步覆盖旧版功能。目前 ARM3 提供虚拟内存核心virtual.c、池分配器expool.c、缺页处理pagfault.c、Sectionsection.c等主要功能而旧版的marea.c、region.c、rmap.c等已有 ARM3 对应版本。5.2 x86 页表自映射技巧i386 架构下ARM3 利用页目录的最后一项指向页目录自身实现页表的虚拟可寻址性PD[1023] → PD 自身物理地址虚拟地址 PTE_BASE 处可访问页表 PD[1022] → 超空间 PDE用于临时映射物理页 PD[0..1019] → 进程页表项这种设计使得内核可以通过PTE_BASE (index * sizeof(PTE))直接访问任意 PTE无需切换页目录。5.3 PFN 数据库的物理页账本每个物理页对应一个MMPFN条目~24 字节包含引用计数、共享计数PTE 指针指向映射到此页的 PTE页面列表状态Free/Standby/Modified/Zeroed/Bad/Transition颜色索引Cache Color原始访问位和修改位备份PFN 数据库本身位于非分页池中由MmArmInitSystem在 Phase0 构建。6. 与 Windows NT 的差异特性Windows NTReactOS工作集管理器MmWorkingSetManagerKeBalanceSetManagerbalance.cwslist.cpp简化实现修改写入器MiModifiedPageWriter线程依赖balance.c的回调机制逻辑预取MmPrefetchPages完整实现mdlsup.c中有基本实现AWENtAllocateUserPhysicalPages完整ARM3 实现Session Pool完整支持session.c实现功能有限ARM 架构完整大部分为 UNIMPLEMENTED 存根