0

我在获取调试器和gdb使用 Linux 内核中的 FIQ 处理程序按预期工作时遇到了困难。它可以很好地触发设置 FIQ 触发条件的驱动程序代码,但不能使用 FIQ。

我正在使用来自 Olimex 的调试ARM-USB-TINY-H器 +imx233-SJTAG转换器(该板没有用于并行 JTAG 的引脚)来调试 i.mx233 板。

我正在gdb 7.5.1使用 buildroot 进行编译,并且openocd 0.6.1来自 Ubuntu 存储库。我启动 openocd:

# openocd -f olimex-arm-usb-tiny-h.cfg -f imx233.cfg

Open On-Chip Debugger 0.6.1 (2012-12-06-17:15)
....
Info : only one transport option; autoselect 'jtag'
trst_and_srst srst_pulls_trst srst_gates_jtag trst_push_pull srst_open_drain
adapter speed: 800 kHz
dcc downloads are enabled
fast memory access is enabled
Info : max TCK change to: 30000 kHz
Info : clock speed 789 kHz
Info : JTAG tap: imx23.cpu tap/device found: 0x079264f3 (mfg: 0x279, part: 0x7926, ver: 0x0)
Info : Embedded ICE version 6
Info : imx23.cpu: hardware has 2 breakpoint/watchpoint units

启动gdb和设置断点:

# arm-buildroot-linux-uclibcgnueabi-gdb vmlinux
....
target remote :3333
Remote debugging using :3333
0x00000000 in ?? ()
(gdb) monitor halt
target state: halted
target halted in ARM state due to debug-request, current mode: Supervisor
cpsr: 0x600000d3 pc: 0xc0019024
MMU: enabled, D-Cache: enabled, I-Cache: disabled
(gdb) hbreak mydriver_userland_write
Hardware assisted breakpoint 1 at 0xc02da930: file drivers/misc/mydriver.c, line 309.
(gdb) c
Continuing.

现在,当我从用户空间向驱动程序发送消息时,gdb 将愉快地触发。

Breakpoint 1, mydriver_userland_write (filp=0xc2cb81c0, buf=0x19d8600 "1\n\235\001t", count=2, f_pos=0xc2cb3f88) at drivers/misc/mydriver.c:309
309                       size_t count, loff_t *f_pos) {

在处理了来自用户空间的信息后,我初始化了 FIQ 触发的条件,并返回。在gdb中,我为 FIQ 设置断点。(第 60 行基本上是清除中断标志后的第 4 条汇编指令)

## Enable catching for FIQ vectors
(gdb) monitor arm9 vector_catch fiq
reset: don't catch
undef: don't catch
swi: don't catch
pabt: don't catch
dabt: don't catch
irq: don't catch
fiq: catch

## setup the breakpoint
(gdb) hbreak myfiq_handler.S:60
Hardware assisted breakpoint 1 at 0xc02db040: file     drivers/misc/myfiq_handler.S, line 60.
(gdb) c
Continuing.

现在一切都设置好了,我触发了导致 FIQ 处理的条件,这就是发生奇怪结果的地方:

Program received signal SIGTRAP, Trace/breakpoint trap.
0xffff001c in ?? ()

在这一点上我真的无能为力:

## Try to see call trace
(gdb) bt
#0  0xffff001c in ?? ()

## Try stepping
(gdb) step
Cannot find bounds of current function
(gdb) next
Cannot find bounds of current function

monitor reg显示像这样的寄存器状态http://paste.ubuntu.com/6113942/ 如果我查看 vmlinux 映射文件,PC 会直接指出文件的最后 4 行:

ffe5095d A __crc_groups_free
fff3672c A __crc_directly_mappable_cdev_bdi
ffffe9f5 A __crc_cfg80211_wext_giwfrag
     w __crc_softirq_work_list

如果我使用stepi命令,整个执行似乎挂起。

我还在学习如何使用gdb,所以我现在真的不知道在哪里寻找问题..欢迎任何建议!

4

1 回答 1

1

FIQ例程被复制到向量表的尾部。ARM向量表的布局是,

  1. 重置
  2. 未定义指令
  3. 软件中断 (SWI)
  4. 预取中止
  5. 数据中止
  6. 4字节孔
  7. IRQ(正常中断)
  8. FIQ(快速中断)。

与分组寄存器一样r8-r14,该FIQ模式直接将执行交给地址0x1c(加上表偏移量)。所有其他异常通常都会执行分支指令。但是,对于FIQ,不需要分支意味着您的汇编程序可以直接执行。

请参阅set_fiq_handler()Linux 的fiq.c中的例程。您的GDB将不知道此重定位,并将在原始地址处放置一个断点。需要注意的是,初始FIQ例程必须是PC 相关的,否则将不会执行。在GDB中,您可以使用b 0xffff001c在初始FIQ指令处设置断点。

与指令一样,其他异常和向量表定义位于文件底部附近的entry-armv.S中,这将被您的例程覆盖。另请参阅vmlinux.lds.S,它是内核的链接器脚本。您有一个0x1000-0x1c的空间作为例程的大小。__vectors_startW(b) vector_fiqFIQ

于 2013-09-16T13:59:31.850 回答