进程内存布局

内存管理包含:

  • 物理内存管理
  • 虚拟内存管理
  • 物理内存与虚拟内存的映射

除了内存管理模块, 其他模块都使用虚拟地址(包括内核)

虚拟内存空间包含:

  • 内核空间(高地址)
  • 用户空间(低地址)
     +--------------+
     | kernel space |  high address
     +--------------+
 ^   |    stack     |
 |   +--------------+
 |            ^
         |    |
user     |    |
space    |    |
         v   
     +--------------+
     |     heap     |
     +--------------+
     |     bss      |
     +--------------+
 |   |     data     |
 |   +--------------+
 |   |     text     |
 v   +--------------+  low address

空间存放内容

  • 用户空间:多个进程看到的用户空间是独立的
    从低到高布局为:
    • 代码段
    • 数据段
    • BSS段(未初始化静态变量)
    • 内存映射段
    • 栈地址空间段
  • 内核空间: 多个进程看到同一内核空间, 但内核栈每个进程不一样
    • 内核代码也仅能访问内核空间
    • 内核也有内核代码段, DATA 段, 和 BSS 段; 位于内核空间低地址
    • 内核代码也是 ELF 格式, 只是所处的位置不同

内存映射

分段

  • 虚拟地址 = 段选择子(段寄存器) + 段内偏移量
  • 段选择子 = 段号(段表索引) + 标识位
  • 段表 = 物理基地址 + 段界限(偏移量范围) + 特权等级
  • 段表称为段描述符表, 放在全局标识符表中
  • Linux 将段基地址都初始化为 0, 不用于地址映射
  • Linux 分段功能主要用于权限检查

分页

  • 物理内存被换分为大小固定(4KB)的页, 物理页可在内存与硬盘间换出/换入
  • 页表 = 虚拟页号 + 物理页号; 用于定位页
  • 虚拟地址 = 虚拟页号 + 页内偏移
  • 若采用单页表, 32位系统中一个页表将有 1M 页表项, 占用 4MB(每项 4B)
  • Linux 32位系统采用两级页表: 页表目录(1K项, 10bit) + 页表(1K项, 10bit)(页大小(4KB, 12bit))
  • 映射 4GB 内存理论需要 1K 个页表目录项 + 1K*1K=1M 页表项, 将占用 4KB+4MB 空间
  • 因为完整的页表目录可以满足所有地址的查询, 因此页表只需在对应地址有内存分配时才生成;
  • 64 为系统采用 4 级页表

    X86-64体系结构下内存布局Complete virtual memory map with 4-level page tables

    极客时间刘超老师的《趣谈inux操作系统》相关笔记

Be First to Comment

发表回复