内存独享

4ed91c744220d8b4298237d2ab2eda9d.webp

分段

9697ae17b9f561e78514890f9d58d4eb.webp
7c82068d2d6bdb601084a07569ac8b04.webp

段表全程段描述符(segment descriptors),放在全局描述符表 GDT(Global Descriptor Table)里面。

分页

abbcafe962d93fac976aa26b7fcb7440.webp
8495dfcbaed235f7500c7e11149b2feb.webp
b6960eb0a7eea008d33f8e0c4facc8b8.webp42eff3e7574ac8ce2501210e25cd2c0b.webp7dd9039e4ad2f6433aa09c14ede92991.webp
内存管理.png

  • 内存管理包含: 物理内存管理; 虚拟内存管理; 两者的映射
  • 除了内存管理模块, 其他都使用虚拟地址(包括内核)
  • 虚拟内存空间包含: 内核空间(高地址); 用户空间(低地址)
  • 用户空间从低到高布局为: 代码段; DATA 段; BSS 段(未初始化静态变量); 堆段; 内存映射段; 栈地址空间段
  • 多个进程看到的用户空间是独立的
  • 内核空间: 多个进程看到同一内核空间, 但内核栈每个进程不一样
  • 内核代码也仅能访问内核空间
  • 内核也有内核代码段, DATA 段, 和 BSS 段; 位于内核空间低地址
  • 内核代码也是 ELF 格式

  • 虚拟内存地址到物理内存地址的映射

  • 分段
    • 虚拟地址 = 段选择子(段寄存器) + 段内偏移量
    • 段选择子 = 段号(段表索引) + 标识位
    • 段表 = 物理基地址 + 段界限(偏移量范围) + 特权等级
  • Linux 分段实现
    • 段表称为段描述符表, 放在全局标识符表中
    • Linux 将段基地址都初始化为 0, 不用于地址映射
    • Linux 分段功能主要用于权限检查
  • Linux 通过分页实现映射
    • 物理内存被换分为大小固定(4 KB)的页, 物理页可在内存与硬盘间换出/换入
    • 页表 = 虚拟页号 + 物理页号; 用于定位页
    • 虚拟地址 = 虚拟页号 + 页内偏移
    • 若采用单页表, 32 位系统中一个页表将有 1M 页表项, 占用 4MB(每项 4B)
    • Linux 32 位系统采用两级页表: 页表目录(1K项, 10bit) + 页表(1K项, 10bit)(页大小(4KB, 12bit))
    • 映射 4GB 内存理论需要 1K 个页表目录项 + 1K*1K=1M 页表项, 将占用 4KB+4MB 空间
    • 因为完整的页表目录可以满足所有地址的查询, 因此页表只需在对应地址有内存分配时才生成;
    • 64 为系统采用 4 级页表