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

2010-10-11 15:00 1128 7 7 分类: EDA/ IP/ 设计与制造

关键词:调试ARM Linux核,区分受保护区间,Ronetix PM9261,GNU工具;


1、简介


现在越来越流行的基于32位ARM高速微处理器允许Linux进入嵌入式。这就是调试它的内核和应用软件变得重要的原因。因为Linux是一个多进程的操作系统,它利用一个Memory Management Unit (MMU)给每一个进程分开的存储空间。同时,MMU负责把这些受保护的过程存储空间区分开来。不同进程的选择使得调试变得复杂,现在我将会向你展示如何在没有干预过程下调试Linux核和应用软件。


我需要的一些工具


为了本文的操作说明,我将会用到ARM-ELF ,ARM-LINUX GNU系列工具和Ronetix PM9261。Ronetix 是装有Linux操作系统的。


2.调试内核


2.1内核的建立


2.1.1安装GNU系列工具



wget http://download.ronetix.info/toolchains/arm/ronetix-gnutools-arm-elf-4.1.1-linux.tar.bz2
cd /
tar xvfj ronetix-gnutools-arm-elf-4.1.1-linux.tar.bz2
export PATH=/usr/cross/arm-elf/bin:$PATH
export ARCH=arm
export CROSS_COMPILE=arm-elf-


2.1.2安装和编制Linux核



cd
mkdir ronetix
cd ronetix
wget http://download.ronetix.info/sk-eb926x/linux/kernel/2.6.23.14/linux-2.6.23.14.tar.bz2
wget http://download.ronetix.info/sk-eb926x/linux/kernel/2.6.23.14/2.6.23-at91.patch
wget http://download.ronetix.info/sk-eb926x/linux/kernel/2.6.23.14/linux-2.6.23.14-ronetix-08-04-29.2136.patch
tar xvfj linux-2.6.23.tar.bz2
cd linux-2.6.23.14
patch -p1 < ../2.6.23-at91.patch
patch -p1 < ../linux-2.6.23-ronetix.patch
make pm9261_defconfig
make menuconfig

- go to “Kernel hacking” and enable the “Kernel debugging” option
make clean
make modules

- generate vmImage:
mkdir image
cd image
arm-elf-objcopy -O binary -S ../vmlinux vmlinux.bin
gzip -f9 vmlinux.bin
mkimage -A arm -O linux -T kernel -C gzip -a 0x20008000 -e 0x20008000 -n "PM9261 Linux Kernel Only Image" -d vmlinux.bin.gz vmImage
rm vmlinux.bin.gz
cd ..


编程的二进制文件是:image/vmImage


2.1.3安装核单元


2.1.4产生ROOTFS程序



cd
cd ronetix
wget http://download.ronetix.info/sk-eb926x/linux/rootfs/rootfs-pm926x-openzaurus-20081103.tar.bz2
su -
tar xvfj rootfs-pm926x-openzaurus.tar.bz2
cd linux-2.6.23.14
make INSTALL_MOD_PATH=../openzaurus-gpe-install-ronetix modules_install


编程的二进制文件是:rootfs.jffs2


2.2 U-BOOT,内核和ROOTFS编程


跟启动装入器一样拷贝刚才编写的vmImage 和rootfs.jffs2文件(http://download.ronetix.info/sk-eb926x/linux/bootloader/u-boot-2008.10/u-boot-pm9261.bin)到你的TFTP和FTP的根目录下,改正PEEDI的 configuration文件的路径。


打开系列或者远程操作台到PEEDI:



cd
cd ronetix
mkfs.jffs2 -v -n -d openzaurus-gpe-install-ronetix --little-endian --pad --eraseblock=131072 --pagesize=2048 -o rootfs.jffs2


代替上面的指令,用一个指令就可以编译所有的程序:


2.3核调试


这块板将会由u-boot编程,以vmlinux 和 the rootfs二进制形式。


开始gdb/insight。



telnet 192.168.3.100 ; assuming the IP address of PEEDI is 192.168.3.100

peedi> flash set 0 ; select the first flash profile (U-BOOT)
peedi> flash erase
peedi> flash program

peedi> flash set 1 ; select the second flash profile (Kernel)
peedi> flash program

peedi> flash set 2 ; select the ROOTFS flash profile
peedi> flash erase
peedi> flash program


在gdb的控制窗口:



peedi> run $prog


这块板开始运行了,u-boot第一个启动,然后是Linux核。如果你有系列的控制台,你可以看到Linux开始运行了。现在你可以暂停这个核,设置你想要的断点。


如果你想在核运行之前设置断点,那么用这个暂停指令就不是那么好了,因为我们可能在用户进程里面中断了。所以最好在核里的某一部分设置。比如我们可以在start_kernel() 的main.c处设断点。用nm工具将会发现这个正确的地址。


这个板运行了(先u-boot,后内核),在start_kernel函数里面将会停止。



Arm-elf-insight vmlinux


现在你可以用软件设断点。我们可以把中断和观测点放在我们想要目标中断的点,然后调试它,重新启动。


如果到达了一些中断,目标将会停止,gdb将会显示相应的源文件。你可以进入和跳过引用函数,添加和除掉断点,观察变化的参数和检查目标的存储等等操作。


3,应用软件的调试


调试Linux的应用软件跟调试某些典型的核很相似。这个"Hello world"像我们调试的应用程序。



(gdb) target remote 192.168.3.100:2000
(gdb) set $pc = 0x10000040 ; assuming the u-boot is flashed at 0x10000000
(gdb) c


这个0xDFFFDFFF值指定用PEEDI目标文件里的CORE_BREAK_PATTERN指令,打断add-1指令一定要添加到INIT部分,用来设置中断模式ARM调试记录


我将会用-g选择来完成它,将包括gdb调试文件。


现在我们必须在目标中启动Linux,直到它显示Linux 注册的提示。注册并启动这个应用。


它将会显示一行"Halting the target...",并且执行它。这就体现了在maim()函数第二行的中断模式。我将会在这里给出更多的例子。


通常Linux核是从比用户app更高的地址开始执行的,它的地址空间不会重叠任何其他进程的地址空间。换句话说,这里只有一个虚拟的用这些存储范围的地址空间,它属于内核的。这就允许我们用硬件中断,观察点和保证只有内核可以影响它们。


跟内核不一样,用户的应用软件用同样的虚拟地址(是被MMU转移的不同的物理地址)。这就意味着,如果我们设置硬件中断,观测所有用户的进程的话将有可能影响到它。


这就是为什么当调试用户程序的时候只有用软件中断。这种方式它们就专注于已经调试过的进程,保证没有其它的进程干扰它们。这样的结果就是,目标的异步停止一定要避免。因为不保证当执行调试过程的时候CPU将会停止。


这就意味着暂停PEEDI的指令,gdp的CTRL-C或者里面的停止按钮不一定要用到了。取代软件中断的设置在调试过程必须停止的地方。要提醒你的是你一定要在PEEDI的目标文件里设置CORE_BREAKMODE参数。
    现在你就明白我为什么要用硬件中断来暂停内核了,但是在应用源中的软件中断模式来停止用户的进程。


所以进程(和整个目标)暂停后,我可以看到现在的PC值,增加4(2个在THUMB里面已经调试过了)和设置回PC里。这样做只是跳过bkpt 指令:



(gdb) target remote 192.168.3.100:2000
(gdb) set $pc = 0x10000040 ; assuming the u-boot is flashed at 0x10000000
(gdb) hbreak start_kernel ; hardware breakpoint is used because the MMU is still not active
(gdb) c


我们可以在主机里启动gdp:



(gdb) delete ; delete the hardware breakpoint


然后连接到PEEDI:


我们仅需要一个简单的步骤就可以使gdb修复目标状态:



#include <stdio.h>

int main()
{
printf( "Halting the target...\r\n" );
asm( ".long 0xDFFFDFFF" ); // halt the target and let us put breaks
printf( "Entering eternal loop...\r\n" );

while ( 1 )
{
sleep( 1 );
printf( "tick\r\n" );
}
return 0;
}


现在开始,我们像调试内核一样调试了。即设置一些软件断点然后启动进程:



arm-linux-gcc -g –O0 main.c -o main.elf


当它碰到中断后,我们可以一步一步,进入,走进函数引用,检查存储空间等等。


4.结论


调试Linux核和应用软件可能一开始看起来很难,但是你试过之后就会觉得很简单。


在这个说明书里,我已经展示如何调试ARM Linux核和应用程序。


更多资料,请联系我们:


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


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

文章评论0条评论)

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