繁体   English   中英

我应该如何在 u-boot linux 引导调试期间应用 add-symbol-file 命令?

[英]How should I apply add-symbol-file command during u-boot linux boot debug?

我正在使用 u-boot(使用 SPL falcon 模式,其中 u-boot-spl 直接启动 linux)在 qemu 虚拟机上跟踪 linux 引导加载。 Now the code jumped to linux kernel and because I have done add-symbol-file vmlinux 0x80081000 I can follow the kernel code step by step using gdb connected to the virtual machine. 实际上我将 kernel 图像加载到 0x80080000 但我必须将地址设置为 0x80081000 以使源代码根据 PC 值正确显示在 gdb 上(我不知道为什么需要这种 0x10 差异)。
后来我发现 kernel 设置了页表(身份映射和交换表)并跳转到__primary_switched ,这是纯 kernel 虚拟地址首次用于 PC 的地方。 这是在 head.S 文件末尾进行调用的地方。

ldr x8, =__primary_switched
adrp    x0, __PHYS_OFFSET
br  x8

在符号文件(vmlinux,一个 elf 文件)中,__primary_switched 之前的符号都映射到虚拟地址(从 0xffffffc0 ..... 高地址开始),但 gdb 可以跟随源,即使 PC 值使用物理地址. (PC 最初加载了 kernel 启动的物理地址,并且正在使用 PC 相对跳转,直到它跳转到__primary_switched ,mmu 禁用或使用身份映射)所以这是否意味着,在执行add-symbol-file时,只有文字开头的符号很重要吗?
另一个问题:我可以使用 gdb 关注 kernel 源,但在 __primary_switched 之后,我看不到源。 根据现在的 kernel 虚拟 PC 值,调试器未显示正确的源位置。 我是否应该再次使用 add-symbol-file 告诉调试器使用正确的偏移量? 如果是这样怎么办?

添加(UTC 时间 2022 年 1 月 12 日星期三上午 8:32)
我从 gdb 手册中找到,

"add-symbol-file filename [ -readnow | -readnever ] [ -o offset ] [ textaddress ] [ -s section address... ] add-symbol-file 命令从文件文件名中读取附加的符号表信息。你会当文件名已被动态加载(通过其他方式)到正在运行的程序中时使用此命令。 textaddress 参数给出了文件文本部分已加载的 memory 地址。您可以另外指定其他部分的基地址使用任意数量的“-s 部分地址”对。如果省略部分,gdb 将使用在文件名中找到的默认地址。任何地址或文本地址都可以作为表达式给出。..."

我稍微改变了我的程序来解决一个问题。 readelf 显示从 ffffffc010080800 开始的 .text 部分。 所以我将命令调整为“add-symbol-file vmlinux 0x80000800”,gdb 在跳转到 ZE206A54E97690CCE6Z50CC872DD70EE8 后显示 kernel 源代码正确 __primary_switched 之后它仍然没有向我显示源代码。

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .head.text        PROGBITS         ffffffc010080000  00010000
       0000000000000040  0000000000000000  AX       0     0     4
  [ 2] .text             PROGBITS         ffffffc010080800  00010800
       0000000000304370  0000000000000000  AX       0     0     2048
  [ 3] .rodata           PROGBITS         ffffffc010390000  00320000
   .... (skip) ...
  [12] .notes            NOTE             ffffffc01045be18  003ebe18
       000000000000003c  0000000000000000   A       0     0     4
  [13] .init.text        PROGBITS         ffffffc010470000  003f0000
       0000000000027ec8  0000000000000000  AX       0     0     4
  [14] .exit.text        PROGBITS         ffffffc010497ec8  00417ec8
       000000000000046c  0000000000000000  AX       0     0     4

由于 '__primary_switched' 位于 section.init.text 中,我尝试在 add-symbol-file 命令中添加“-s.init.text 0xffffffc010470000”或“-s.init_text 0x803ef800”(物理地址)无济于事。 我的命令错了吗? 或者这可能来自页表(虚拟->物理)问题,因为我在输入 __primary_switched 后立即看到同步异常(我看到 PC 值已变为 0x200。如果异常向量位于 0x0,这是同步异常的向量条目像未定义的指令。我还应该检查向量基地址是否设置正确。)

我发现我的 kernel 加载地址错误(__PHYS_OFFSET 低于物理 ddr 地址开始)。 修复它后,PC 会以 kernel 虚拟地址正常递增,我应该使用虚拟地址应用 add-symbol-file 命令。
这是新的部分地址。

        Section Headers:
          [Nr] Name              Type             Address           Offset
               Size              EntSize          Flags  Link  Info  Align
          [ 0]                   NULL             0000000000000000  00000000
               0000000000000000  0000000000000000           0     0     0
          [ 1] .head.text        PROGBITS         ffffffc010080000  00010000
               0000000000000040  0000000000000000  AX       0     0     4
          [ 2] .text             PROGBITS         ffffffc010080800  00010800
               0000000000304370  0000000000000000  AX       0     0     2048
          [ 3] .rodata           PROGBITS         ffffffc010390000  00320000
               00000000000a6385  0000000000000000  WA       0     0     4096
          [ 4] .modinfo          PROGBITS         ffffffc010436385  003c6385
               00000000000018ff  0000000000000000   A       0     0     1
          [ 5] .pci_fixup        PROGBITS         ffffffc010437c90  003c7c90
               00000000000020f0  0000000000000000   A       0     0     16
          [ 6] __ksymtab         PROGBITS         ffffffc010439d80  003c9d80
               0000000000006d20  0000000000000000   A       0     0     4
          [ 7] __ksymtab_gpl     PROGBITS         ffffffc010440aa0  003d0aa0
               0000000000005808  0000000000000000   A       0     0     4
          [ 8] __ksymtab_strings PROGBITS         ffffffc0104462a8  003d62a8
               00000000000134f2  0000000000000000   A       0     0     1
          [ 9] __param           PROGBITS         ffffffc0104597a0  003e97a0
               0000000000000b68  0000000000000000   A       0     0     8
          [10] __modver          PROGBITS         ffffffc01045a308  003ea308
               0000000000000cf8  0000000000000000   A       0     0     8
          [11] __ex_table        PROGBITS         ffffffc01045b000  003eb000
               0000000000000e18  0000000000000000   A       0     0     8
          [12] .notes            NOTE             ffffffc01045be18  003ebe18
               000000000000003c  0000000000000000   A       0     0     4
          [13] .init.text        PROGBITS         ffffffc010470000  003f0000
               0000000000027ec8  0000000000000000  AX       0     0     4
  [14] .exit.text        PROGBITS         ffffffc010497ec8  00417ec8

最终的 kernel 图像在 0x80080000 处加载。 然后 __PHYS_OFFSET 变为 0x80000000。 (TEXT_OFFSET 默认为 0x80000)。 现在我可以使用此命令在 __primary_switch 之前调试 kernel 源。

add-symbol-file images/vmlinux 0x80080800 -s .head.text 0x80080000 -s .init.text 0x803f7800

在 kernel 进入 __primary_switched 之后(现在使用 kernel 虚拟地址),我添加了这个命令来查看源代码,我可以使用 qemu 和 ZCA3E1C20EFD5690F9489A87C665 一步步跟随代码。

add-symbol-file images/vmlinux 0xffffffc010080800 -s .head.text 0xffffffc010080000 -s .init.text 0xffffffc010470000 Hope this helps someone later.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM