我正在尝试实施简单的操作系统,现在必须实现内存管理。
首先,我们输入简单的代码来检查内存大小,如下所示。
我遇到的问题是这个功能的结果取决于增量大小。
如果我将增量设置为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;
}
答案 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
的值视为可以执行某些读写操作的地址 - 未定义的行为