目录
前言
内核(Kernel)总是那么捉摸不透,而且有时也会出BUG,这时我们也应该对内核进行调试,但内核不像软件:内核调试很艰难,内核错误往往会导致系统宕机,很难保留出错时的现场,而且任何对内核空间的访问和修改都可能引发更多错误。同时,市面上的调试工具(例如WinDbg、KD、CDB等)也不能很好的解决这些问题。
机缘巧合之下,发现了一个非常强大的内核调试工具:GDK8(Web: Nano Code GDK8),它是格蠹科技针对ARMv8平台研发的开发和调试平台,GDK8搭配格蠹科技的Nano Debugger(NDB),用他们来调试Linux程序,将Linux平台的调试技术推上一个新的台阶, 是学习和研究ARMv8架构、LINUX操作系统和嵌入式软件技术的有力助手。
GDK8提供两种调试模式供选择:远程调试、内核调试。远程调试:可以调试用户空间的代码和数据,例如打开一个用户空间的可执行程序,或者编辑一些库加载到可执行程序上,但不可访问内核驱动,所以足够安全。内核调试:除了可以调试用户空间的数据外,还可以调试内核空间的代码和数据,并也支持调试驱动,所以足够深入、专业。下面我将介绍一下内核调试。
一、与GDK8创建连接
1 . 将sd转接卡与挥码枪按照以下方式连接(一定不要连错)。
2 . 把杜邦线连接的sd卡插入到GDK8。并用USB线将挥码枪和主机连接。
3 . 切换到GDK8的JTAG模式,通过GDK8的葫芦娃小程序或者遥控器按[Fn+5]进行切换。
4 . 按照顺序来操作Nano Code (若未登录Nano Code请先注册和登录)。
5 . 稍等片刻,观察Nano Code的反馈。
6 . 连接成功后,键盘按[F6]或点击暂停符号进行中断。中断后我们可以输入一些内核调试命令。例如输入[r]来查看通用寄存器信息。
7 . 如图所示,命令反馈正常,此时就可以根据自己的需求来进行个性化的内核调试了。
8 . 更多调试命令可以查看帮助->命令下的命令指南。
二、访问系统寄存器
因为我的开发需求是解析VBAR_EL1寄存器的信息。所以这里要获取该寄存器的地址,
rdmsr VBAR_EL1
此时可以把这个地址记录下来,下次用就不需要再使用rdmsr来获取了。
三、符号化调试
使用ln 命令来获取特定地址处的函数信息
ln ffffff8008081800
这是因为解析函数信息需要符号表,nanocode默认未加载,我们可以手动的加载上。
1 . 把符号表解压到本地磁盘,例如我把符号表放到wucheng目录下(符号表下载链接)
2 . 在Nano Code 里加载符号表
.sympath D:\gedu_work\wucheng (.sympath 后面的参数是符号表本地磁盘路径)
3 . 重启符号表模块(不需要重启nano code)
.reload
4 . 重新测试ln命令
ln ffffff8008081800
5 . 成功显示函数名,说明符号加载成功,我们可以继续解析VBAR_EL1寄存器的信息了。
- 例如查看某个地址处的内存
dd ffffff8008081800
- 查看某个地址处的汇编指令(相当于对dd显示的数据的解析)
u ffffff8008081800
- 显示当前内核的执行状态
k
四、加载项目源码
在调试的时候,大家都喜欢对照着项目源码,而Nano Code也支持这项功能,就比如我这里调试引入GDK8的内核源码。这样就可以对照源码,进行可视化的调试了。
1 . 下载GDK8的源码到本地
2 . 输入命令引入源码,并重启
.srcpath D:\gedu_work\gdk8\kernel-wucheng .reload
3 . 如果程序对应的源码正确,并且引入的路径正确,.reload重启之后Nano Code会自动弹出源码窗口。
五、自定义调试命令
除了可以使用Nano Code现有的命令来调试,还可以编写自己的调试命令。针对不同的项目打造不同的调试命令,来实现个性化的调试环境。就比如,找到Nano Code拓展命令插件ndx.dll源码,我们可以通过修改ndx.dll源码来怎加自己的的调试命令。
1 . 在ndx.def里添加命令
2 . 在ndx.cpp里实现命令
3 . 编译ndx项目
4 . 用刚编译生成的ndx.dll库替换掉Nano Code原本的ndx.dll库。
原本的ndx.dll库在Nano Code安装目录下的exts文件夹下。
5 . 在Nano Code里加载ndx.dll库。
.load ndx .reload
6 . 测试拓展命令
!cmdtest
(注意,在ndx中编写的拓展命令,调用时,前面要加叹号 ! )
7 . 所以,现在自己可以编写独特的拓展命令,针对不同的项目,打造不同的个性化的调试环境。
最后,附上GDK8的美照