查找地址范围内有多少免费和已用页面

时间:2014-02-07 14:14:06

标签: c kernel osdev

我正在尝试在我为论文撰写的小内核上移植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)

可能有更好的方法来检查页面是否被使用.. 谢谢你的帮助

2 个答案:

答案 0 :(得分:0)

这可能不是你想要的,但它可能会有所帮助。 我曾经做过类似的任务(嵌入式系统的内存分配器),这就是我所做的:

  1. 定义并对齐可分配的页面
  2. 在别处定义一个引用所有页面的数组:我在分配/释放页面时更新arry [idx]值并使计数更容易

答案 1 :(得分:0)

if (x >> 22)检查是否设置了高于21的位。我不知道为什么你换22(看起来像一个任意数字 - 为什么你这样做?)。如果要检查是否存在条目(在任何级别的分页结构中),请检查该条目的第0位。请注意,检查最高位仅在条目被分配了高地址时才会起作用(不会捕获,例如,0x100000)。

另请注意,如果present位为0,则忽略所有其他字节,因此操作系统可以在其中存储任何值,这些信息也可能是有用的信息。