linux源代码阅读笔记 free_page_tables()分析

76 /*
 77  * This function frees a continuos block of page tables, as needed
 78  * by 'exit()'. As does copy_page_tables(), this handles only 4Mb blocks.
 79  */
 80 int free_page_tables(unsigned long from,unsigned long size)//size以B为单位而不是以页表为单位
 81 {
 82         unsigned long *pg_table;
 83         unsigned long * dir, nr;
 84 
 85         if (from & 0x3fffff)
 86                 panic("free_page_tables called with wrong alignment");
 87         if (!from)
 88                 panic("Trying to free up swapper memory space");
 89         size = (size + 0x3fffff) >> 22;//这里计算size大小的内存占用了多少页表。
 90         dir = (unsigned long *) ((from>>20) & 0xffc); /* _pg_dir = 0 */
 91         for ( ; size-->0 ; dir++) {
 92                 if (!(1 & *dir))
 93                         continue;
 94                 pg_table = (unsigned long *) (0xfffff000 & *dir);
 95                 for (nr=0 ; nr<1024 ; nr++) {
 96                         if (1 & *pg_table)
 97                                 free_page(0xfffff000 & *pg_table);
 98                         *pg_table = 0;
 99                         pg_table++;
100                 }
101                 free_page(0xfffff000 & *dir);
102                 *dir = 0;
103         }
104         invalidate();
105         return 0;
106 }

这个函数的功能是释放一段连续的内存,from是起始地址,size是释放的内存大小。这里需要注意的是,在

这个版本的内核中,size是以B为单位的而不是以页表为单位的。

89         size = (size + 0x3fffff) >> 22;
这句代码,它的含义是将size由以B为单位转化为以页表为单位。怎么理解?
在0.11版本内核中,页长度为4096b,每个页表有1024项。因此,一个页表所索引的内存最大为1024×4096=4MB。
我们可以发现,如果size=4MB*n,那么执行完上面这个语句后,size即为n。
 dir = (unsigned long *) ((from>>20) & 0xffc);
这句代码,是计算起始目录项

 97                                 free_page(0xfffff000 & *pg_table);
这句代码。0xfffff000是保护位,pg_table所指向的页表起始地址的低位一定为0
 
原文地址:https://www.cnblogs.com/elnino/p/4435114.html