内存管理包含:
- 物理内存管理
- 虚拟内存管理
- 物理内存与虚拟内存的映射
除了内存管理模块, 其他模块都使用虚拟地址(包括内核)
虚拟内存空间包含:
- 内核空间(高地址)
- 用户空间(低地址)
+--------------+
| 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