free_page_tables函数

本文参考地址:

1. https://blog.csdn.net/jjavaa/article/details/8115664

2. linux-0.11源码


//// 根据指定的线性地址和限长(页表个数),释放对应内存页表指定的内存块并置表项为
// 空闲。页目录位于物理地址0开始处,共1024项,每项4字节,共占4K字节。每个目录项
// 指定一个页表。内核页表从物理地址0x1000处开始(紧接着目录空间),共4个页表。每
// 个页表有1024项,每项4字节。因此占4K(1页)内存。各进程(除了在内核代码中的进
// 程0和1)的页表所占据的页面在进程被创建时由内核为其主内存区申请得到。每个页表
// 项对应1页物理内存,因此一个页表最多可映射4MB的物理内存。
// 参数:from - 起始线性基地址;size - 释放的字节长度。

 1 int free_page_tables(unsigned long from,unsigned long size)
 2 {
 3     unsigned long *pg_table;
 4     unsigned long * dir, nr;
 5 
 6     // 首先检测参数from给出的线性基地址是否在4MB的边界处。因为该函数只能处理这
 7     // 种情况。若from=0,则出错。说明视图释放内核和缓冲所占空间。
 8     if (from & 0x3fffff)
 9         panic("free_page_tables called with wrong alignment");
10     if (!from)
11         panic("Trying to free up swapper memory space");
12     // 然后计算参数size给出的长度所占的页目录项数(4MB的进位整数倍),也即所占
13     // 页表数。因为1个页表可管理4MB物理内存,所以这里用右移22位的方式把需要复制
14     // 的内存长度值除以4MB.其中加上0x3fffff(即4MB-1)用于得到进位整数倍结果,即
15     // 除操作若有余数则进1。例如,如果原size=4.01Mb,那么可得到结果size=2。
20     size = (size + 0x3fffff) >> 22;
       

//计算给定的线性级地震对应的实际目录项。对应的目录项号=from>>2。由于每项占4字节。且页目录表从物理地址0开始存放因而实际页目录项指针=目录项<<2(即form >>20)
//0xffc确保目录项制作范围有效。因为只移动了20位,因此最后2位页表项索引的内容,应屏蔽掉
21 dir = (unsigned long *) ((from>>20) & 0xffc); /* _pg_dir = 0 */ 22 // 此时size是释放的页表个数,即页目录项数,而dir是起始目录项指针。现在开始 23 // 循环操作页目录项,依次释放每个页表中的页表项。如果当前目录项无效(P位=0) 24 // 表示该目录项没有使用(对应的页表不存在),则继续处理下一个目录项。否则从目 25 // 录项总取出页表地址pg_table,并对该页表中的1024个表项进行处理。释放有效页 26 // 表项(P位=1)对应的物理内存页表。然后该页表项清零,并继续处理下一页表项。 27 // 当一个页表所有表项都处理完毕就释放该页表自身占据的内存页面,并继续处理下 28 // 一页目录项。最后刷新也页变换高速缓冲,并返回0. 29 for ( ; size-->0 ; dir++) { 30 if (!(1 & *dir)) //当前目录项无效,则继续查找,参考下图 31 continue;



32         pg_table = (unsigned long *) (0xfffff000 & *dir);  // 取页表地址
33         for (nr=0 ; nr<1024 ; nr++) {
34             if (1 & *pg_table)                          // 若该项有效,则释放对应页。 
35                 free_page(0xfffff000 & *pg_table);
36             *pg_table = 0;                              // 该页表项内容清零。
37             pg_table++;                                 // 指向页表中下一项。
38         }
39         free_page(0xfffff000 & *dir);                   // 释放该页表所占内存页面。
40         *dir = 0;                                       // 对应页表的目录项清零
41     }
42     invalidate();                                       // 刷新页变换高速缓冲。
43     return 0;
44 }

 

posted @ 2021-04-29 10:38  人生充满不确定性  阅读(192)  评论(0)    收藏  举报