1 //// 取消写保护页面函数。用于页异常中断过程中写保护异常的处理(写时复制)。 2 // 在内核创建进程时,新进程与父进程被设置成共享代码和数据内存页面,并且所有这些 3 // 页面均被设置成只读页面。而当新进程或原进程需要向内存页面写数据时,CPU就会检测 4 // 到这个情况并产生页面写保护异常。于是在这个函数中内核就会首先判断要写的页面是 5 // 否被共享。若没有则把页面设置成可写然后退出。若页面是出于共享状态,则需要重新 6 // 申请一新页面并复制被写页面内容,以供写进程单独使用。共享被取消。本函数供下面 7 // do_wp_page()调用。 8 // 输入参数为页表项指针,是物理地址。[up_wp_page -- Un-Write Protect Page] 9 void un_wp_page(unsigned long * table_entry) 10 { 11 unsigned long old_page,new_page; 12 13 // 首先取参数指定的页表项中物理页面位置(地址)并判断该页面是否是共享页面。如 14 // 果原页面地址大于内存低端LOW_MEM(表示在主内存区中),并且其在页面映射字节 15 // 图数组中值为1(表示页面仅被引用1次,页面没有被共享),则在该页面的页表项 16 // 中置R/W标志(可写),并刷新页变换高速缓冲,然后返回。即如果该内存页面此时只 17 // 被一个进程使用,并且不是内核中的进程,就直接把属性改为可写即可,不用再重 18 // 新申请一个新页面。 19 old_page = 0xfffff000 & *table_entry; 20 if (old_page >= LOW_MEM && mem_map[MAP_NR(old_page)]==1) { 21 *table_entry |= 2; 22 invalidate(); 23 return; 24 } 25 // 否则就需要在主内存区申请一页空闲页面给执行写操作的进程单独使用,取消页面 26 // 共享。如果原页面大于内存低端(则意味着mem_map[]>1,页面是共享的),则将原页 27 // 面的页面映射字节数组递减1。然后将指定页表项内容更新为新页面地址,并置可读 28 // 写等标志(U/S、R/W、P)。在刷新页变换高速缓冲之后,最后将原页面内容复制 29 // 到新页面上。 30 if (!(new_page=get_free_page())) 31 oom(); 32 if (old_page >= LOW_MEM) 33 mem_map[MAP_NR(old_page)]--; 34 *table_entry = new_page | 7; 35 invalidate(); 36 copy_page(old_page,new_page); 37 }
原文:https://www.cnblogs.com/llsimplelife/p/14816569.html