原创 用PEEDI工具调试Linux核和应用程序

2010-10-11 14:18 1277 4 4 分类: EDA/ IP/ 设计与制造

关键词:调试Linux核,GNU工具链,KaRo Trition起步包,PEEDI,简单快捷;



介绍


基于微形控制器的32位高速ARM的持续流行使得Linux可以进入嵌入式装置的世界。这是需要调试它的核及应用变得重要的原因。Linux是一个多处理开发系统,它利用一个存储管理单元(MMU)给每个过程一个单独的存储空间。MMU也同样为保护每个存储单元区别于其它存储单元负责。不同过程调试间的转换,因此这里我将展示怎么调试Linux核以及应用不受干扰程序被调试。



我用到的工具


为了达到本文的目的,我将用到ARM-ELF和ARM-LINUX GNU工具链,以及带有2个配套原件Trition LP单元的KaRo Trition起步包。Trition板内带有Linux。



设置 PEEDI


除了所有在目标配置文件中共同的设置,这里必须设置两个XScal明确参数。首先是调试控制器的地址。调试控制器是一个2KB调试检测器,就像程序以定义过的虚拟地址下到CPU的微操作快速缓冲贮存区。这个地址被选择,以至于没有用户操作编码被过度写入,这保证了在用户执行编码时CPU没有命令到达。这里有另一个是调试控制器地址的限制——PEEDI的分支命令优先于CPU的重置向量,这允许了分支在+/-32MB之间波动,外向量处于0x0000_0000或者0xFFFF_0000.因此最终的调试地址可能从0x0000_0000到0x01FF_FC00,以及从0xFE00_0000到0xFFFF_FC00,与1KB(0x400)范围均衡,没有与任何用户编码重合。我个人选择地址0xFFFFF800,CPU剩余的2KB的存储空间。


在载入调试控制器后,PEEDI需要优先于CPU的重置向量来指向调试控制器的进入。由于微型指令的快速缓冲贮存区是32位长字节,PEEDI不能优先而只有重置向量可以优先于所有的八个向量。那就是PEEDI必须一直注意应用向量的原因。接下来是第二个XScal明确参数设置,指导PEEDI怎么管理外向量。这里有两个选择——设置向量的连续值,或者让PEEDI每次调试开始时都能恢复向量。每个向量可能有自己的性能设置,因此,如果我们选择连续向量,我们需要在描述有效的ARM指令时设置相应的CORE_VECTOR_XXX参数值,属于用户编码的相应向量.例如:0xE59FF018代表了”LDR pc,[pc,#18]”命令,这对于一个外向量是很普遍的。我个人的选择是第二个——让PEEDI接受每次CPU进入调试控制器后的向量。为了实现它,我会设置所有的CORE_VECTOR_XXX参数为AUTO。即使在应用编码下载时,PEEDI填满向量,这项技术工作效果都很好。有种情况是当PEEDI不能自动下载向量,即当向量运行时的应用被设置。为了在那种困难的时刻帮助PEEDI,你不得不在向量设置后和确保断开前在用户编码处设置一个断点。你可以用三种方式来完成:


1、 设置32位写通道,观察在用户编码向量最后修正的点。


2、 在向量被设置但是不确定处,设置硬件断点到编码点。


3、 在资源编码,向量被设置但是不确定处增加一个软件断点“asm(“bkpt 0”)”。


在目标停止之后,你可以马上重新开始。整个过程可以轻易地在核的初始化部分自动运行,就像这样:



在开始真正的调试之前我们有一件事需要加强注意——确保没有用户编码会打扰调试控制器。尤其是提供Triton板的Linux接口打扰控制器启动,为了阻止它:


——在资源的任一处用“MCR p15,0,rd,c7,c5”代替“MCR p15,0,rd,c7,c5,1”


——在建立Linux核时,使CONFIG_XSCALE_CACHE_ERRATA(XScale快速缓冲区勘误表的工作区)不能正常运行。


现在我们准备好接上电缆,来证实我们迄今为止所完成的。在你接上PEEDI到你的调试板时,如果每件事都是正确的,你可以首先看到红灯亮,在这之后,Linux注册启动。现在你可以键入一些字符来观察Linux正常的工作,然后你可以分配PEEDI命令行界面暂停指令来停止目标,尝试键入更多的字符,没有任何东西出现。现在出现结果命令,你原先键入的字符开始出现。因此我们已经控制目标了。



调试核


为了调试核,我们需要一段ELF格式的程序,包括调试信息,即收集GCC-g附件,这段程序必须在目标中闪存。首先我们要做的是在执行核编码的时候停止目标。使用暂停命令不是一个好的办法,因为我们可能在用户进程中暂停,因此最好在核内设置一个断点或者就像我前面讲到的那样将最后的程序移到初始化部分。现在如果我们重新开始目标,在向量被核的备份编码设置后会断开。这里我们可以在载入ELF核之后在主机上开始gdb/insight。



然后连接PEEDI:



现在我们将用一个简单的步骤让gdb恢复目标状态。



你会看到在执行程序时会停到设置了外向量的the_trap_init()功能,以汇编编码显示,因为它在entry-armv.S汇编源文件中执行。为了调试一些C程序,我们可以举例在主要C文件的start_kernel()功能处设置一个断点,这称为time_init()功能,然后我们可以开始目标。



几秒之后你将看到目标停止,gdb显示带有突出显示行的源文件mian.c,这里有time_init()功能。我们可以放置断点,观察我们希望目标断开,调试并重启的任意点。


如果断点击中了,目标将会停止,gdb会显示相应的源文件。你可以进出功能调用,增加/移动断点,观察变量,检查目标的存储等等。


调试应用


调试Linux应用与调试带有规格参数表的核相似。


以下是我们将调试的“Hello world”类似应用。



我将用-g附件来编制它,包括gdb需要的调试信息。



现在我们已经在目标上启动Linux,等待直到它显示Linux准时注册。以用户和密码来注册,默认的是KaRo提供的Triton-LP。


核提供了一个RAM文件系统,我们可以下载ELF文件的应用,用来调试(当然TFTP服务器必须在主机上运行):



Linux 可能会设置进入权限,因此我们要平息它:



现在我们已经准备好开始我们的应用:



它会显示一行字:“目标不完善…”,然后按它说的做。在main() function的第二行,这并不是“bkpt”汇编程序的要点。我在这里再写上几点:


通常在比计算机应用程序更高的地址执行Linux核,它的地址空间与其它的执行地址空间没有重合。换言之,只有一个虚拟地址空间使用这些存储地址,并且属于核。这允许我们使用硬件断点,观察点,并保证我们只有核将会击中他们。


不像核,用户应用使用相同的虚拟地址(由存储器管理单元转化为不同的部分)。这意味着如果我们设置了一个硬件断点或观察点,任何用户的程序可能会击中它。那是为什么当调试用户的应用程序时必须使用软件断点的原因。这个方式他们被用于调试过程,并保证没有任何其它的过程会击中他们。结果是,必须避免目标的异步停止,因为不能保证CPU在执行调试程序时会停止。这意味着停止PEEDI命令,gdb的CTRL-C,或者内部的停止按钮必须使用。代替软件的断点可能被设置在调试过程停止的地方。这里我需要提及的是你需要从PEEDI的目标配置文件到SOFT设置CORE_BREAKMODE参数。


现在你明白我为什么要使用观察点暂停核了,而不是停止用户程序的应用资源的软件断点。


因此在程序(所有目标)停止之后,我将看到目前的PC值,增长4倍(2假设THUMB编码被调试),重新设回PC。这只有跳过bkpt指令才能完成:



我们可以在主机上开始gdb:



然后 连接PEEDI



现在我们在gdb只需一步就可以恢复目标状态:



从现在开始我们可以像我们调试核一样进行调试,即设置一些软件断点,开始执行:



在断点之后,我们可以一步一步,进出功能调用,检查存储器等等。


结论


调试Linux核,应用可能在第一眼看时觉得困难,但是当你尝试后会变得简单。


在这篇应用笔记,我已经展示了调试Linux核及在X坐标上的应用,但是如果你忽视XScale的特殊性,这是针对所有的ARM。


例如,asm(“bkpt0”)必须被asm(“long BREAK_PATTEN”)代替,BREAK_PATTERN是由PEEDI目标配置文件中CORE_BREAK_PATTERN参数进行价值规定的.


索取更多资料,请联系我们:


广州虹科电子 http://www.hkaco.com 


吴工-38743030  wj@hkaco.com  QQ:534807413

文章评论0条评论)

登录后参与讨论
我要评论
0
4
关闭 站长推荐上一条 /2 下一条