在内核在ArchInit()函数中调用ArchInit()函数之后,我在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设备并继续启动,直到它到达会话管理器或内核外壳为止,但是在真正的计算机中,它在初始化调度程序之前就出现了页面错误(所以,问题不是我的调度程序)。
发布于 2019-04-14 09:00:40
如果它在仿真器中工作,但在真正的硬件上不起作用,那么我首先要怀疑的是:
然而,这是一个单块内核,这意味着您将继续面临“内核空间中的任何代码都会导致其他地方的任何代码出现问题”;还有一些常见的内存使用错误(例如,不小心编写完分配的代码)。出于这个原因,我需要更好的工具来帮助诊断问题,特别是对于堆。
具体来说,对于堆,我将从金丝雀开始(例如,在堆中的每个内存块之前放置一个神奇的数字,比如0xFEEDFACE,在堆中的每个内存块之后放置另一个不同的数字;然后检查魔术数字是否仍然存在,并在方便的地方更正--例如,当块被释放或调整大小时)。然后,我编写了一个"check_heap()“函数,它尽可能地对所有检查进行扫描(金丝雀,如果像”空闲块数量“这样的统计数据实际上是正确的,等等)。这样做的目的是(每当您怀疑有什么东西可能破坏了堆),您可以插入对"check_heap()“函数的调用,并移动该调用,直到找到导致堆损坏的代码。我还建议在您的"kmalloc()或等效“(例如,您可以执行myFooStructure = kmalloc("Foo Structure", sizeof(struct foo));之类的操作)中有一个”什么“参数,其中提供的”什么字符串“存储在分配的块的元数据中,以便以后(当您发现堆已损坏时)您可以在崩溃之前显示与该块关联的”哪些字符串“,以便您能够(例如)。列出当前每种类型的东西中有多少可以帮助确定内存泄漏的原因(例如,如果"Foo结构“块的数量不断增加)。当然,这些事情可以(应该是吗?)通过编译时选项(例如#ifdef DEBUG_HEAP)启用/禁用。
我推荐的另一件事是自我测试。它们类似于单元测试,但直接内置到内核本身中,并且始终存在。例如,您可以编写代码将日光灯从堆中敲出(例如,分配随机大小的内存并将其填充到内存耗尽,然后释放一半内存,然后再分配更多,直到再次耗尽内存,等等;同时在每一步之间调用"check_heap()“函数);其中该代码可以/应该接受一个”多少撞击“参数(因此您可以花费一小部分时间进行自我测试,或者花费大量时间进行自我测试)。您还可以编写代码,将虚拟内存管理器和物理内存管理器(以及调度程序和.)中的日常事务处理掉。然后,您可以决定每次内核启动和/或提供一个特殊的内核参数/选项时,总是进行少量的自测试,以启用“非常彻底的自测试模式”。
不要忘记,最终(如果/当操作系统发布时),你可能不得不求助于“远程调试via.mail”(例如,没有任何编程经验的人,如果他可能不懂英语,就会给你发一封电子邮件,说"OS不工作“;在最终用户的”放弃和不再关心之前“计数器耗尽之前,你必须试着找出问题所在)。
https://stackoverflow.com/questions/55671191
复制相似问题