源码位置:mm/memory.c, mm/page.s
1. 内存管理代码主要工作为:
a. 物理内存(基于页框)的分配与释放;
b. 页表到物理内存的映射;
c. 缺页中断;
d. 页面写保护中断;
利用intel的内存管理机器,可实现页面共享.
2. 内存管理函数的归类
A. 中断处理
page.s
B. 页框的分配与释放
get_free_page(void) 获取一个空闲的物理页框,返回物理地址
free_page(addr); 释放一个物理页框,addr为物理地址
C. 线性地址的操作
free_page_tables(from, size); 释放线性地址from开始,size大小的空间(页表也会被释放),要求from是4M字节对齐.
copy_page_tables(from, to, size) ; 复制from 到 to, 只复制到页表级别,实际映射的物理页框共享(启动写保护);
put_page(page, address); 将线性地址page映射到物理页框address;
get_empty_page(address); 将线性地址address映射到一个物理页框(也就是所谓的提交物理内存)
D. 页面保护处理
do_wp_page(error_code, address) 处理线性地址address处发生的写保护异常, un_wp_page(table_entry) 取消table_entry该页面的写保护,使用copy_page复制一个新页面。
write_verify(address) 验证该页面是否可写,防止内核态替用户态强行写数据;
E. 缺页处理
do_no_page(error_code, address); 处理address处的缺页, 如果address是对应于程序体部分则尝试去分享其它进程(执行同一个ELF-file)的code+data, 否则则分配内存。
share_page(address)进行尝试分享其它进程的逻辑地址address处的页面。
try_to_share(address, p); 尝试分享进程p的逻辑地址address处的页面。
F. 内存管理初始化+统计
mem_init(start_mem, end_mem);
calc_mem(void);
疑问:
if (!current->executable || tmp >= current->end_data) { get_empty_page(address); return; }
current->executable何时为空?下面在阅读进程管理部分代码解决之.
A: 进程0和1的executable为空