第2章 内存寻址
1. 内存地址
逻辑地址、虚拟地址、线性地址、物理地址,它们是很绕的逻辑,有些和Intel绑定的概念,没有必要完全区分;
可以认为,地址包括:虚拟地址和物理地址两种。
1.1. 逻辑地址
- 程序编译后的地址
1.2. 线性地址
- 程序运行时的内存地址
1.3. 物理地址
- 内存总线上的地址
- 如果CPU没有分页机制,那么线性地址=物理地址
2. 硬件中的分页
2.1. 分页基础概念
分页单元把RAM分为固定长度(4KB)的页框,每一个页框包含一物理页;
把线性地址映射成物理地址的数据结构叫做页表;页表总是放在主存中;
Intel处理器的每个页的大小为4KB(除非扩展分页);
32bit处理器一共有4GB线性地址(实际物理地址可能没有这么大);
页表也不是一次性全部加载,因此常用的页表也会被记录下来,称为TLB;每个CPU有自己的TLB并且不共享。
2.2. 线性地址
32位的线性地址分为3个域:Directoery(目录,10bit) + Table(页表,10bit) + Offset(偏移量,12bit);
每个页表32bit,4GB / 4KB个页表,占用32bit * (4GB / 4KB) = 4MB,也就是光存页表就花了4MB;
二级分页可以节省页表本身的内存占用,是因为只为进程实际使用的那些虚拟内存区请求页表。
2.4. 硬件高速缓存
① 动态RAM(DRAM)慢速,静态RAM(SRAM)高速
② 引入硬件高速缓存的原因
- CPU时钟频率达到GHZ,DRAM的存取时间是时钟周期的几百倍
- 局部性原理:程序和数据的相邻地址最近被访问到的可能性极大
③ 高速缓存重点介绍
- 写分为通写(既写cache也写RAM)和回写(只写cache),Linux采用回写
- 只有当CPU执行刷新高速缓存指令,或者一个FLUSH硬件信号产生时(缺页时),高速缓存行才被写到DRAM中
- 多处理器系统中,每个cpu都有自己的高速缓存硬件,它们之间会通过硬件互相同步
3. 物理内存布局
3.1. 物理地址不可用情况
- 包含BIOS数据的页框:一般从地址0开始
- 映射硬件设备IO的共享内存(靠前的地址?)
3.2 内核将下面页框置为保留
- 上述不可用物理的页框
- 含有内核代码和已初始化的数据结构的页框
3.3. Linux内核在内存中的占用情况
为了避免把内核装入一组不连续的页框里,Linux跳过RAM第一个MB,用未保留页动态存放所分配的页;
Linux占用页框举例:
0 不可用页框 1 可用页框 0x9f 不可用页框 0x100(_text) 内核代码 _etext 已初始化内核数据 _edata 未初始化内核数据 _end
_text:内核代码第一个字节的地址
_etext:内核代码结束的位置;已初始化内核数据的首地址
_edata:已初始化内核数据的结束;未初始化内核数据的首地址
_end:未初始化内核数据的结束
4. 进程页表
有些线性地址只能内核态访问,有些线性地址内核态和用户态均可访问;
内核维持着自己使用的页表:主内核全局目录。
本文来自博客园,作者:moonのsun,转载请注明原文链接:https://www.cnblogs.com/moon-sun-blog/p/18643097
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?