1.分页机制
- 虚拟内存通过CPU的硬件单元映射到物理内存中,物理内存也以页为单位进行管理,称为物理页面(Physical Page)或者页帧(Page Frame)。
- 进程虚拟地址空间的页称为虚拟页(Virtual Page)
- 操作系统为了管理这些页帧需要按照物理地址顺序给每个页帧编号,称为页帧号(Page Frame Numeber,PFN)
- CPU内部负责虚拟页面到物理页面转换的硬件单元称为内存管理单元(Memory Management Unit,MMU)
- ARM处理器的MMU包括TLB和Table Walk Unit,TLB是一块高速缓存,缓存页表转换的结果,减少内存访问时间
- 一个完整的页表翻译和查找的过程叫做页表查询(Translation Table Walk)
2.虚拟地址到物理地址的转换
当TLB未命中时,处理器按上图流程查询页表
- 处理器根据页表基地址控制寄存器TTBCR和虚拟地址判断使用哪个页表基地址寄存器TTBRx
- 页表基地址寄存器中存放着一级页表的基地址
- 处理器根据虚拟地址的bit[31:20]作为索引,在以及页表中找到页表项
- 一级页表的表项中存放着二级页表的物理基地址,虚拟地址的bit[19:12]作为索引在二级页表中找到相应的页表项。
- 二级页表项里存放着4KB物理基地址。
3.内存布局图
- Linux内核包括内核模式和用户模式
- ARM处理器的user模式共用户进程使用,supervisor模式供内核使用;
- Linux内核通常把0~3G给用户空间, 3GB ~ 4GB给内核空间
- Linux32位的典型内存空间布局图如下
- 内核空间从3GB(0xC000000)开始,
- lowmem(0xC000000 - 0xef800000)是线性映射区,大小为760Mb
- 线性映射区即,物理内存线性的映射到内核空间中
- 物理地址[0:760MB]被线性映射到[3GB:3GB+760MB]的虚拟地址上
- 线性映射区虚拟地址和物理地址相差PAGE_OFFSET,3GB
- 内核空间被分为两大区域,低端区域用于线性映射区,高端区域用于vmalloc区域及其他映射区
4.从进程角度看内存管理
- ELF(Executable and Linkable Format)是linux上流行的可执行文件格式
- 用来定义不同类型的对象文件中存放了什么东西,以及什么格式去存放
- 结构如下图所示
- 常见的几个段(Section):
- 代码段(.text):存放源代码被编译后的机器指令;
- 数据段(.data):存放已经初始化的全局变量和已经初始化的局部静态变量;
- bss段(.bss):存放为初始化的全局变量和未初始化的局部静态变量;
- 可以通过如下指令编译成elf文件
$ arm-linux-gnueabi-gcc -static test.c -o test.elf
- 可以使用readelf工具来查看elf包含哪些段(section)
$ arm-linux-gnueabi-readelf -S test.elf
- 程序在编译时尽量把相同权限属性的段分配在同一个空间里,叫做分段(Segment)
- 描述这些Segment的结构叫做程序头(Program Header),描述了ELF文件是如何映射到进程地址空间的
arm-linux-gnueabi-readelf -l test.elf
- 可以看到上面的31个section被分为了7个segment,并表明了映射关系
- 可以通过proc文件系统动态窥探linux内核运行情况