Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2298920
  • 博文数量: 395
  • 博客积分: 10994
  • 博客等级: 上将
  • 技术积分: 5586
  • 用 户 组: 普通用户
  • 注册时间: 2010-12-17 19:49
文章存档

2014年(1)

2013年(10)

2012年(74)

2011年(303)

2010年(7)

分类: LINUX

2011-07-21 20:27:29

 

黑色经典系列之《嵌入式 Linux 系统开发技术详解——基于 ARM

 

 

5   交叉开发工具链 交叉编译工具链制作.pdf   

 

 

本章目标

 

本章介绍编译生成       GNU 工具链的基本步骤。通过学习本章内容可以使读者理解交叉工

具链的来源,并且体会到生成和维护工具链的复杂性。

 

工具软件的来源

制作交叉编译器

制作交叉调试器

 

 

华清远见<嵌入式 Linux 系统开发班>培训教材

 

5.1    工具链软件

 

Linux 软件从一开始就使用 GNU 的工具链。这些 GNU 的工具和软件都是开放源码的,

可以免费下载源码编译。但是并不能以为任何一个版本拿来都能用,各种软件包存在版本匹

配问题,并且不同版本都有一些补丁。

一套完善的工具链对于嵌入式 Linux 开发非常重要。发行版的 Linux 都会包含一整套工

具链。工具链的维护和升级是 Linux 公司(特别是嵌入式 Linux 公司)非常重要的一项工作。

5.1.1    相关软件工程

GNU 的工具链源码包可以从 GNU 网站 或者镜像下载。这个站点有很

GNU 软件,其中 Linux 使用的工具链软件是:BINTUTILSGCCGLIBC GDB

通过这些软件包,可以生成       gccg++arasld  等编译链接工具,还可以生成    glibc

库和 gdb 调试器。这些编程工具的使用在第 3 章有详细说明。对于交叉开发的工具链来说,

在文件名字上加了一个前缀,用来区别本地的工具链。例如:arm-linux-gcc,除了体系结构

相关的编译选项以外,它的使用方法与 Linux 主机上的 GCC 相同。所以 Linux 编程技术对于

嵌入式 Linux 同样适用。

交叉开发工具链就是为了编译、链接、处理和调试跨平台体系结构的程序代码。在 X86

Linux 主机上,除了编译生成 ARM MIPS PowerPC 等体系结构的程序,还可以为 X86 不同

版本的 Linux 开发程序。例如:为了维护不同版本的 X86 目标机,可以在 Redhat Linux 9

主机上通过交叉编译的方式开发。

下面介绍一下这些软件工程的一些特点。

BINUTILS 是二进制程序处理工具,包括连接器、汇编器等目标程序处理的工具。

GCCGNU  Compiler  Collection)是编译器,不但能够支持 C/C++语言的编译,而且能

够支持 FORTRAN JAVA ADA 等编程语言。不过,一般不需要配置其他语言的选项,也可以

避免编译其他语言功能而导致的错误。对于 C/C++语言的完整支持,需要支持 glibc 库。

GLIBC    是应用程序编程的函数库软件包,可以编译生成静态库和共享库。完整的       GCC

需要支持 glibc

GDB 是调试工具,可以读取可执行程序中的符号表,对程序进行源码调试。

5.1.2    软件版本的匹配

 

1Crosstool

 

Crosstool 软件实际上是一套脚本,用于编译和测试大多数体系结构的各种 GCC glibc

的版本组合。当然,前提是 glibc 能够支持这些体系结构,它还为工具链源码包提供了补丁。

Crosstool 网站上,可以下载到这些编译脚本、补丁和文档。

Crosstool 包含了体系结构和 gccglibc 各种组合配置的最小补丁。Crosstool 测试支持范

围如表 5.1 所示。


 

5.1


crosstool 测试支持范围

 

华清远见<嵌入式 Linux 系统开发班>培训教材


 


 

 

处理器体系结构

 

gcc 版本

glibc 版本


《嵌入式 Linux 系统开发技术详解——基于 ARM—— 5 章、交叉开发工具链

 

alpha, arm, i686, ia64, mips, powerpc, powerpc64,  

sh4, sparc, sparc64, s390, x86_64

gcc-2.95.3 ... gcc-4.0.0

glibc-2.1.3 ... glibc-2.3.5


 

crosstool 的新版本会不断扩大测试范围。不妨下载 crosstool-0.38 版本,看看软件中大堆

的脚本和补丁。

$ wget  -c 

$ tar –zxvf crosstool-0.38.tar.gz

$ cd crosstool-0.38

顶层目录下有很多*.sh 脚本和*.dat 配置文件,这是对于各种体系结构和工具版本进行编译测

试的脚本。例如:all.shdemo-arm.sharm.datgcc-4.1-20050709-glibc-2.3.2-hdrs-2.6.11.2.dat 等。

因为文件确实太多,我们就不一一分析这些脚本了,只把几个目录归纳说明,如表 5.2 所列。


 

5.2

   

buildlogs

contrib.

doc

patches

summaries


crosstool 目录说明

   

编译各种各样版本的日志文件

为社区贡献的补丁

开发使用文档,初次接触的时候可以看一看

各种版本工具的补丁,包含 binutilsgccglibc 各种版本的补丁

几种体系结构的测试结果总结


 

 

Crosstool 的维护者是 Dan Kegel,可以到

 

2LFSLinux From Scratch

 

顾名思义,LFS 就是要指导人们从头开始制作 Linux 系统。它提供详细的操作步骤,从

源代码开始,一步一步地编译出自己的 Linux 系统。

LFS 最大的优点是可以按照自己的喜好和需要定制自己的系统。它可以帮助人们了解

Linux 系统从头到脚到底是怎么工作的,打造一个 LFS 系统的过程,把 Linux 内部各个部分

如何协调工作以及互相的依赖关系都展示出来。

LFS 2 个优点是可以从更大的程度上控制开发者自己的系统,而不依赖于别人打造的

工具。开发者成为了 Linux 系统每个部分的操纵者,比如目录的分配和起动脚本,开发者还

可以了解每一个程序是做什么的,装在哪里,如何安装。

LFS 3 个优点是你可以建立一个很小的 Linux 系统。在安装一般的 Linux 发行版的时

候,最后需要较大的硬盘空间,其中安装了一些可能并不需要的程序。可以建立一个小体积

的嵌入式 LFS 系统,成功地把一个系统缩减到了 8M,并且可以支持 Apache 网络服务器。

一步的简化可以把体积压缩到 5M 以下。

LFS 4 个优点是系统安全性。由于整个系统都是自己定制的,可以在编译系统源码的

时候加进任何一个想要的安全补丁,就不用去等别人打过补丁编译好的二进制包了。

这样的优点举不胜举,这只是其中比较突出的特点。随着 LFS 经验逐渐增加,你会在自

己身上发现知识所带来的力量。

 

华清远见<嵌入式 Linux 系统开发班>培训教材


 


 

华清远见——嵌入式培训专家   

 

LFS 工程又分成几个项目,每个项目的内容如表 5.3 所示。其中 LFS 是最基本的文档,

其他项目的文档或者软件是进一步开发的工具。对于嵌入式 Linux 系统开发来说,LFS CLFS

都是很好的文档。


 

5.3


 

 

   


LFS 文档项目


 

 

   


 

LFSLinux From Scratch

BLFSBeyond Linux From Scratch


最主要的文档,它是其他项目的基础

扩展根据 LFS 制作的系统功能


 

ALFSAutomated Linux From Scratch   提供 LFS 等自动管理和编译的工具


 

CLFSCross Linux From Scratch


提供各种体系结构的交叉编译方法


 

HLFSHardened Linux From Scratch     关注系统的安全性


 

Hints

LiveCD

Patches


提高系统性能的说明文档,LFS 或者 BLFS 没有包含的部分

LFS 开发主机光盘和修复盘

构建 LFS 主要的补丁


 

 

最新版本的 LFS 文档可以从 LFS 站点 下载。

LFS 本文档列出了构建 LFS 需要的所有软件包索引。每个软件包都列出了软件包的主页、

使用手册和相关资料的链接地址。LFS 书包含了构建 LFS 的所有东西,有充足的信息,并且

还有一些培训资料。因此,可以自己解决使用过程中的问题。

这里是开始理解曾经安装过的软件的好地方,但是要自己动手编译这个系统。这个自己

动手构建的 Linux 系统是在 X86 的平台上的。对于嵌入式 Linux 系统开发,可以重点学习一

些工具软件和系统软件包。

CLFSCross Linux From Scratch)告诉读者如何制作一个交叉编译器以及必需的工具。

基于各种体系结构构建一个基本的系统。例如:可以在 X86 系统上制作 Sparc 工具链,并且

利用这个工具链从源码编译 Linux 系统。

LFS 文档由 Matthew Burgess 编写维护,其他的项目有更多的人参与。

 

3.常用版本

 

BinutilsGCC glibc 的版本匹配是个大麻烦。应该说,越新的版本功能越强大,但是

最新版本有可能存在 BUG,这就需要不断地测试修正。

对于       GCC       的版本,2.95.x     曾经统治了    Linux  2.4     内核时代,它表现得极为稳定。现在

GCC2.95.3 版本已经过时了,Linux 2.6 内核需要更高的工具链版本支持。Linux 2.6 内核最好

使用 GCC 3.3 以上版本。

对于 glibc 版本,还要跟 Linux 内核的版本号匹配。在编译 glibc 时,要用到 Linux 内核

头文件,在内核源码的 include 目录下。如果发现有变量没有定义而导致编译失败,就改变内

核版本号。如果没有完全的把握保证内核修改完全了,就不要动内核,而应该把 Linux 内核

的版本号降低或升高,以适应 glibc 版本。如果选择的 glibc 的版本号低于 2.2,还要下载一个

glibc-crypt 的软件包,例如 glibc-crypt-2.1.tar.gz。解压到 glibc 源码树中。

 

华清远见<嵌入式 Linux 系统开发班>培训教材


 


 

《嵌入式 Linux 系统开发技术详解——基于 ARM—— 5 章、交叉开发工具链

 

对于 binutils 版本,可以尽量使用新的版本,很多工具是辅助 GCC 编译的功能,问题相

对较少。

2.4 内核和 2.6 内核的工具链版本的基本组合见表 5.4,这些是在 ARM 平台上测试过的。

新的处理器或者体系结构都要求使用更高的版本才能够支持。


 

5.4

 

 

binutils

gcc

glibc


 

 

工具链版本


ARMV4T 平台工具链常用版本

Linux 2.4.x

2.14

2.95.3

2.2.5


 

 

 

 

2.14

3.3.2

2.2.5


 

 

Linux 2.6.x


 

glibc-threads

gdb

 

5.1.3    工具链制作流程


2.2.5

5.3


2.2.5

6.0


 

由于工具链是几个软件包组合编译生成的,所以每个软件包的编译并不是独立的,相互

存在依赖关系。

一个关键的问题是完整的 GCC 编译器是依赖于 glibc 的,而 glibc 需要对应体系结构的

GCC 来编译。这怎么解决呢?先编译一个辅助的 GCC 编译器(Bootstrap compiler),用来编

glibc,然后再重新编译完整的 GCC 编译器。

5.1 是编译工具链的流程图。可以把这个过程划分为 5 个步骤。


 

 

binutils源码

 

 

 

 

 

 

 

 

 

 

 

gcc源码


 

 

本地编译

 

 

 

 

 

 

 

 

 

 

 

本地编译


 

 

binutils工具

 

 

 

 

内核源码       glibc源码

 

 

 

 

 

辅助编译器


 

 

 

 

 

 

 

 

 

 

 

 

 

 

glibc


 

 

 

 

 

 

 

 

 

 

完整的 GCC

编译器

 

 

 

 

 

 

完整的gcc


 

 

 

 

5.1    交叉工具链编译流程图


本地编译


译器


 

    做好准备工作。下载工具源码包和补丁,准备内核头文件,创建工作目录等。

    编译 binutils。这个软件包的编译一般很顺利,不会出现什么问题。

 

 

华清远见<嵌入式 Linux 系统开发班>培训教材


 


 

华清远见——嵌入式培训专家   

 

    编译辅助编译器。这一步使用简化配置,编译通常也很顺利。

    编译 glibc 库。这里要使用交叉编译工具链,例如:arm-linux-gcc 等。

    编译生成完整的 GCC 编译器。重新配置 GCC 功能,使其支持 CC++等语言。

注意在配置编译之前,首先要查看所有补丁,把需要的补丁打进去。有的补丁可以解决

编译过程的语法错误,有的补丁专门修正对某个体系结构的支持,有时还要手工地修改一些

文件内容。其中,后两步编译过程最麻烦,编译一般会出现一些错误。

编译 binutilsgccglibc 是最基本的工具链。如果要调试程序,还离不开调试器 gdb。相

对来说,gdb 的编译很简单,它也应该作为工具链配套提供。最后还要编译安装交叉调试器。

本章的内容着重描述制作过程,而且举例说明的版本已经顺利编译通过。但是在使用过

程中,很有可能发现工具链在某个方面存在问题,甚至严重的    BUG,这就需要不断地修正

BUG,它和 Linux 内核一样是不断发展提高的。

 

 

5.2    制作交叉编译器

 

 

5.2.1    准备编译环境

我们来自己动手编译这套交叉开发工具链。选择 GCC-3.3.2 的版本,在 ARM 体系结构

平台上,这个版本既能支持 Linux 2.4 内核开发,又能够支持 Linux 2.6 内核开发。

首先准备编译环境。创建一个工作目录~/crosstool,把下载的源码包放到~/crosstool/source

目录下。

接下来下载相关软件包。这些软件包从 GNU 或者 FSF 官方站点上都可以下载,也可以

从其他嵌入式 Linux 网站下载。例如:ARM Linux 官方站点就提供 binutilsgcc glibc 的源

代码包,但是一般没有包含 gdb 的软件包。

这些软件包都很大,可以考虑使用下载工具。Linux 下的 wget 就很好,可以支持 FTP

HTTP,还支持断点续传。下载命令如下。

 

$ wget  -c 

$ wget  -c 

$ wget  -c 

$ wget  -c 

$ wget  -c 

 

不要忘了找找工具链的补丁。最好下载最新版本的 crosstool 软件包,从中可以找到一些

有用的东西。对于编译的语法错误,已经有相应的补丁修正。当然,我们也可以手工修改。

还要准备内核头文件目录。从内核源码中把 include 目录复制过来。

准备好工作区,创建如下目录。

 

~/crosstool/source

~/crosstool/buildlogs

 

华清远见<嵌入式 Linux 系统开发班>培训教材


 

《嵌入式 Linux 系统开发技术详解——基于 ARM—— 5 章、交叉开发工具链

 

~/crosstool/patches

~/crosstool/linux-2.6.x

~/crosstool/xxxxxx/build-arm-linux

 

xxxxxx 代表 binutilsglibcgccgdb 的源代码目录。在这些目录下创建 build-arm-linux

目录,作为临时工作目录。配置编译过程生成       Makefile、目标文件、临时文件等,都存放在

build-arm-linux       目录下。这样所有编译的内容都在独立的一个目录下,甚至可以为多种体系

结构建立各自的编译目录。

编译的过程可能会出错,导致编译过程无法继续进行。详细分析出错信息,有助于解决

源码中的语法错误。

那么如何保存配置编译过程的信息?这些信息量很大,都可能超出    Shell       向上翻滚查看

的范围。最好是把编译过程的信息保存成日志文件,方便后面的分析。

举例说明保存编译信息的行命令,它把 make 过程打印的所有信息都保存在 xxx.log 中。

$ make    2>&1 | tee xxx.log

 

这条命令是编译并保存打印信息。在 Linux Shell 的设备定义中,“0”表示标准输入,“1”

表示标准输出,“2”表示标准出错信息输出。2>&1 表示把 2 设备的信息重定向到 1 设备;“|”

是管道符号,把标准输出的信息直接传递给后面的命令;tee 是创建文件并保存信息的工具;

xxx.log 是文件名。

这种管道的用法在 Linux Shell 命令中使用非常普遍。下面的编译过程中都可以使用这个

方法,生成日志文件,保存到 buildlogs 目录下。不过为了看起来简洁,下面的操作步骤省略

了这一项。

 

5.2.2    编译 binutils

 

按照下列步骤编译 binutils

$ tar -jxf ./source/binutils-2.14.tar.bz2

$ cd binutils-2.14

$ mkdir build-arm-linux

$ cd build-arm-linux

$ ../configure --target=arm-linux --prefix=/usr/local/arm/3.3.2

$ make

$ make install

解压源码包,并在 binutils-2.14 源码目录中创建 build-arm-linux 目录,作为配置编译工作

目录。

--target 指定交叉工具的目标板体系结构,所有运行在主机上的交叉工具都要配置这个选项。

--prefix 指定路径前缀,编译完成以后,将安装到这个目录下。使用交叉工具链也是与路

径有关系的。

编译过程简单顺利,编译出来的文件或者工具全部安装到/usr/local/arm/3.3.2/目录下。

我们需要的开发工具都在 bin/目录下。这时查看一下 bin 目录下的文件,可以得到下列

 

华清远见<嵌入式 Linux 系统开发班>培训教材


 

 

交叉开发工具。


华清远见——嵌入式培训专家   


 

 

$ ls /usr/local/arm/3.3.2/bin

arm-linux-addr2line

arm-linux-ar

arm-linux-as

arm-linux-c++filt

arm-linux-ld

arm-linux-nm

arm-linux-objcopy

arm-linux-objdump

arm-linux-ranlib

arm-linux-readelf

arm-linux-size

arm-linux-strings

arm-linux-strip

 

这些 GNU 开发工具是都带 arm-linux 前缀。这些工具的用法跟主机本地的工具是相同

的,只是处理的二进制程序体系结构不同。在开发主机上,如果是为目标板平台编译可执行

程序,一定要用交叉开发工具。

记住把新生成的工具添加到环境变量 PATH 中,可以在 Linux 启动脚本添加:

export PATH=$PATH:/usr/local/arm/3.3.2/bin

 

5.2.3    编译 GCC 的辅助编译器

 

按照下列步骤编译辅助编译器。

1)解压源码包

$ tar -jxf ./source/gcc-3.3.2-tar.bz2

$ cd gcc-3.3.2

2)配置 t-linux 文件

因为现在还没有 glibc 的支持,所以需要配置一些简单选项。对于 arm-linux 工具,可以

修改 gcc/config/arm/t-linux 配置文件。

编辑 t-linux,在文件末尾添加如下 2 行。

#  gcc/config/arm/t-linux

……

           TARGET_LIBGCC2_CFLAGS += -Dinhibit_libc -D__gthr_posix_h

           T_CFLAGS = -Dinhibit_libc -D__gthr_posix_h

 

-Dinhibit_libc 选项意思是禁止使用 libc,因为现在还没有为目标板编译出 glibc 库。

3)配置

 

华清远见<嵌入式 Linux 系统开发班>培训教材


 


 

《嵌入式 Linux 系统开发技术详解——基于 ARM—— 5 章、交叉开发工具链

 

$ mkdir build-arm-linux

$ cd build-arm-linux

$ ../configure --target=arm-linux \

       --prefix=/usr/local/arm/3.3.2 \

       --with-headers=~/crosstool/linux-2.6.x/include \

       --disable-shared --disable-threads --enable-languages="c"

--target 指定交叉工具的目标板体系结构是 arm-linux

--prefix 指定安装路径为/usr/local/arm/3.3.2

--with-headers 指定内核头文件所在路径为~/crosstool/linux-2.6.x/include

--disable-shared 选项指定不使用共享库,这样就不依赖于 glibc 了。

--disable-threads 选项指定不使用线程,也就不使用线程库了。

--enable-languages 指定仅支持 C 语言。

4)编译

$ make

这个编译过程会比较顺利,但是要花的时间稍微长一些。如果编译出错,可能是由于

t-linux 配置的原因。可以从网上再搜索一些别人的例子,比较一下。

5)安装

$ make install

生成的文件也安装到/usr/local/arm/3.3.2 目录下。主要是在 bin/目录下添加 arm-linux-gcc

工具。不过现在是辅助的编译器,编译 glibc 的时候要使用。

5.2.4    编译生成 glibc

按照下列步骤编译 glibc

1)解压源码包

$ tar xvzf ~/crosstool/source/glibc-2.2.5.tar.gz

$ cd glibc-2.2.5

$ tar xvzf ~/crosstool/source/glibc-linuxthreads-2.2.5.tar.gz

 

2)修正 BUG

glibc 的源码中有一些 BUG 需要修正,否则编译过程肯定会频频出错。可以通过各种方

式来修改,例如:使用脚本语言、补丁工具或者编辑器 vim

下面说明一下要修改的文件以及修改的内容,“+”号表示添加这一行,“−”号表示删除

这一行。

sysdeps/unix/sysv/linux/configure:参照 i386 的选项,在 i386 上面添加 arm 的选项。

+  arm*)

+    libc_cv_gcc_unwind_find_fde=yes

+    arch_minimum_kernel=2.0.10

 

华清远见<嵌入式 Linux 系统开发班>培训教材


 

 

+    ;;

   i386*)


华清远见——嵌入式培训专家   


 

     libc_cv_gcc_unwind_find_fde=yes

     arch_minimum_kernel=2.0.10

 

sysdeps/unix/sysv/linux/arm/errlist.c:删除 2 weak_alias(),添加 1 strong_alias()

-weak_alias (__old_sys_nerr, _old_sys_nerr)

 compat_symbol (libc, __old_sys_nerr, _sys_nerr, GLIBC_2_0);

 compat_symbol (libc, _old_sys_nerr, sys_nerr, GLIBC_2_0);

-weak_alias (__old_sys_errlist, _old_sys_errlist);

+strong_alias (__old_sys_errlist, _old_sys_errlist);

 compat_symbol (libc, __old_sys_errlist, _sys_errlist, GLIBC_2_0);

 compat_symbol (libc, _old_sys_errlist, sys_errlist, GLIBC_2_0);

 #endif

 

stdio-common/sprintf.csprintf()函数添加变参。

int

-sprintf (s, format)

-       char *s;

-       const char *format;

+sprintf (char *s, const char *format, ...)

 {

   va_list arg;

   int done;

 

stdio-common/sscanf.csscanf()函数添加变参。

int

−sscanf (s, format)

      const char *s;

      const char *format;

+sscanf (const char *s, const char *format, ...)

 {

   va_list arg;

   int done;

sysdeps/unix/sysv/linux/arm/sysdep.h:从列表中删除“a1”

asm volatile ("swi  %1  @ syscall " #name  \


 

                  : "=r" (_a1)


\


 

                  : "i" (SYS_ify(name)) ASM_ARGS_##nr    \

 

 

华清远见<嵌入式 Linux 系统开发班>培训教材


 


 

 


《嵌入式 Linux 系统开发技术详解——基于 ARM—— 5 章、交叉开发工具链

 

    : "a1", "memory");          \


 

+   


    : "memory");


\


 

          _sys_result = _a1; 

       } 


\

\


 

       if (_sys_result >= (unsigned int) -4095)          \

 

sysdeps/arm/dl-machine.h:在宏定义的汇编语句每一行末尾添加“\n\”,涉及的汇编语句

很多,要全部加上。这里只以 CALL_ROUTINE 宏定义举例说明,另外还要修改 RTLD_START

ELF_MACHINE_RUNTIME_TRAMPOLINE 两个宏定义中的汇编语句。

    and then redirect to the address it returns.  */

    // macro for handling PIC situation...

 #ifdef PIC

−#define CALL_ROUTINE(x) " ldr sl,0f

    add  sl, pc, sl

−1:   ldr  r2, 2f

    mov  lr, pc

    add  pc, sl, r2

    b    3f

−0:   .word_GLOBAL_OFFSET_TABLE_ - 1b - 4

−2:   .word " #x "(GOTOFF)

+#define CALL_ROUTINE(x) "\

+   ldr sl,0f\n\

+   add       sl, pc, sl\n\

+1:  ldr r2, 2f\n\

+   mov lr, pc\n\

+   add pc, sl, r2\n\

+   b          3f\n\

+0:  .word  _GLOBAL_OFFSET_TABLE_ - 1b - 4\n\

+2:  .word " #x "(GOTOFF)\n\

 3: "

 #else

 #define CALL_ROUTINE(x) " bl " #x

 

sysdeps/unix/sysv/linux/arm/ioperm.c:把 BUS_ISA 替换成 CTL_BUS_ISA

 

@@ -100,8 +106,8 @@

 {

   char systype[256];

   int i, n;

−static int iobase_name[] = { CTL_BUS, BUS_ISA, BUS_ISA_PORT_BASE };

 

华清远见<嵌入式 Linux 系统开发班>培训教材


 


 

华清远见——嵌入式培训专家   

 

  static int ioshift_name[] = { CTL_BUS, BUS_ISA, BUS_ISA_PORT_SHIFT };

+  static int iobase_name[] = { CTL_BUS, CTL_BUS_ISA, BUS_ISA_PORT_BASE };

+  static int ioshift_name[] = { CTL_BUS, CTL_BUS_ISA, BUS_ISA_PORT_SHIFT };

 

config.make.in:把"slibdir=@...@"替换成"slibdir=@libdir@"

最后,有些程序的函数参数“_thread”名称都替换成“_thr”。相关文件如下。

linuxthreads/sysdeps/pthread/pthread.h

linuxthreads/internals.h

linuxthreads/sysdeps/unix/sysv/linux/bits/sigthread.h

3)配置

 

$ mkdir build-arm-linux

$ cd build-arm-linux

$ CC=arm-linux-gcc \

AS=arm-linux-as \

LD=arm-linux-ld \

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

       --with-headers=~/crosstool/linux-2.6.x/include \

       --enable-add-ons=linuxthreads --enable-shared \

       --prefix=/usr/local/arm/3.3.2/arm-linux

 

编译 glibc 时,要使用交叉编译工具,因此定义环境变量 CC AS LD 为交叉工具链。

--host 指定目标板的体系结构。

--with-headers 指定内核头文件路径为~/crosstool/linux-2.6.x/include

--enable-add-ons=linuxthread 选项支持线程库。

--enable-shared 选项支持共享库。

--prefix 指定的是工具链目标板相关文件的目录:安装目录下的 arm-linux 目录。

4)编译

$ make

 

如果编译过程出错,会大大影响编译速度。因此在修改       BUG       的时候要彻底,否则要花

费更长的时间。

5)安装

$ make install

 

结果在/usr/local/arm/3.3.2/arm-linux 目录下的 lib 等目录中,安装了 glibc 共享库等文件。

5.2.5    编译生成完整的 GCC 编译器

返回到 gcc-3.3.2 的源码目录下,按照下列步骤编译完整的 gcc 编译器。

1)修改 t-linux

 

 

华清远见<嵌入式 Linux 系统开发班>培训教材


 

《嵌入式 Linux 系统开发技术详解——基于 ARM—— 5 章、交叉开发工具链

 

$ cd gcc-3.3.2

$ vi gcc/config/arm/t-linux

 

这里再修改 t-linux,把添加的 2 -Dinhibit_libc 去掉。不能再禁止使用 libc,这里重新

编译支持 libc 的完整的 GCC 编译器。

2)清除临时文件

$ cd gcc-3.3.2/build-arm-linux/

$ make distclean

$ rm -rf ./*

 

把辅助编译器的配置清除掉,最后剩余的文件可以手工删除。

3)配置

    $ ../configure --target=arm-linux \

             --prefix=/usr/local/arm/3.3.2 \

             --with-headers=~/crosstool/linux-2.6.x/include \

             --enable-threads=pthreads \

             --enable-shared \

             --enable-static \

             --enable-languages="c,c++"

 

--target 指定交叉工具的目标板体系结构是 arm-Linux

--prefix 指定安装路径为/usr/local/arm/3.3.2

--with-headers 指定内核头文件所在路径为~/crosstool/linux-2.6.x/include

--enable-threads 选项指定使用线程库。

--enable-shared 选项指定使用共享库。

--enable-languages 指定支持 C C++语言。如果这一项不设置,会把 Java 等语言的支持

也编译进来,那么可能会由于编译其他不需要的功能而出现错误,不能顺利编译通过。

4)编译

$ make

 

这一次编译的条件多一些,极有可能出现错误,一定细心配置。编译时间也比前面

的过程长。

5)安装

$ make install

 

编译的结果是得到完整的编译器 arm-linux-gcc arm-linux-g++。到现在为止,完全可以

使用这一套工具链进行交叉编译了。

 

 

 

 

 

华清远见<嵌入式 Linux 系统开发班>培训教材


 

华清远见——嵌入式培训专家   

 

5.3    制作交叉调试器

 

 

5.3.1    编译交叉调试器

对于交叉调试器,并不是工具链必需的工具。但是它是与工具链配套使用的,GDB 的调

试能力和 BUG 的修正也因为版本的不同而不同。这里仅说明一下基本的编译过程。

按照下列步骤编译交叉调试器。

1)解压源码包

$ tar -zxvf ./source/gdb-6.0-tar.gz

$ cd gdb-6.0

 

2)配置

$ mkdir build-arm-linux

$ cd build-arm-linux

$ ../configure --target=arm-linux --prefix=/usr/local/arm/3.3.2

 

配置也很简单,只需要配置--target --prefix,指定目标板体系结构和安装路径即可。

3)编译

$ make

 

耐心等待,一般不会出错。

4)安装

$ make install

 

编译结果是在/usr/local/arm/3.3.2/bin 目录下得到 arm-linux-gdb 工具。

5.3.2    编译 gdbserver

 

根据第 4 章的交叉调试的例子,目标板还需要 gdbserver 工具为目标板交叉编译 gdbserver

Gdbserver 的源码在 gdb 源码树的 gdb/gdbserver 目录下。按照下列步骤配置编译。

$ cd gdb-6.0

$ cd gdb/gdbserver

$ chmod u+x configure

$ CC=arm-linux-gcc \

./configure --host=arm-linux

$ make

 

使用 arm-linux-gcc 交叉编译,配置--host arm-linux

编译结果生成 gdbserver gdbreplay,这是目标板体系结构的可执行程序,复制到目标

机文件系统中。

 

华清远见<嵌入式 Linux 系统开发班>培训教材

 

阅读(1801) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~