返回
Linux 0.11 源码分析 - 写时复制的实现
Android
2023-12-02 11:48:49
引言:
写时复制(Copy-on-Write)是一种内存管理技术,允许多个进程共享同一页物理内存,直到其中一个进程尝试写入该页时,才会为该进程创建一个该页的副本。这样可以节省内存空间,并提高系统性能。
Linux 0.11 中的写时复制:
在 Linux 0.11 内核中,写时复制主要通过页表来实现。当进程第一次访问一个页面时,如果该页面不在物理内存中,那么内核会从磁盘上加载该页面到物理内存中,并创建一个新的页表项来映射该页面。
写时复制的步骤:
- 当一个进程尝试写入一个只读页面时,硬件会引发一个页面错误中断。
- 内核捕获这个中断,并检查页面错误的原因。
- 如果页面错误的原因是写保护,那么内核会创建一个该页面的副本,并将该副本分配给该进程。
- 内核然后修改页表,使该进程的页表项指向该页面的副本。
- 进程可以继续执行,并对该页面的副本进行写入操作。
示例代码:
/* 在页面错误中断处理程序中 */
static int do_wp_page(struct task_struct *tsk, struct vm_area_struct *vma,
unsigned long address, int write_access)
{
struct page *page;
void *kaddr;
int err;
/* 获取页面的副本 */
page = alloc_page(GFP_HIGHUSER);
if (!page)
return -ENOMEM;
/* 将页面映射到内核地址空间 */
kaddr = page_address(page);
err = map_page_dirty(vma, address & PAGE_MASK, page);
if (err) {
put_page(page);
return err;
}
/* 将页面的内容从旧页面复制到新页面 */
copy_page(kaddr, vma->vm_file->f_op->mmap(vma, address & PAGE_MASK, PAGE_SIZE,
PROT_READ | PROT_WRITE));
/* 取消映射页面 */
unmap_page(kaddr);
/* 将新页面添加到进程的页表中 */
set_pte_vaddr(tsk, address, mk_pte(page, vma->vm_page_prot));
/* 继续执行 */
tsk->thread.regs->pc += 2;
return 0;
}
总结:
写时复制是一种有效的内存管理技术,可以节省内存空间,并提高系统性能。Linux 0.11 内核中的写时复制是通过页表来实现的,当进程第一次访问一个页面时,如果该页面不在物理内存中,那么内核会从磁盘上加载该页面到物理内存中,并创建一个新的页表项来映射该页面。当一个进程尝试写入一个只读页面时,硬件会引发一个页面错误中断,内核捕获这个中断,并检查页面错误的原因。如果页面错误的原因是写保护,那么内核会创建一个该页面的副本,并将该副本分配给该进程。内核然后修改页表,使该进程的页表项指向该页面的副本。进程可以继续执行,并对该页面的副本进行写入操作。