OSDev:为什么我的内存分配功能在AHCI初始化函数中突然停止工作?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OSDev:为什么我的内存分配功能在AHCI初始化函数中突然停止工作?相关的知识,希望对你有一定的参考价值。

在我的内核调用ArchInit()函数内的AHCIInit()函数后,我在其中一个MemAllocate()调用中出现页面错误,这只发生在真机中,因为我尝试在VirtualBox,VMWare和QEMU上复制它。

我尝试调试代码,对内存分配器进行单元测试并从内核中删除所有内容,但内存管理器和AHCI驱动程序本身除外,我发现的唯一一件事就是破坏了分配块,制作了MemAllocate( )页面错误。

整个内核源代码位于https://github.com/CHOSTeam/CHicago-Kernel,但问题可能出现的主要文件是: https://github.com/CHOSTeam/CHicago-Kernel/blob/master/mm/alloc.c https://github.com/CHOSTeam/CHicago-Kernel/blob/master/arch/x86/io/ahci.c

我希望AHCIInit()能够检测并初始化所有AHCI设备并继续启动,直到它到达会话管理器或内核shell,但在实际计算机中,它甚至在初始化调度程序之前就会出现故障(所以不,问题不是'我的调度员)。

答案

如果它在仿真器中工作但在真实硬件上不起作用;然后我怀疑的第一件事是:

  • 物理内存管理中的错误。例如,物理内存管理器初始化不会将“可用RAM区域的起始地址”舍入到页边界或不将“可用RAM区域的结束地址”舍入到页边界,从而导致“半可用RAM和一半不可用RAM” “稍后由堆分配的页面(它在仿真器上工作的地方,因为固件提供的内存映射恰好描述了很好地对齐的区域)。
  • 假设RAM包含零但可能不存在的错误(它在仿真器上工作,因为它们往往会使几乎所有的RAM都充满零)。
  • 竞争条件(不同的时间导致不同的行为)。

然而;这是一个单片内核,这意味着你将不断面对“内核空间中的任何一段代码都会导致其他任何地方的代码都出现问题”;并且存在一堆常见的内存使用错误(例如,意外地写出你分配的内容的结尾)。出于这个原因,我想要更好的工具来帮助诊断问题,尤其是堆。

具体来说,对于堆我应该从金丝雀开始(例如,在堆中的每个内存块之前放置一个像0xFEEDFACE的幻数,在堆中的每个内存块之后放另一个不同的数字;然后检查幻数仍然是在方便的地方出现并纠正 - 例如,当块被释放或调整大小时)。然后我会编写一个“check_heap()”函数,它会尽可能地扫描所有检查的内容(如果统计信息如“空闲块数”实际上是正确的话,那么这些函数就是这样)。这个想法是(每当你怀疑某些东西可能已经破坏了堆)你可以插入对“check_heap()”函数的调用,然后移动该调用,直到找到哪一段代码导致堆损坏。我还建议在你的“kmalloc()或等价物”中有一个“what”参数(例如你可以做像myFooStructure = kmalloc("Foo Structure", sizeof(struct foo));这样的事情),其中提供的“what string”存储在已分配块的元数据中,以便稍后(当你发现堆已经损坏时)你可以在腐败之前显示与块相关联的“什么字符串”,这样你就可以(例如)列出当前有多少类型的东西来帮助确定什么是泄漏内存(例如,如果“Foo Structure”块的数量不断增加)。当然,编译时选项(例如#ifdef DEBUG_HEAP)可以(应该?)启用/禁用这些内容。

我推荐的另一件事是自我测试。这些就像是单元测试,但直接构建在内核本身并始终存在。例如,您可以编写代码来将日光从堆中剔除(例如,分配随机大小的内存块并用内存填充它们,直到内存不足,然后释放其中一半,然后分配更多,直到内存不足为止再次等;同时在每一步之间调用“check_heap()”函数);这段代码可以/应该采取“多少重击”参数(这样你可以花费少量时间进行自检,或者花大量时间进行自检)。您还可以编写代码来从虚拟内存管理器和物理内存管理器(以及调度程序......)中获取日光。然后你可以决定每次内核启动时总是进行少量的自我测试和/或提供一个特殊的内核参数/选项来启用“极其彻底的自测模式”。

不要忘记最终(如果/何时发布操作系统)你可能不得不求助于“通过电子邮件进行远程调试”(例如,没有任何编程经验的人,可能不太了解英语,给你发送一个电子邮件说“操作系统无法正常工作”;你必须设法弄清楚在最终用户“在放弃之前的麻烦之前不再关心”之前出现了什么问题“计数器耗尽了”。

以上是关于OSDev:为什么我的内存分配功能在AHCI初始化函数中突然停止工作?的主要内容,如果未能解决你的问题,请参考以下文章

C++中内存分配问题

处理失败的内存分配

VESA 模式,OSDEV

在C++的class类中,要分配一块大的内存,该如何操作?

malloc内存分配

动态内存分配