第二章搭建Linux交叉编译开发环境CrosscompilingenvironmentCopyright©2003-2007SinoSys.AllRightsReserved双实科技2.1什么是交叉编译什么是交叉编译呢?简单地说,就是在一个平台上生成另一个平台上的可执行代码。这里需要注意的是所谓平台,实际上包含两个概念:体系结构(Architecture)和操作系统(OperatingSystem)。同一个体系结构可以运行不同的操作系统;同一个操作系统也可以在不同的体系结构上运行。Copyright©2003-2007SinoSys.AllRightsReserved双实科技2.2建立交叉编译开发工具链2.2.1编译工具链以下是一个基于RedHatlinux的交叉编译环境的建立过程。整个编译过程包括:1.下载源文件、补丁和建立编译的目录;2.建立内核头文件;3.建立二进制工具(binutils);4.建立初始编译器(bootstrapgcc);5.建立c库(glibc);6.建立全套编译器(fullgcc)。Copyright©2003-2007SinoSys.AllRightsReserved双实科技2.2建立交叉编译开发工具链(1)下载源文件、补丁和建立编译的目录a,下载:linux-2.4.21+rmk2;binutils-2.10.1;gcc-2.95.3;glibc-2.2.3;glibc-linuxthreads-2.2.3b,建目录:/home/xxx/embedded下建立三个子目录build-tools、kernel和toolsc,需要输出环境变量Copyright©2003-2007SinoSys.AllRightsReserved双实科技2.2建立交叉编译开发工具链d,建立编译目录:build-binutils——编译binutils的目录build-boot-gcc——编译gcc启动部分的目录build-glibc——编译glibc的目录build-gcc——编译gcc全部的目录gcc-patch——放gcc的补丁的目录Copyright©2003-2007SinoSys.AllRightsReserved双实科技2.2建立交叉编译开发工具链(2)建立内核头文件a,把内核源代码放入$PRJROOT/kernel目录b,给Linux内核打上补丁c,编译内核生成头文件d,建立正确的链接Copyright©2003-2007SinoSys.AllRightsReserved双实科技2.2建立交叉编译开发工具链(3)建立二进制工具(binutils)a,解压binutils源文件b,然后进入build-binutils目录配置和编译binutils注意:add2line——将要找的地址转成文件和行号,它要使用debug信息。Copyright©2003-2007SinoSys.AllRightsReserved双实科技2.2建立交叉编译开发工具链ar——产生、修改和解开一个存档文件。as——gnu的汇编器。c++filt——C++和java中有一种重载函数,所用的重载函数最后会被编译转化成汇编的标号,c++filt就是实现这种反向的转化,根据标号得到函数名。gasp——gnu汇编器预编译器。Copyright©2003-2007SinoSys.AllRightsReserved双实科技2.2建立交叉编译开发工具链ld——gnu的连接器。nm——列出目标文件的符号和对应的地址。objcopy——将某种格式的目标文件转化成另外格式的目标文件。objdump——显示目标文件的信息。Copyright©2003-2007SinoSys.AllRightsReserved双实科技2.2建立交叉编译开发工具链ranlib——为一个存档文件产生一个索引,并将这个索引存入存档文件中。readelf——显示elf格式的目标文件的信息。size——显示目标文件各个节的大小和目标文件的大小。strings——打印出目标文件中可以打印的字符串,有个默认的长度,为4。strip——剥掉目标文件的所有的符号信息。Copyright©2003-2007SinoSys.AllRightsReserved双实科技2.2建立交叉编译开发工具链(4)建立初始编译器(bootstrapgcc)a,进入build-tools目录,将gcc源代码解压b,然后进入gcc-2.95.3目录给gcc打上补丁c,配置boostrapgcc,后面要用bootstrapgcc来编译glibc库d,编译并安装boot-gccCopyright©2003-2007SinoSys.AllRightsReserved双实科技2.2建立交叉编译开发工具链注意:gcc——gnu的C语言编译器。unprotoize——将ANSIC的源码转化为K&RC的形式,去掉函数原型中的参数类型。cpp——gnu的C的预编译器。gcov——gcc的辅助测试工具,可以用它来分析和优化程序。Copyright©2003-2007SinoSys.AllRightsReserved双实科技2.2建立交叉编译开发工具链(5)建立c库(glibc)a,解压glibc-2.2.3.tar.gz和glibc-linuxthreads-2.2.3.tar.gz源代码b,进入build-glibc目录配置glibcc,编译和安装glibcCopyright©2003-2007SinoSys.AllRightsReserved双实科技2.2建立交叉编译开发工具链注意:然后还要修改libc.so文件,将GROUP(/lib/libc.so.6/lib/libc_nonshared.a)改为:GROUP(libc.so.6libc_nonshared.a)这样连接程序ld就会在libc.so所在的目录查找它需要的库,因为主机/lib目录可能已经装了一个相同名字的库,一个为编译可以在宿主机上运行的程序的库,而不是用于交叉编译的。Copyright©2003-2007SinoSys.AllRightsReserved双实科技2.2建立交叉编译开发工具链(6)建立全套编译器(fullgcc)在建立boot-gcc的时候,我们只支持了C。到这里,我们就要建立全套编译器,来支持C和C++注意:g++——gnu的c++编译器。protoize——与unprotoize相反,将K&RC的源码转化为ANSIC的形式,函数原型中加入参数类型。c++——gnu的c++编译器。Copyright©2003-2007SinoSys.AllRightsReserved双实科技2.2建立交叉编译开发工具链2.2.2下载工具链这里主要介绍一下Denx公司发布的一整套开放源码的嵌入式Linux开发工具链——ELDK(EmbeddedLinuxDevelopmentKit)ELDK可以安装和运行在以下主机环境中:FedoraCore1,2,3RedHatLinux7.3,8.0,9SuSELinux8.x,9.0,9.1,9.2Copyright©2003-2007SinoSys.AllRightsReserved双实科技2.2建立交叉编译开发工具链Debian3.0(Woody)andtesting(Sarge)Ubuntu4.10FreeBSD5.0SuseLinux7.2,7.3Mandrake8.2Slackware8.1beta2GentooLinux1.4_rc2ELDK同时支持ARM、PPC、MIPS等多种处理器。Copyright©2003-2007SinoSys.AllRightsReserved双实科技2.2建立交叉编译开发工具链ELDK包括了一个安装工具和许多RPM包,他们可以安装到用户的交叉编译的主机的硬盘中。ELDK的RPM包可以分为2种:嵌入式Linux开发工具;为目标处理器编译好的工具和元件。其中,第一部分包括执行在开发主机上的交叉编译工具,有GNU交叉编译器GCC、Binutils和GDB等。第二部分是一些已经编译好的、可以在目标开发板上运行的工具和库。这些工具和库可以用来建立一个Linux的Roofs文件系统。Copyright©2003-2007SinoSys.AllRightsReserved双实科技2.2建立交叉编译开发工具链2.2.3验证工具链注意:通过上述两种方式建立的工具链,还需要经过验证方可使用,我们主要通过实际编译一个例子程序来验证。Copyright©2003-2007SinoSys.AllRightsReserved双实科技2.3配置主机服务在嵌入式软件开发过程中,有些主机服务是必要的,同时也会为我们的开发工作带来便利。这里主要介绍四种主机服务:samba、DHCP、TFTP和NFS。Copyright©2003-2007SinoSys.AllRightsReserved双实科技2.3配置主机服务2.3.1配置sambaSamba服务使Linux和Windows之间实现文件共享,方便对文件的编辑。1)修改samba配置文件/etc/samba/smb.conf2)为Samba创建一个单独的口令文件。要根据你的现存/etc/passwd文件来创建3)改变Samba口令文件的权限许可,因此只有根用户才有读写权限Copyright©2003-2007SinoSys.AllRightsReserved双实科技2.3配置主机服务4)要设置每个Samba用户的口令,使用以下命令(把username替换为每个用户的用户名)5)加密口令必须在Samba配置文件中被启用6)在shell提示下键入servicesmbrestart来确定smb服务被启动7)为避免每次启动主机都要手工启动samba服务,使用命令使得samba服务在每次系统启动时都默认执行Copyright©2003-2007SinoSys.AllRightsReserved双实科技2.3配置主机服务2.3.2配置DHCPDHCP是动态主机配置协议。这个协议用于向计算机自动提供IP地址,子网掩码和路由信息。在开发的过程中,目标系统并没有自己的静态IP地址,它是在启动时向DHCP服务器申请,因此需要在主机上配置DHCP服务,以便在目标系统请求IP时,动态为它分配IP地址。DHCP服务的配置文件为/etc/dhcpd.conf,通过修改该文件进行配置。etc/dhcpd.conf通常包括三部分:parameters、declarations、option。Copyright©2003-2007SinoSys.AllRightsReserved双实科技2.3配置主机服务(1)DHCP配置文件中的parameters(参数):表明如何执行任务,是否要执行任务,或将哪些网络配置选项发送给客户(2)DHCP配置文件中的declarations(声明):用来描述网络布局、提供客户的IP地址等(3)DHCP配置文件中的option(选项):用来配置DHCP可选参数,全部用option关键字作为开始Copyright©2003-2007SinoSys.AllRightsReserved双实科技2.3配置主机服务(4)重新启动dhcp服务(5)为避免每次启动主机都要手工启动dhcp服务,使用命令使得dhcp服务在每次系统启动时都默认执行Copyright©2003-2007SinoSys.AllRightsReserved双实科技2.3配置主机服务2.3.3配置TFTP在目标系统的开发过程中,Linux内核是从主机下载到目标系统上解压并运行的,因此主机必须提供这种文件传输服务。Tftp是一种简单的文件传输协议,多用于嵌入系统应用中,因此主机需要配置tftp服务,供下载内核时使用Copyright©2003-2007SinoSys.AllRightsReserved双实科技2.