1

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

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

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

如果我将增量​​设置为 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;
}
4

2 回答 2

5

你不能那样做探测。

首先,正如您已经发现的那样,内存不一定是连续的。几乎从来没有。640k 处的漏洞是出于遗留原因,但在内存中更远的地方通常会被拆分。您必须向固件询问内存布局。

其次,一些内存库可能会双重映射到物理空间,如果您开始使用它们,您最终会遇到真正的麻烦。这不是很常见,但处理它真的很痛苦。

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

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

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

于 2013-10-08T07:33:42.877 回答
1

以下作业有问题:

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

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

于 2013-10-08T06:15:55.073 回答