我正在尝试将libaloc放在我为论文中写的一个小内核上。为了做到这一点,我需要一个扫描一系列地址的函数才能查找免费(和二手)页面。我写了扫描和地址的该功能(应该对其进行paget对齐),并在使用页面免费或使用:
的情况下打印: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: %dn",PAGE_TABLE_INDEX (y));
}
else{
cfreepage++;
kernelPrintf("Found free page number: %dn",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: %dn",cusedpage);
kernelPrintf("Free Pages Found: %dn",cfreepage);
return 0;
}
此代码有效,但有一个问题:使用的一些页面将免费。我认为问题是:
if(((uint32_t)(page)>>22) != 0)
可能有更好的方法来检查是否使用了页面。感谢您的帮助
if (x >> 22)
检查是否设置了高于21的。我不知道为什么您转移22(看起来像一个任意号码 - 为什么要这样做?)。如果要检查是否存在条目(在任何级别的分页结构中),请检查该条目的位0。请注意,只有在分配高地址的条目时,检查最高位才能起作用(例如,0x100000)。
还要注意,如果present
位为0,则所有其他字节都被忽略了,因此OS可以在其中存储任何值,这也可能是有一天会方便的信息。
这也许不是您想要的,但可能会有所帮助。我曾经有一个类似的任务要做(嵌入式系统的内存分配器),这是我所做的:
- 定义并对齐可分配的页面
- 在其他地方定义一个引用所有页面的数组:当我分配/发布页面时,我更新arry [idx]值,并且使计数变得容易