2.12 系统调用sys_brk

1.static void free_pgtables(struct mm_struct * mm, struct vm_area_struct *prev,
2.	unsigned long start, unsigned long end)
3.{
4.	unsigned long first = start & PGDIR_MASK;
5.	unsigned long last = end + PGDIR_SIZE - 1;
6.	unsigned long start_index, end_index;
7.
8.	if (!prev) {
9.		prev = mm->mmap;
10.		if (!prev)
11.			goto no_mmaps;
12.		if (prev->vm_end > start) {
13.			if (last > prev->vm_start)
14.				last = prev->vm_start;
15.			goto no_mmaps;
16.		}
17.	}
18.	for (;;) {
19.		struct vm_area_struct *next = prev->vm_next;
20.
21.		if (next) {
22.			if (next->vm_start < start) {
23.				prev = next;
24.				continue;
25.			}
26.			if (last > next->vm_start)
27.				last = next->vm_start;
28.		}
29.		if (prev->vm_end > first)
30.			first = prev->vm_end + PGDIR_SIZE - 1;
31.		break;
32.	}
33.no_mmaps:
34.	/*
35.	 * If the PGD bits are not consecutive in the virtual address, the
36.	 * old method of shifting the VA >> by PGDIR_SHIFT doesn't work.
37.	 */
38.	start_index = pgd_index(first);
39.	end_index = pgd_index(last);
40.	if (end_index > start_index) {
41.		clear_page_tables(mm, start_index, end_index - start_index);
42.		flush_tlb_pgtables(mm, first & PGDIR_MASK, last & PGDIR_MASK);
43.	}

sys_brk系统调用中,在调用这个函数之前,start到end这块地址对应的vm_area结构体已经被释放了,对应的物理页面的映射也已经断开,在mm->mmap链表中,是找不到start到end对应的vm区间的。free_pgtables作用就是释放所有页表项都已经清零的页表所占的内存,在22行先找到起始地址大于等于start的vm区间,然后判断last是不是大于这个区间的起始地址 ,如果是,说明first到last之间不全是空洞,就需要把这个区间的起始地址赋值给last。同样,还要判断first是不是大于前一个区间的结束地址,是的话,就没问题,否则first地址开始的这一页页面表项就还不是完全清零的,first就需要移动到prev->vm_end后面的一个页目录项对应的页表

prev->vm_start  prev->vm_end  first  start  last   next->vm_start

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值