zoukankan      html  css  js  c++  java
  • 交叉编译和交叉调试环境搭建及使用

    交叉编译和交叉调试环境搭建及使用



    1. 交叉编译器

    1.1 交叉编译器介绍

    在一种计算机环境中运行的编译程序,能编译出在另外一种环境下运行的代码,我们就称这种编译器支持交叉编译。这个编译过程就叫交叉编译。简单地说,就是在一个平台上生成另一个平台上的可执行代码,而这种工具就是交叉编译器(cross compiler)。

    1.2 搭建交叉编译环境 


    1.2.1 实验环境

    交叉编译工具:arm-linux- 4.2.2

    编译平台:ubuntu10.10

    开发板类型:UT-S3C6410

    1.2.2 搭建步骤

    1) 在/usr/local/下建立交叉编译器的安装目录arm:

    sudo  mkdir /usr/local/arm

    2)将下载的交叉编译器包解压到/usr/local/arm目录下:

    sudo tar jxvf cross-4.2.2-eabi.tar.bz2 -C /usr/local/arm/ 

    3)解压成功后,修改PATH环境变量:

    sudo vim  /etc/profile

    在文件为加入交叉编译器arm-linux-所在的路径:

    export PATH=$PATH:/usr/local/arm/4.2.2-eabi/usr/bin

    然后退出vim。

    4) 更新一下配置文件/etc/profile:

    source /etc/profile

    5)检测是否安装成功:

    现在就可以使用交叉编译器了,写一个测试程序helloworld,交叉编译下,看是否能在开发板上运行。

             i. 交叉编译测试程序

    arm-linux-gcc helloworld.c -o helloworld

             ii.把生成的可执行文件helloworld复制到NFS的挂载目录下:

    sudo  cp ./helloworld   /nfsboot

    注意:本实验中开发板使用NFS挂载rootfs,nfsboot是NFS的挂载目录。

            iii.在超级终端上运行:

    ./helloworld

    执行结果:

    2. 交叉调试GDB的介绍和使用
    2.1 GDB是什么?

    GDB(GNU symbolic debugger) 简单的说是UNIX和LINUX下的一个调试工具。

    2.2 GDB的主要特性

    像所有的调试器一样,GDB可以让你调试一个程序,包括让程序在你希望的地方停下,此时你可以查看变量,寄存器,内存及堆栈。更进一步你可以修改变量及内存值。GDB是一个功能很强大的调试器,它可以调试多种语言。在此我们仅涉及C和C++的调试,而不包括其它语言。还有一点要说明的是,GDB是一个调试器,而不像VC一样是一集成环境。你可以使用一些前端工具如XXGDB,DDD等。他们都有图形化界面,因此用更方便,但它们仅是GDB的一层外壳。因此,你仍应熟悉GDB命令。事实上,当你使用这些图形化界面时间较长时,你才会发现熟悉GDB命令的重要性。

    2.3 GDB的安装

    1)下载源码:

    可以从http://www.gnu.org/software/gdb/download/获取到最新的GDB版本。

    2)先做一些准备工作:

    a)Sudo mkdir –p /usr/local/arm-gdb

    b)Sudo chown –R cjok /usr/local/arm-gdb

    c)cd Download

    3)然后开始编译arm-linux-gdb

    a)解压gdb包:

            tar zxvf gdb-7.2.tar.gz

    b) 配置configure文件:

    cd gdb-7.2/

    ./configure --target=arm-linux  --prefix=/usr/local/arm-gdb

    c)编译和安装

    make

    sudo make install

    d)cd到/usr/local/arm-gdb/目录下会看到

    cd  /usr/local/arm-gdb

    ls

    e)然后把arm-linux-gdb所在的路径添加到PATH环境变量中:

    sudo vim /etc/profile

    在文件为加入export PATH=$PATH:/usr/local/arm-gdb/bin

    source /etc/profile

    查看一下:

        

    4)编译gdbserver

    a)配置configure文件

    cd  gdb-7.2/gdb/gdbserver/

    ./configure --target=arm-linux --host=arm-linux

    b)编译

    make CC=arm-linux-gcc

    c)把刚刚生成的gdbserver拷贝到NFS共享目录下,因为gdbserver最终是在目标机上运行:

    sudo cp gdbserver /nfsboot/

    5) 测试gdbserver

    a)编译一个简单的程序helloworld.c

    arm-linux-gcc –g helloworld.c –o helloworld

    cp helloworld /nfsboot

    *记得编译时,加-g选项

    b)库问题

    需要注意的是运行gdbserver还需要libthread_db库,如果你做的文件系统里没有相应的库,需要从交叉编译器内拷贝一个过去。

    cp –avf /usr/local/arm/4.2.2-eabi/lib/libthread_db*   /nfsboot/lib

    注意:若不知道少了什么库,可以根据运行时错误提示拷贝。

    c)到超级终端上启动gdbserver

    ./gdbserver 192.168.1.10:2345 helloworld

    注意:我用的HOST IP是192.168.1.10,2345是监听端口,可以随便设定

    然后会出现:

    d)然后在主机上启动gdb:

    cd /nfsboot   

    arm-linux-gdb helloworld

    会出现:

    链接到开发板上:

    target remote 192.168.1.128:2345

    注意:192.168.1.128是开发板的IP,2345是监听端口,要与上面设置的相同

    这是超级终端会出现:

    e)设置一下gdb环境变量

     show solib-absolute-prefix

     set solib-absolute-prefix /usr/local/arm/4.2.2-eabi/lib/

    usr/local/arm/4.2.2-eabi/lib/ 是交叉编译器的库路径

     show solib-search-path

     set solib-search-path /nfsboot/lib/

    /nfsboot/lib是文件系统的库路径

    注:红色部分为执行的指令。

    到此环境已经搭建好,现在可以像在Linux下用GDB调试程序了。

    2.4 GDB的使用

    OK,现在就可以开始交叉调试了。

    a) 把之前的helloworld修改一下:

    1. 1 #include <stdio.h>
    2.   2
    3.   3 int main(void)
    4.   4 {
    5.   5 int a, b, i;
    6.   6 a = 3;
    7.   7 b = 4;
    8.   8 i = a + b;
    9.   9 printf("i = %d ", i);
    10.  10 return 0;
    11.  11 }

    b)交叉编译生成可执行文件之后,放到NFS的挂载目录下

      

          i.在超级终端上执行:

    ./gdbserver 192.168.1.10:2345 helloworld      

            ii.在HOST上执行:

    arm-linux-gdb helloworld

    target remote 192.168.1.128:2345

    开始对程序进行调试:

    2.5 GDB的常用指令

       load:装入一个程序;

       symbol-file:装入符号库文件,可以是用-g参数编译的可执行文件;

       f(ile):指定一个可执行文件进行调试,gdb将读取些文件的调试讯息,如f a.exe;

       l(ist):列程序出源文件;

       r(un) :装载完要调试的可执行文件后,可以用run命令运行可执行文件;

       b(reak):设置断点(break point),如b 25,则在源程序的第25行设置一个断点,当程序执行到第25行时,就会产生中断;也可以使用b funcname,funcname为函数的名称;

    当程序运行到断点停下来时:

       c(ontinue):c命令可以另中断的程序继续执行,直到下一个中断点或程序结束;

       p(rint):输入某个变量的值,如程序定义了一个int a的就是,p a就会输出aa的当前值;

       n(ext):程序执行到断点时中断执行,可以用n指令进行单步执行;

       s(tep):程序执行到断点时中断执行,可以用s指令进行单步执行进某一函数;

       q(uit):退出GDB

  • 相关阅读:
    MD5加密40位加密规律
    python中 if __name__ == '__main__': 浅解
    python3关于邮件的操作
    ecshop莫名其妙出现“Table '.starecs_stats' is marked as crashed and should be repaired”
    微擎安装问题
    蝉知CMS本地迁移到服务器具体步骤
    React Hooks useContext + useReducer实现简易Redux
    git merge时merge/squash merge/rebase merge的区别
    FormData 和 Content-Type: multipart/form-data
    对Promise.prototype.finally()的粗浅理解
  • 原文地址:https://www.cnblogs.com/lidabo/p/4499011.html
Copyright © 2011-2022 走看看