2013-10-08 37 views
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; 
} 
+2

不要探测内存。在实模式下使用BIOS(因为它看起来像你在x86上)以获得内存布局。见int 15h。 – Macmade

回答

1

下列赋值车:

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

ptr不指向任何有效的存储,你不能把i的值作为地址,在这里你可以进行一些读写操作 - 未定义行为

+1

请注意,作为内核,您可以在任何内存位置读取/写入,特别是禁用中断时。 – Macmade

+0

@Macmade嗯兴趣!我明白,但给我一些链接在这.. –

+0

@Macmade虽然技术上是真实的(即使访问一些内存将只是NMI你死亡中断启用或禁用),这是一个可怕的想法,因为硬件登录到处。 – Art

5

你不能做那样的探针。

首先,内存不一定像您已经发现的那样连续。它几乎从来没有。 640k的漏洞是出于传统原因,但通常情况下,内存中的进一步分裂。你必须问你的固件的内存布局。

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

第三,也许最重要的是,有设备映射到该空间。通过写入随机地址,您可能会写入重要硬件的寄存器。回写你所读的内容对你来说不会有好处,因为一旦你写入硬件寄存器就会有副作用。事实上,一些硬件寄存器在读取时会产生副作用。某些硬件未必受到保护,您可能会造成永久性损坏。由于EEPROM /闪存是未受保护的,因此在1:1映射内核中存在指针错误,因此我过去已经制造了以太网硬件。您写入的其他位置实际上可能会更改内存本身的布局。

既然你是最有可能在i386阅读:http://wiki.osdev.org/Detecting_Memory_(x86)

此外,考虑使用检测内存为你传达,你需要一个定义良好的API中了解其他重要信息的引导装载程序。对于所有奇怪的硬件变体,引导加载程序更好地进行调试。

+0

谢谢你的回复。这对我非常有帮助。一直以来,我觉得需要更多的研究。 ^^〜! – joejo

+0

@joejo只要不断学习。这是一个无尽的领域,尤其是因为硬件制造商会以比您可以全面了解的方式更快地制造新奇怪的设计和错误。操作系统是迄今为止最令人满意的软件。 – Art

相关问题