调试QEMU中的早期内核启动代码

问题描述 投票:5回答:1

我将一些代码(汇编和C的混合)编译成ELF二进制文件,QEMU中的某些固件/引导加载程序代码加载到特定的物理地址。 ELF使用虚拟地址链接;但是,代码是在关闭MMU的情况下运行的,这意味着它需要与位置无关。

问题是PC被设置为入口点的物理地址,这是有道理的,但由于所有符号都是使用虚拟地址引用的,因此GDB不知道入口点在哪里。

我仍然可以在MMU打开时调用的函数上设置断点(因此PC将在那时处理虚拟地址),但这不足以调试早期代码,包括单步执行它。

我已经能够通过使用物理地址链接来调试此代码,但显然这会在我打开MMU时立即产生问题。

有谁知道我在这里缺少什么?

c assembly arm gdb qemu
1个回答
1
投票

我不认为您的问题特别针对QEMU(甚至是ARM)。我相信至少有三种方法可以解决这个问题,

  1. 只需使用汇编程序
  2. 使用symbol-file
  3. 叠加

汇编

我有这个问题,但只会切换到检查汇编程序。如果您使用MMU /普通地址版本objdump -S来匹配汇编程序,这是相当容易的。您可以将objdump输出传递给文件,并根据需要删除未重定位的代码。但是,大多数编辑器都能够处理大文件。

查看汇编程序可能非常有用,因为通常某种重定位常量或非PIC类型引用不正确。您需要两个代码/数据都是正确的,并且您的PIC代码可能会调用一些gcc库例程链接到您未考虑的某个位置。因此虽然这是原始的,但它确实有一些优点。

这很有趣

另一种方法是使用symbol-file所拥有的。在启动期间使用symbol-file的物理链接,然后在MMU切换后使用MMU /普通链接的symbol-file。显然加载MMU版本。

叠加

我认为你可以用overlays处理这个问题,尽管你实际上正在做反向。 VMA是MMU地址,LMA是物理引导地址。将其标记为最初映射,然后在打开MMU时可以使用_ovly_debug_event()进行更新。

覆盖采用代码,但它是最方便的。如果您已经在软件开发系统中拥有“调试”构建目标并对该代码进行了条件化,我会尝试这样做。但是,如果您在ld中使用实际叠加层,它实际上可能会解决您的一些问题,您可能会发现它最强大。覆盖资源影响非常小,但它存在。


参考

这些参考文献是关于为什么要调试它的编码问题。

© www.soinside.com 2019 - 2024. All rights reserved.