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

问题描述 投票:0回答:2

我正在 qemu 虚拟机上使用 u-boot (使用 SPL falcon 模式,其中 u-boot-spl 直接启动 Linux)跟踪 linux 引导加载。现在代码跳转到linux内核,因为我已经完成了

add-symbol-file vmlinux 0x80081000
我可以使用连接到虚拟机的gdb一步步跟踪内核代码。实际上我将内核映像加载到了 0x80080000,但我必须将地址设置为 0x80081000,以使源代码根据 PC 值正确出现在 gdb 上(我不知道为什么需要这个 0x1000 的差异)。
后来我发现内核设置了页表(身份映射和交换表)并跳转到
__primary_switched
,这是PC第一次使用纯内核虚拟地址的地方。这是在 head.S 文件末尾进行调用的地方。

ldr x8, =__primary_switched
adrp    x0, __PHYS_OFFSET
br  x8

在符号文件(vmlinux,一个elf文件)中,__primary_switched之前的符号都映射到虚拟地址(从0xffffffc0.....高地址开始),但即使PC值使用物理值,gdb也可以跟踪源地址。 (PC 最初加载了内核启动的物理地址,并且使用了 PC 相对跳转,直到跳转到

__primary_switched
,mmu 禁用或使用身份映射)这是否意味着,在执行
add-symbol-file
时仅使用文本开头的符号很重要吗?
另一个问题:我可以使用 gdb 跟踪内核源代码,但是在 __primary_switched 之后,我看不到源代码。调试器不会根据现在的内核虚拟 PC 值显示正确的源位置。我应该再次使用 add-symbol-file 告诉调试器使用正确的偏移量吗?如果是这样怎么办?

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

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

我稍微改变了我的程序来解决一个问题。 readelf 显示从 ffffffc010080800 开始的 .text 部分。 所以我将命令调整为“add-symbol-file vmlinux 0x80000800”,并且gdb在跳转到linux后显示了正确的内核源代码。 它仍然没有向我显示 __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”位于.init.text部分,我尝试添加“-s .init.text 0xffffffc010470000”或“-s .init_text 0x803ef800”(物理 地址)到 add-symbol-file 命令无济于事。难道是我的命令错了?或者这可能是来自页表(虚拟 -> 物理)问题,因为我在输入 __primary_switched 后立即看到同步异常(我看到 PC 值已变为 0x200。如果异常向量位于 0x0,则这是同步异常的向量条目就像未定义的指令一样。我还应该检查向量基地址是否设置正确。)

linux-kernel gdb u-boot
2个回答
0
投票

我发现我的内核加载地址错误(__PHYS_OFFSET 低于物理 ddr 地址开始)。 修复后,PC 会随着内核虚拟地址正常递增,我应该使用虚拟地址应用 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

最终内核映像加载于0x80080000。然后 __PHYS_OFFSET 变为 0x80000000。 (TEXT_OFFSET 默认为 0x80000)。现在我可以使用此命令在 __primary_switch 之前调试内核源代码。

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

在内核进入 __primary_switched (现在使用内核虚拟地址)后,我添加了此命令来查看源代码,我可以使用 qemu 和 gdb 逐步跟踪代码。

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

但是几天后,我想我可以使用

add-symbol-file images/vmlinux 0xffffffc010080800
(应用所有部分信息)。


0
投票

-o
add-symbol-file
选项可以是负数,所以我们可以使用
-o
设置相对于
.head.text
节的全局偏移量,那么后面的所有节也会被偏移,不需要单独设置节地址。

举个例子: 内核入口的虚拟地址或

.head.text
0xffffffc010080800
,加载的内核物理地址是
0x80080000
,则
0xffffffc010080800
-
0x80080000
=
0xFFFFFFBF90000800
,然后可以使用
add-symbol-file vmlinux -o -0xFFFFFFBF90000800
来调整偏移量。

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