地址空间
- 32位系统,CPU可直接寻址4GB空间,这也是每个进程的地址空间大小。
- 其中,高2GB供内核模块使用,称为内核空间。
- 低2GB供用户态模块使用,称为用户空间。
- 使用/3GB开关,可以将用户空间增大到3GB。
- Windows内容load到内核空间高地址,主程序load到用户空间低地址。
内核空间
- 上面说了,对于32位的系统来说,内核空间有2GB。
- 所有进程共享内核空间。
- 对于32位系统,指的是
0x80000000
到0xFFFFFFFF
之间的空间。而对于64位系统而言,指的则是0x00000400'00000000
到0xFFFFFFFF'FFFFFFFF
之间的地址空间。
线性地址到物理地址
- 操作系统分配给进程的地址空间是逻辑地址(也称为虚拟地址)
- 在现代操作系统中,每个进程都拥有自己的虚拟地址空间。
- 这些虚拟地址并不直接对应于物理内存中的实际位置
- 相反,操作系统和硬件之间的协作使用一种称为虚拟内存管理的技术将这些虚拟地址转换为物理地址
- 好处之一是每个进程都可以像自己拥有整个地址空间一样运行,无需担心其他进程的存在
- 虚拟内存管理还允许操作系统执行许多有用的操作
- 例如页面调度,将不常用的内存页面移出到磁盘上
- 以及“按需加载”内存,即只在需要时才将内存页面加载到物理内存中
- 虚拟地址到物理地址的转换通常由硬件中的内存管理单元(
MMU
)来完成- 操作系统通过设置合适的页面表来控制这个转换过程,详细如下:
- 分割虚拟地址
虚拟地址通常被分割为几个部分。一个常见的方法是将其分为两部分:页目录索引和页表索引。还可能包括一个偏移量,用来在物理页内部寻址 - 使用页目录索引查找页目录
操作系统维护了一个页目录,其中包括指向每个进程页表的指针。通过虚拟地址的页目录索引部分,可以在页目录中找到对应的页表入口 - 使用页表索引查找页表入口
找到页表后,可以使用虚拟地址的页表索引部分来查找具体的页表入口。页表入口会包含物理页帧的地址,这是虚拟页在物理内存中的位置 - 添加偏移量
虚拟地址中的偏移量部分用于定位物理页内的具体字节。将此偏移量添加到物理页帧的地址,得到完整的物理地址 - 处理特殊情况
如果虚拟地址对应的页表入口标记为不在物理内存中(例如,已被交换到磁盘上),则会触发页面错误,操作系统将负责处理,可能包括从磁盘加载所需的页
如果虚拟地址不在进程的合法地址空间内,也会触发页面错误
CR3寄存器
- IA32 CPU用来记录当前页目录表的物理基地址的寄存器,简称PDBR(
Page Directory Base Register
) - 每个进程的最重要属性之一
- 切换任务时,系统会将前一个任务的CR3作为上下文信息(context)的一部分保存起来。
- 在开始执行新任务前,系统会恢复寄存器状态,包括CR3,EFLAGS,EIP等
- 切换CR3寄存器意味着切换地址空间
- 不同的进程拥有不同的地址空间(CR3内容),这是为了隔离与保护。
DPL特权
- 正在执行的代码所在代码段的特权级别就是该代码的特权级别
- 当一段代码调用位于其他段的函数或访问其他段的数据时,CPU会检查发起访问者是否有足够的权限。如果没有通过检查,则产生异常。
内核模块
- NTOS(Kernel-mode services)
- NTOSKENL.EXE
- Scheduing, aka kernel
- Run-time Library,Executive services, object manager,services for I/O,memory,process...
- Hal(硬件适配层)
- 为NTOS及驱动程序隔离硬件差异性
- x hal!*
- Drivers
- 扩展内核的功能,管理设备
HAL.DLL
- 硬件抽象层
- 安装盘中(driver.cab)准备了多个文件,安装程序根据硬件配置选择合适的复制到<WinRoot>\System32目录下
- Hal.dll
- Halacpi.dll:高级配置和电源接口
- Halapic.dll:高级可编程中断控制器
- Halaacpi.dll:ACPI APIC
- Halmps.dll:多CPU
- Halmacpi.dll:多CPU加ACPI
NTOSKENL.EXE
- Windows内核和执行体的PE映像文件,位于<WinRoot>\System32\
- 内容
- 内核
- 执行体
- 以DLL方式输出函数给HAL和其他内核模块
- 内核服务的实现
- 系统初始化和启动(分两个阶段初始化OS内核)
I/O管理器启动boot类型的驱动,然后启动system_start类型的驱动程序
创建SMSS.EXE进程
- 安装程序根据硬件配置将不同版本的文件复制到目标目录下,并将其改为统一的名字
NTOS Kernel
- 内核的内核,OS的底层
- 处理器相关
- 线程等待、调度以及上下文切换
- 异常和中断分支
- 不是一个经典的微内核
- 与其他内核部件共享地址空间
- X nt!ke*
NTDLL.DLL
- 沟通用户空间和内核空间的桥梁
- 用户空间的代码通过这个DLL来调用内核空间的系统服务
- 当内核空间需要用户空间的配合时,也会使用这个DLL,是逆向调用和异常分发的用户态着陆点
- 系统会在启动阶段便把它加载到内存中,并把它映射到所有用户进程的进程空间中,而且是映射在相同的位置(虚拟地址)
- 支持例程,比如程序映像加载,运行时库的函数,异常分发例程,和调用支持例程等
SMSS
- 第一个用户态进程,是NT内核执行体在初始化的最后一步创建的
- 工作
- 执行BootExecute表键中定义的程序
- 执行PendingFileRenameOperations表键中定义的延迟改名操作
- 初始化Paging file和未完成的注册表初始化
- 加载和初始化Win32子系统的内核模块Win32K.sys
- 创建Win32子系统服务器进程,CSRSS
- 创建WinLogon进程
WinLogon
- 启动LSASS(Local Security Authority Subsystem Service)进程
- (WinXP)启动LogonUI进程
- 加载GINA模块(MSGINA.DLL),显示登录对话框
- 启动Services.exe,启动系统服务
本文为原创文章,版权归Aet所有,欢迎分享本文,转载请保留出处!
你可能也喜欢
- ♥ C++20_第二篇03/21
- ♥ Windows_API_Apply_112/31
- ♥ 51CTO:Linux C++网络编程四08/19
- ♥ Windows 窗口以及渲染相关06/15
- ♥ Effective C++_第二篇07/01
- ♥ Windows高级调试_调试器03/19