为什么我的内存检查代码不能正常工作

时间:2013-10-08 06:13:26

标签: c memory memory-management operating-system

我正在尝试实施简单的操作系统,现在必须实现内存管理。

首先,我们输入简单的代码来检查内存大小,如下所示。

我遇到的问题是这个功能的结果取决于增量大小。

如果我将增量​​设置为1024,则此函数返回640Kb 但是,如果我将增量​​设置为1024 * 1024,则此功能返回120Mb (我的系统(bochs)的内存设置为120MB。)

我检查了优化选项和A20门。

有谁知道为什么我的功能不能正常工作?

unsigned int memtest_sub(unsigned int start, unsigned int end)
{
    unsigned int    i;  
    unsigned int*   ptr;
    unsigned int    orgValue;   
    const unsigned int  testValue = 0xbfbfbfbf;

    for (i = start; i <= end; i += 1024*1024) {
        ptr = (unsigned int*) i;
        orgValue = *ptr;
        *ptr = testValue;
        if (*ptr != testValue) {
            break;
        }   
        *ptr = orgValue;
    }   
    return i;
}

2 个答案:

答案 0 :(得分:5)

你不能做那样的探测。

首先,你已经发现的内存不一定是连续的。它几乎从来都不是。 640k的漏洞是出于传统原因,但在内存中更进一步的分裂。您必须向固件询问内存布局。

其次一些存储库可能被双重映射到物理空间,如果你开始使用它们,你最终会陷入困境。这不是很常见,但处理它真的很痛苦。

第三,也许最重要的是,有一些设备映射到该空间。通过写入随机地址,您可能会写入重要硬件的寄存器。写回你读的任何内容对你都不好,因为一些硬件寄存器一旦你写它们就有副作用。事实上,一些硬件寄存器在您阅读时会产生副作用。某些硬件不一定受到保护,您可能会造成永久性损坏。我过去通过在1:1映射内核中存在指针错误而使以太网硬件变硬,因为EEPROM /闪存没有受到保护。你写的其他地方实际上可能会改变内存本身的布局。

由于您最有可能在i386上阅读此内容:http://wiki.osdev.org/Detecting_Memory_(x86)

此外,请考虑使用为您检测内存的引导加载程序,并在定义良好的API中传达您需要知道的内容和其他重要信息。对于所有奇怪的硬件变体,可以更好地调试引导加载程序。

答案 1 :(得分:1)

以下作业有错误:

    ptr = (unsigned int*) i;
    orgValue = *ptr;
    *ptr = testValue; 

ptr没有指向任何有效内存,您不能将i的值视为可以执行某些读写操作的地址 - 未定义的行为