Linux操作系统内存管理的源码实现
程序就一个函数调用,很少有这么简单的函数,哈哈!address很显然是程序想要访问但引起出错的线 性地址了。(0xfffff000&*((unsigned long *)((address>>20)&0xffc))计算出32位线性 地址对应页表的地址,再加上一个((address>>10) & 0xffc),就是加上页表内的偏移量,即得 到页表内的一个页表项。看un_wp_page()就更明白了。 221 void un_wp_page(unsigned long * table_entry) 222 { 223 unsigned long old_page,new_page; 224 225 old_page = 0xfffff000 & *table_entry; 226 if (old_page >= LOW_MEM && mem_map[MAP_NR(old_page)]==1) { 227 *table_entry |= 2; 228 invalidate(); 229 return; 230 } 231 &nb 232 oom(); 233 if (old_page >= LOW_MEM) 234 mem_map[MAP_NR(old_page)]--; 235 *table_entry = new_page | 7; 236 invalidate(); 237 copy_page(old_page,new_page); 238 } 225-229做了个判断,如果此物理页面没有被共享,则只要将可写位置1(227)。不然就进入231行去。 在物理内存中分配一页空间,把原页面的内容copy到新页面里(copy_page),再把那个引起出错的 address映射到这个新页面的物理地址上去(235行)。至此,写保护出错的处理完成了,可以返回去执行原 进程里引起出错的那条指令了。 上面所述,就是所谓的“写时复制(copy on write)”。如果是缺页异常的话,则执行do_no_page,最 简单的办法就是直接申请一张物理页面,对应到这个引起出错的address,如下: 372 address &= 0xfffff000; 373 tmp = address - current->start_code; 374 if (!current->executable || tmp >= current->end_data) { 375 get_empty_page(address); 376 return; 377 } (编辑:云计算网_泰州站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |