(rt-thread gdb)异常向量的设置以及ARM下单步调试的实现
2014-07-14 17:46
330 查看
之前2天时间弄了个框架
以为这个STUB能很快完成
搞了一周后才发现GDB的难度超出了我的预期
好在有其他的代码可以参考
由于自己缺少汇编的编写经验
在异常向量的处理上花了太多的时间
现在看看我用的undef入口代码
代码在bl rt_hw_trap_udef前部分和RTT原本的差不多,都是将寄存器值压入栈供函数使用
有的一点区别就是我们的SP,LR寄存器是先恢复到SVC模式再压栈
因为GDB需要的是sp,lr 而不是sp_udef lr_udef
后半部分主要就是把存入的寄存器覆盖回去.恢复现场
要注意的是这里使用movs pc,lr
因为在undef里 lr_udef寄存器保存的是PC+4的值,我们这里把lr_udef当做了PC传递给函数
但函数修改出来后的值是PC
所以不能用subs 而是直接movs
还有这周主要的工作就是完善了单步执行
大部分的arm架构都是没有支持单步执行的调试单元的
也就是说我们必须用断点来模拟单步执行
= =不过很纠结我的一点就是kgdb将单步执行视为普通的continue
让模拟单步的环节交给GDB
但我找不到是kgdb是如何告诉gdb让他来模拟的.....
所以我只能自己去模拟单步
addr是要设置断点的位置
先是解析当前的指令,看是否需要跳转
如果不需要,那就将断点设置为pc+4
不然 就要对命令作解析
比如 bx lr
那我们就要设置ADDR为lr
大致计划上BeagleBone的工作就差不多了,只剩下大量测试了
多核支持也只能等以后RTT多核完善后再说
接下来是准备去实现对cortexM的支持
一开始是准备对所有的arm使用同一套arch
这套arch同时实现软件断点,硬件断点
但现在看来cortexM带有非常完善的调试单元
而且cortexM大多混用thumb指令
差异较大
所以准备分开实现
cortexA系列.ARM9等等不再去实现硬件断点,因为软件断点已经足够好哟你
cortexM只实现硬件断点
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/899229cfab2c02d614490485cabb781b.gif)
虽然我找不到对cortexM做GDB支持的理由
廉价便宜的各种JTAG,SWD调试器完全满足了需要
以为这个STUB能很快完成
搞了一周后才发现GDB的难度超出了我的预期
好在有其他的代码可以参考
由于自己缺少汇编的编写经验
在异常向量的处理上花了太多的时间
现在看看我用的undef入口代码
.globl vector_undef vector_undef: sub sp, sp, #72 stmia sp, {r0 - r12} @/* Calling r0-r12 */ add r8, sp, #60 mrs r1, cpsr msr cpsr_c, #I_Bit|F_Bit|Mode_SVC mov r0, r0 @mov r2, lr @ Save old lr stmdb r8, {sp, lr} @/* Calling SP, LR */ msr cpsr_c, r1 @/* return to Undefined Instruction mode */ str lr, [r8, #0] @/* Save calling PC */ mrs r6, spsr str r6, [r8, #4] @/* Save CPSR */ str r0, [r8, #8] @/* Save OLD_R0 */ mov r0, sp bl rt_hw_trap_udef ldmia sp, {r0 - r12} @ Calling r0 - r2 mov r0, r0 ldr lr, [sp, #60] @ Get PC add sp, sp, #72 movs pc,lr
代码在bl rt_hw_trap_udef前部分和RTT原本的差不多,都是将寄存器值压入栈供函数使用
有的一点区别就是我们的SP,LR寄存器是先恢复到SVC模式再压栈
因为GDB需要的是sp,lr 而不是sp_udef lr_udef
后半部分主要就是把存入的寄存器覆盖回去.恢复现场
要注意的是这里使用movs pc,lr
因为在undef里 lr_udef寄存器保存的是PC+4的值,我们这里把lr_udef当做了PC传递给函数
但函数修改出来后的值是PC
所以不能用subs 而是直接movs
还有这周主要的工作就是完善了单步执行
大部分的arm架构都是没有支持单步执行的调试单元的
也就是说我们必须用断点来模拟单步执行
= =不过很纠结我的一点就是kgdb将单步执行视为普通的continue
让模拟单步的环节交给GDB
但我找不到是kgdb是如何告诉gdb让他来模拟的.....
所以我只能自己去模拟单步
if (ins_will_execute(curins)) { // Decode instruction to decide what the next PC will be addr = (unsigned long) target_ins((unsigned long*)pc, curins); } else { // The current instruction will not execute (the conditions // don't hold) addr = pc+4; }模拟单步的基本过程就是这样
addr是要设置断点的位置
先是解析当前的指令,看是否需要跳转
如果不需要,那就将断点设置为pc+4
不然 就要对命令作解析
比如 bx lr
那我们就要设置ADDR为lr
大致计划上BeagleBone的工作就差不多了,只剩下大量测试了
多核支持也只能等以后RTT多核完善后再说
接下来是准备去实现对cortexM的支持
一开始是准备对所有的arm使用同一套arch
这套arch同时实现软件断点,硬件断点
但现在看来cortexM带有非常完善的调试单元
而且cortexM大多混用thumb指令
差异较大
所以准备分开实现
cortexA系列.ARM9等等不再去实现硬件断点,因为软件断点已经足够好哟你
cortexM只实现硬件断点
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/899229cfab2c02d614490485cabb781b.gif)
虽然我找不到对cortexM做GDB支持的理由
廉价便宜的各种JTAG,SWD调试器完全满足了需要
相关文章推荐
- arm-linux-gdb+gdbserver环境搭建以及远程调试
- GDB调试_单步运行时,程序运行步骤异常
- GDB多线程调试基本命令和实现简介以及一个常见问题的解决
- arm-linux-gdb+gdbserver环境搭建以及远程调试
- arm下gdb调试和杀线程以及make编译
- arm-linux-gdb+gdbserver环境搭建以及远程调试 及调试core文件
- arm-linux-gdb+gdbserver环境搭建以及远程调试 及调试core文件
- 项目开发中的一些注意事项以及技巧总结 基于Repository模式设计项目架构—你可以参考的项目架构设计 Asp.Net Core中使用RSA加密 EF Core中的多对多映射如何实现? asp.net core下的如何给网站做安全设置 获取服务端https证书 Js异常捕获
- 手把手教你使用eclipse+qemu+gdb来单步调试ARM内核【学习笔记】
- GDB多线程调试基本命令和实现简介以及一个常见问题的解决
- gdb调试要点以及arm-linux交叉工具的使用
- arm-linux-gdb+gdbserver环境搭建以及远程调试
- 用Qt 调用GDB调试 Arm程序 详细步骤----可单步执行每一行
- Linux的GDB远程调试的实现
- 嵌入式Linux的GDB远程调试的实现
- 【嵌入式Linux学习七步曲之第二篇 ARM+Linux开发环境】gdb+gdbserver的方式进行ARM程序调试
- Solaris安装GCC/GDB以及环境变量的设置
- S3C2410 ARM板上构造gdb +gdbserver调试环境
- ARM 向量中断机制在uClinux 下的设计与实现
- 编译安装gdb+insight和gdbserver远程调试arm