分类: 嵌入式
2011-09-13 21:05:01
嵌入式Linux开发环境构建
构建嵌入式Linux开发环境,就是构建交叉编译环境。嵌入式系统没有自主开发能力,需要在PC机上生成可执行代码
交叉编译环境
在一个平台上生成另一个平台上的可执行代码
所谓平台,实际上包含两个概念:
1、体系结构
2、操作系统
Linux交叉编译工具的组成
Linux交叉编译工具是工作在Linux操作系统下的一套由编译器、链接器和 libc 库等组成的开发环境。
n binutils 包含ld、ar、as等一些产生或处理二进制文件的工具
n gcc gcc主体部分
n glibc 用户层应用用到的库
n gdb 目标系统的程序调试器
二进制工具集
n binutils是一组二进制工具程序集,是辅助GCC的主要软件,它主要包括
n addr2line 把程序地址转换为文件名和行号。在命令行中给它一个地址和一个可执行文件名,它就会使用这个可执行文件的调试信息指出在给出的地址上是哪个文件以及行号。
n ar 建立、修改、提取归档文件。归档文件是包含多个文件内容的一个大文件,其结构保证了可以恢复原始文件内容。
n as 是GNU汇编器,主要用来编译GNU C编译器gcc输出的汇编文件,他将汇编代码转换成二进制代码,并存放到一个object文件中,该目标文件将由连接器ld连接
n C++filt解码C++符号名,连接器使用它来过滤 C++ 和 Java 符号,防止重载函数冲突。
n gprof 显示程序调用段的各种数据。
n ld 是连接器,它把一些目标和归档文件结合在一起,重定位数据,并链接符号引用,最终形成一个可执行文件。通常,建立一个新编译程序的最后一步就是调用ld。
n nm 列出目标文件中的符号。
n objcopy把一种目标文件中的内容复制到另一种类型的目标文件中.
n objdump 显示一个或者更多目标文件的信息。使用选项来控制其显示的信息。它所显示的信息通常只有编写编译工具的人才感兴趣。
n ranlib 产生归档文件索引,并将其保存到这个归档文件中。在索引中列出了归档文件各成员所定义的可重分配目标文件。
n readelf 显示elf格式可执行文件的信息。
n size 列出目标文件每一段的大小以及总体的大小。默认情况下,对于每个目标文件或者一个归档文件中的每个模块只产生一行输出。
n strings 打印某个文件的可打印字符串,这些字符串最少4个字符长,也可以使用选项-n设置字符串的最小长度。默认情况下,它只打印目标文件初始化和可加载段中的可打印字符;对于其它类型的文件它打印整个文件的可打印字符,这个程序对于了解非文本文件的内容很有帮助。
n strip 丢弃目标文件中的全部或者特定符号。
n libiberty 包含许多GNU程序都会用到的函数,这些程序有: getopt, obstack, strerror, strtol 和 strtoul.
n libbfd 二进制文件描述库.
n libopcodes 用来处理opcodes的库, 在生成一些应用程序的时候也会用到它, 比如objdump.Opcodes是文本格式可读的处理器操作指令.
库文件使用举例
源程序add.c和sub.c
//add.c
int add(int a, int b)
{
return a+b;
}
//sub.c
int sub (int a, int b)
{
return a+b;
}
主程序:
#include
int main(void)
{
printf(“add %d”,add(9,5));
printf(“add %d”,sub(9,5));
}
编译成目标文件
gcc –c add.c sub.c
建立库文件
ar rv libtest.a add.o sub.o
ar的rv参数的说明:
r:将多个文件组成一个文件
v:输出信息
在编译时指定库文件
gcc mian.c –ltest –L.
-ltest指明将libtest.a链接进来、-L.指明在当前目录下查找库文件
Diff和patch工具
Diff命令的功能为逐行比较两个文本文件,列出其不同之处,也可以用来制作补丁文件。
Path命令被用来打补丁——就是依据补丁文件来修改原始文件。
内核补丁
生成 diff -uNr linux-2.6.xxx linux-2.6.xxx.1 > diff.patch
升级 cp diff.patch linux-2.6.xxx/.
cd linux-2.6.xxx
patch -p1 < diff.patch
Diff命令参数
-u 比较结果中输出上下文中一些相同的行,这有利于人工定位
-r 递归比较各个子目录的文件
-N 将不存在的文件当作空文件
Patch命令参数
-pn 表示忽略路径中第n个斜线之前的目录
CVS
n CVS(Concurrent Versions System)是一个C/S系统,多个开发人员通过一个中心版本控制系统来记录文件版本,从而达到保证文件同步的目的。CVS版本控制系统是一种GNU软件包,主要用于在多人开发环境下的源码的维护。
n CVS的基本工作思路是这样的:在一台服务器上建立一个源代码库,库里可以存放许多不同项目的源程序。由源代码库管理员统一管理这些源程序。每个用户在使用源代码库之前,首先要把源代码库里的项目文件下载到本地,然后用户可以在本地任意修改,最后用CVS命令进行提交,由CVS源代码库统一管理修改。这样,就好像只有一个人在修改文件一样,既避免了冲突,又可以做到跟踪文件变化等。
n 一个项目的首次导入
n cvs import -m "write some comments here" project_name vendor_tag release_tag
n 项目导出:将代码从CVS库里导出
n cvs checkout project_name
n cvs update file_name
n cvs add new_file
n cvs ci -m "write some comments here"
n 项目发布导出不带CVS目录的源文件
n 做开发的时候你可能注意到了,每个开发目录下,CVS都创建了一个CVS/目录。里面有文件用于记录当前目录和CVS库之间的对应信息。但项目发布的时候你一般不希望把文件目录还带着含有CVS信息的CVS目录吧,这个一次性的导出过程使用cvs export命令,不过export只能针对一个TAG或者日期导出,比如:
n cvs export -r release1 project_name
n cvs export -D 20021023 project_name
n cvs export -D now project_name
创建交叉编译环境
1 拷贝交叉编译器到工作目录
cp arm-linux-gcc-4.3.2.tgz ~/
解压交叉编译器包
tar –zxvf arm-linux-gcc-4.3.2.tgz
设置环境变量
export PATH=$PATH:~/usr/local/arm/4.3.2/bin
确认交叉编译环境设置成功
arm-linux-gcc -v
通过file命令查看可执行文件格式
# file hello
objdump反汇编命令的使用
# objdump -d hello > log
Readelf命令的使用
# readelf -d hello
可以查看hello使用的动态库