我正在尝试在我为论文撰写的小内核上移植liballoc。 为了做到这一点,我需要一个扫描一系列地址的函数来查找空闲(和使用过的)页面。 我写了那个扫描和地址的功能(它应该是页面表对齐)并打印一个页面是免费的还是被使用的:
uint32_t check_pages(uint32_t startAddr,uint32_t length){
pdirectory* dir = vmm_get_directory ();
pd_entry* pagedir = dir->m_entries;
int cfreepage = 0;
int cusedpage = 0;
uint32_t x = 0, y = 0;
for(x = startAddr; x < (startAddr+length) ; x+=4096*1024){ // check 1 pagetable at a time
if(pagedir[x>>22] != 0){ // check if pagetable exist
ptable* table =(ptable*) pagedir[x>>22];
for(y=x;;y+=4096){ // scan every single pages in the pagetable
pt_entry* page = (pt_entry*)table->m_entries [ PAGE_TABLE_INDEX (y) ];
if(((uint32_t)(page)>>22) != 0){ // check if a page is present FIXME this might be the problem
cusedpage++;
kernelPrintf("Found used page number: %d\n",PAGE_TABLE_INDEX (y));
}
else{
cfreepage++;
kernelPrintf("Found free page number: %d\n",PAGE_TABLE_INDEX (y));
}
if(PAGE_TABLE_INDEX (y)==1023) break;
}
}
else{ // if a pagetable doesn't exist add 1024 free pages to the counter
kernelPrintf("found free pagetable! (1024 free pages)\n");
cfreepage+=1024;
}
}
kernelPrintf("Used Pages Found: %d\n",cusedpage);
kernelPrintf("Free Pages Found: %d\n",cfreepage);
return 0;
}
此代码有效,但有一个问题:使用的某些页面将免费提供.. 我认为问题是如果:
if(((uint32_t)(page)>>22) != 0)
可能有更好的方法来检查页面是否被使用.. 谢谢你的帮助
答案 0 :(得分:0)
这可能不是你想要的,但它可能会有所帮助。 我曾经做过类似的任务(嵌入式系统的内存分配器),这就是我所做的:
答案 1 :(得分:0)
if (x >> 22)
检查是否设置了高于21的位。我不知道为什么你换22(看起来像一个任意数字 - 为什么你这样做?)。如果要检查是否存在条目(在任何级别的分页结构中),请检查该条目的第0位。请注意,检查最高位仅在条目被分配了高地址时才会起作用(不会捕获,例如,0x100000)。
另请注意,如果present
位为0,则忽略所有其他字节,因此操作系统可以在其中存储任何值,这些信息也可能是有用的信息。