交叉编译相关知识-------阿冬专栏!!!
来源:互联网 发布:php如何写短信接口 编辑:程序博客网 时间:2024/04/27 14:35
什么是交叉编译?为什么要使用交叉编译?
来自大牛:http://www.2cto.com/kf/201202/118261.html .
在一种计算机环境中运行的编译程序,能编译出在另外一种环境下运行的代码,我们就称这种编译器支持交叉编译。这个编译过程就叫交叉编译。 简单地说,就是在一个平台上生成另一个平台上的可执行代码。这里需要注意的是所谓平台,实际上包含两个概念:体系结构(Architecture)、操作系统(Operating System)。同一个体系结构可以运行不同的操作系统;同样,同一个操作系统也可以在不同的体系结构上运行。举例来说,我们常说的x86 Linux平台实际上是Intel x86体系结构和Linux for x86操作系统的统称;而x86 WinNT平台实际上是Intel x86体系结构和Windows NT for x86操作系统的简称。
有时是因为目的平台上不允许或不能够安装我们所需要的编译器,而我们又需要这个编译器的某些特征;有时是因为目的平台上的资源贫乏,无法运行我们所需要编译器;有时又是因为目的平台还没有建立,连操作系统都没有,根本谈不上运行什么编译器。
交叉编译这个概念的出现和流行是和嵌入式系统的广泛发展同步的。我们常用的计算机软件,都需要通过编译的方式,把使用高级计算机语言编写的代码(比如C代码)编译(compile)成计算机可以识别和执行的二进制代码。比如,我们在Windows平台上,可使用Visual C++开发环境,编写程序并编译成可执行程序。这种方式下,我们使用PC平台上的Windows工具开发针对Windows本身的可执行程序,这种编译过程称为native compilation,中文可理解为本机编译。然而,在进行嵌入式系统的开发时,运行程序的目标平台通常具有有限的存储空间和运算能力,比如常见的ARM 平台,其一般的静态存储空间大概是16到32MB,而CPU的主频大概在100MHz到500MHz之间。这种情况下,在ARM平台上进行本机编译就不太可能了,这是因为一般的编译工具链(compilation tool chain)需要很大的存储空间,并需要很强的CPU运算能力。为了解决这个问题,交叉编译工具就应运而生了。通过交叉编译工具,我们就可以在CPU能力很强、存储控件足够的主机平台上(比如PC上)编译出针对其他平台的可执行程序。
要进行交叉编译,我们需要在主机平台上安装对应的交叉编译工具链(cross compilation tool chain),然后用这个交叉编译工具链编译我们的源代码,最终生成可在目标平台上运行的代码。常见的交叉编译例子如下:
1、在Windows PC上,利用ADS(ARM 开发环境),使用armcc编译器,则可编译出针对ARM CPU的可执行代码。
2、在Linux PC上,利用arm-linux-gcc编译器,可编译出针对Linux ARM平台的可执行代码。
3、在Windows PC上,利用cygwin环境,运行arm-elf-gcc编译器,可编译出针对ARM CPU的可执行代码。
一个经常会被问到的问题就是,“既然我们已经有了主机编译器,那为什么还要交叉编译呢?”其实答案很简单,没办法啊!有时是因为目的平台上不允许或不能够安装我们所需要的编译器,而我们又需要这个编译器的某些特征;有时是因为目的平台上的资源贫乏,无法运行我们所需要编译器;有时又是因为目的平台还没有建立,连操作系统都没有,根本谈不上运行什么编译器。
另一个经常会被问到的问题就是:“既然可以交叉编译,那还要主机编译干吗?”其实答案也很简单,交叉编译是不得已而为之!与主机编译相比,交叉编译受的限制更多,虽然在理论上我们可以做任何形式的交叉编译,但事实上,由于受到专利、版权、技术的限制,并不总是能够进行交叉编译,尤其是在业余条件下!举例来说,我们至今无法生成惠普公司专有的som格式的可执行文件,因此我们根本无法做目的平台为HPPA-HPUX的交叉编译摘自 Gary嵌入式
- 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<span times="" new="" roman";="" mso-hansi-font-family:"times="" roman";mso-bidi-font-family:"times="" letter-spacing:.4pt;mso-fareast-language:zh-cn"="" style="word-wrap: break-word; font-family: 宋体;">是什么?GDB(GNU symbolic debugger) 简单的说是UNIX和LINUX下的一个调试工具。
2.2 GDB的主要特性像所有的调试器一样,GDB可以让你调试一个程序,包括让程序在你希望的地方停下,此时你可以查看变量,寄存器,内存及堆栈。更进一步你可以修改变量及内存值。GDB是一个功能很强大的调试器,它可以调试多种语言。在此我们仅涉及C和C++的调试,而不包括其它语言。还有一点要说明的是,GDB是一个调试器,而不像VC一样是一集成环境。你可以使用一些前端工具如XXGDB,DDD等。他们都有图形化界面,因此用更方便,但它们仅是GDB的一层外壳。因此,你仍应熟悉GDB命令。事实上,当你使用这些图形化界面时间较长时,你才会发现熟悉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调试程序了。
OK,现在就可以开始交叉调试了。
a) 把之前的helloworld修改一下:
- 1 #include <stdio.h>
- 2
- 3 int main(void)
- 4 {
- 5 int a, b, i;
- 6 a = 3;
- 7 b = 4;
- 8 i = a + b;
- 9 printf("i = %d\n", i);
- 10 return 0;
- 11 }
b)交叉编译生成可执行文件之后,放到NFS的挂载目录下
i.在超级终端上执行:
./gdbserver 192.168.1.10:2345 helloworld
ii.在HOST上执行:
arm-linux-gdb helloworld
target remote 192.168.1.128:2345
开始对程序进行调试:
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
- 1 #include <stdio.h>
- 交叉编译相关知识-------阿冬专栏!!!
- doubango协议栈相关知识!!!!-----阿冬专栏
- Servlet和Applet(Java小应用程序)相关知识!!!!------阿冬专栏
- 交叉编译知识简介
- Java中的Annotation知识!!!---阿冬专栏
- 交叉编译相关
- 收藏 交叉编译器 相关知识
- Android编译相关知识
- nginx编译相关知识
- 编译、链接相关知识
- 交叉编译知识解析(一) —— 交叉编译和交叉工具链
- 交叉编译中libtool相关的问题
- Linux交叉编译工具的制作相关
- linux 编译相关知识积累
- 交叉编译的概念(关于嵌入式的一点儿知识)
- GCC 编译过程及相关的知识
- glib 安装解决以及编译相关知识
- 编译原理--文法及相关知识
- ajax和json跟java实现List、Map直接传递
- java 矩阵包
- 第一章 对象的概念
- cocos2d游戏开发中的一些基本概念
- HDU - 1757 A Simple Math Problem 矩阵快速幂
- 交叉编译相关知识-------阿冬专栏!!!
- D. Pair of Numbers Codeforces Round #209 (Div. 2)
- leetcode wordbreak
- Django与MySQL数据库长连接问题
- ORACLE随机获取数据库表的一条记录
- Python爬虫_用Python爬取csdn页面信息目录
- Struts2 面试题
- TCP/IP协议(1)为什么需要tcp/ip协议(亚当需要寻找夏娃)?
- MSP430+QRCode二维码生成