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
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。