【问题标题】:Find how many free and used page there are in a address range查找地址范围内有多少空闲页面和已使用页面
【发布时间】:2014-03-04 23:52:43
【问题描述】:

我正在尝试将 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)

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

【问题讨论】:

    标签: c kernel osdev


    【解决方案1】:

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

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

    【讨论】:

    • 这太酷了,但我正在寻找一种方法来通过查看“页面存在”位来查找页面是否被使用。你能告诉我你是如何检查页面是否存在的吗?非常感谢
    • 好的,我对 liballoc 的工作原理缺乏了解,也许这个 link 可以提供帮助(找到 here
    • 好吧,伙计,我已经检查了该链接,正如我在问题中所说,我想知道“if(((uint32_t)(page)>>22) != 0) " 是检查页面是否标记为存在的好方法
    【解决方案2】:

    if (x &gt;&gt; 22) 检查是否设置了高于第 21 位的 any 位。我不知道你为什么要移动 22 (看起来像一个任意数字 - 你为什么要这样做?)。如果要检查条目是否存在(在任何级别的分页结构中),请检查该条目的位 0。请注意,只有为条目分配了高地址(例如,0x100000),检查最高位才有效。

    还要注意,如果present 位为 0,则所有其他字节都将被忽略,因此操作系统可以在其中存储任何值,这也可能是有一天会派上用场的信息。

    【讨论】:

    • 感谢您的回复,我已经尝试过:if(((uint32_t)(page) & 1) != 0) 但现在所有页面都是免费的(我 100% 确定那些页面存在).. 为什么?
    • 我已经使用 if 语句修复它并以这种方式修改 ptable 表声明:ptable* table = (ptable*)(pagedir[x>>22] & 0xFFFFF000);顺便说一句,我接受您的回答,因为检查每个条目的位 0 以测试页面是否存在是正确的:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-10
    • 1970-01-01
    • 2018-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-07
    相关资源
    最近更新 更多