`

交叉编译器制作——需要的组件及作用

    博客分类:
  • c
 
阅读更多

交叉编译器制作——需要的组件及作用

在一种计算机环境(称为host machine)中运行的编译程序,能编译出在另外一种环境(称为target machine)下运行的代码,叫做交叉编译。实现这个交叉编译的一系列工具,包括C函数库,内核文件,编译器,链接器,调试器,二进制工具……称为交叉编译工具链
    实际上在进行嵌入式开发时,我们通常都会在主机上(host machine)使用开发板厂商提供的编译器,调试器。比如在windows上装环境调试51,61单片机,在Linux上用arm-gcc写arm开发板的程序……
    搭建交叉编译环境是一个非常繁琐并细致的过程。笔者就已嵌入式Linux交叉编译工具链的搭建为例,介绍下交叉编译工具的创建过程,和原理。

主机(hostmachine),Fedora 9 Linux,  
目标机(target machine),arm,mips,sh,ppc……

一,首先介绍下交叉编译工具链的组成部分。

1,编译器,汇编器。
    编译器是交叉编译工具链中最显眼的部分,因为平常我们与它打交道,写程序,编译成binary,下到开发板上。但是请注意,真正的编译器并不会把程序直接变成二进制文件,而是链接器在做这件事情。

    在Linux中,最常用的编译器就是传说中的gcc了,目前gcc已经到了4.4版本。编译器做的事情是把程序,翻译成目标机的汇编文件(.s),然后调用二进制工具的汇编器(as),变成目标文件(.o)。

    严格的说,汇编器as并不属于编译器gcc,它和链接器ld属于二进制工具(binutils -- binary utilies)。

上一张图供大家理解(gcc.jpg)。

    什么是目标文件(.o)?目标文件本身是一种可链接的二进制文件,目前在System V系列系统中(Linux,Unix)常用的是ELF格式。简单的把.o画一下吧。


2,链接器。
    链接器是把多个目标文件变成二进制文件。这个文件,可以是可执行文件,也可以是一个动态链接库,也可以是一个可重定位的目标文件(更大的.o)。链接成的文件也是ELF格式。

    链接的过程非常复杂,但原理却又简单,后面可以讨论。链接器在Linux中用的是ld,和as一样,在binutils程序包中。

    ELF定义比较复杂,主要是对于链接来说分了很多的section,对于运行来说逻辑上有一些segment。如果大家想了解一下ELF格式,其实是有利于对整个系统的理解和高级调试的。需要时进行讨论。

3,内核文件。
    内核文件是指内核头文件。用途?实际上在编译程序(包括我们编译内核,甚至交叉编译工具链)的时候,通常要使用一些系统调用。内核头文件用于声明这些函数,以便链接器能够找到相应的程序入口。
    Linux中的内核头文件当然是在Linux Kernal 源码包里了,下载Linux Kernel后,即可安装头文件到某目录,供编译器及C库使用。请注意的是,内核头文件和二进制工具没有依赖关系。
    为什么要专门提出这一点?首先,有助于我们对交叉编译工具链各个环境的理解。其次,很多教材都是错的。原因:二进制工具,实际上是根据target machine的ABI接口对程序进行规范和抽象,并不关心到底程序在做什么。ABI=application binary interface,是system V系列系统汇编和硬件关系的接口标准。每个系列的处理器都有自己的ABI接口规范,ABI中定义了一些汇编使用规范和接口,如寄存器的使用,栈的组织,函数调用入口,数据对齐、格式,异常处理接口、信号规范等等等等。

4,C函数库。
     无论是编译内核,还是日常的程序,甚至编译一个C++的编译器,都需要C语言函数库的支持。比如,我malloc一块内存,我要知道怎么malloc,Linux Kernel中不会提供一个内存管理的工具。其次C库是可以更换的,无论是静态链接库还是动态链接库。由于C库的接口标准同意,就可以对库而不是整个系统进行升级。

     在嵌入式系统中,使用的C语言库比较多。最强大,也最huge,最完善的莫过于GNU的glibc了,glibc也是标准的C语言库,目前已经到了version 2.9。另外,由于嵌入式系统的灵活性,不可能将如此大的一个c库移植到一个系统中,就衍生了很多轻量级的c库,如uClibc,newlib。

     请注意,由于编译器是根据C语言库创建出来的,所以编译器是依赖于C库的。比如ARM中的gcc,我们一般看到两种,一种是arm-linux-*,一种是arm-linux-*。区别就在于,arm-linux-*一般是根据glibc创建出来的,只能够和glibc的库使用(你使用glibc 2.8 2.9的动、静态连接库没有关系,而不能使用别的c库),但不能使用,而arm-elf-*一般使用 uClibc或者使用redhat专门为嵌入式系统的开发的C库newlib。

     请注意C库有个C库的头文件需要安装,依赖于内核头文件。


5,调试器(可选)。
     调试器可以看作是补充的工具,当然,前提是你介于牛A和牛C之间。在编程中经常遇到这样那样的问题,有个调试器自然是最方便不过的了。目前支持各种环境的调试器最强的莫过于GDB了,GNU的gcc或许还对于某个平台优化的不好(例如x86环境下gcc编译出来的程序效率就不如intel自家的c++ complier),GDB在嵌入式上强大到一统江湖……

     但调试器并不只包括GDB,还有二进制工具中的objdump,address2line,readelf等。GDB依赖于内核头文件和C库。

    请注意在程序编译时必须加入一些调试信息,才能够使用调试器。常用的调试信息格式有stabs/stabs+, coff/xcoff/xcoff+, dwarf/dwarf+,怎么把这些信息加到程序中可以在gcc里面通过-g选项打开,一般貌似也用不到太深入的……需要用到时候在讨论吧。

二,创建交叉编译工具链。

    创建交叉编译工具链有一些基本步骤。无论是Linux还是其他系统,原理是相通的。可以参考《构建嵌入式操作系统》
    可以参考youbest的CLFS2.0原理分析,CLFS也是一个著名的crosstoolhttp://www.linuxsir.org/bbs/showthread.php?t=267672
    主要步骤是

  • 安装交叉编译内核头文件/安装交叉编译的binutils (不分先后)
  • 安装target machine c库头文件。
  • 通过内核、C头文件和binutils安装gcc的c交叉编译器(bootstrap gcc)
  • 编译交叉编译的c库
  • 通过c库,头文件,编译出gcc的c++编译器。
  • 安装gdb

    对于板子的不同,需要更改的地方是:C库中内存map,kernel header中的各中断,内存映射地址……这些难度较大,都能写一本书了。一般来说抄公版设计,应用标准的C库及kernel header(各平台会以补丁的形式发布)。用到时再讨论吧。

 

分享到:
评论

相关推荐

    交叉编译器的制作与安装

    ### 交叉编译器的制作与安装 #### 交叉编译工具链介绍 在深入了解如何构建基于ARM平台的交叉工具链之前,我们首先需要理解交叉编译的基本概念及其重要性。 **什么是交叉编译?** 交叉编译是在一种平台上编译出能在...

    结论:从Haskell到Rust的交叉编译器,以及parser-haskell

    本文将深入探讨一个独特的项目,即从Haskell到Rust的交叉编译器,并关注其中的关键组件——`parser-haskell`。这个项目的目标是允许开发者利用Haskell的强类型和高级特性来编写代码,然后将其转换为Rust的等价代码,...

    基于ARM9嵌入式Linux引导程序

    这一过程不仅强化了参与者对Linux操作系统的理解和应用,还特别强调了交叉编译器和vivi引导程序在嵌入式系统中的关键作用。 #### 交叉编译器的制作 交叉编译器的配置方法主要包括三种途径:一是直接下载现成的工具...

    编译原理课程设计报告(一个完整的编译器).doc

    本地编译器在与源代码开发相同的平台上生成可执行代码,而交叉编译器则生成可在不同平台运行的代码,对于新硬件平台的软件开发尤为重要。 3. 编译器工作流程 一个典型的编译器工作流程包括五个主要阶段: - 词法...

    嵌入式Linux应用程序开发详解 pdf 第五章

    2. **配置交叉编译器**:按照文档指引进行配置,确保交叉编译器能够正确生成目标平台的代码。 3. **安装交叉编译工具链**:安装完成后,需要将编译器添加到系统路径中,以便于后续使用。 示例:假设使用的是优龙...

    qt交叉编译的配制工具

    在本案例中,我们看到的两个文件——libssh2.dll和QtCrossTool.exe,都是这个过程中的关键组件。 libssh2.dll是一个动态链接库文件,它是libssh2库的Windows版本。Libssh2是一个开源的C语言库,它实现了SSH协议,...

    armlinuxgcc4.4.3_itmop.com.zip

    标题“armlinuxgcc4.4.3_itmop.com.zip”揭示了这是一个与Linux操作系统相关的软件包,特别地,它包含了一个针对ARM架构的交叉编译器——GCC(GNU Compiler Collection)的版本4.4.3。"交叉工具链"指的是在一种环境...

    arm机上移植——vivi源码

    例如,我们可能需要更改CC变量以指定ARM架构的交叉编译器,比如`CC=arm-none-eabi-gcc`。此外,还需要根据目标系统的头文件路径和库文件路径更新INCLUDES和LIBS变量。 Makefile中的目标文件列表也需要调整,以确保...

    台湾人delphi写的股票K线完整源码Demo,简体版,有参考价值

    在编程领域,Delphi作为一款强大的面向对象的集成开发环境(IDE),以其高效的编译器和丰富的组件库深受开发者喜爱。尤其在金融软件开发中,Delphi因其性能优异,被广泛应用于股票交易系统和数据分析工具的开发。...

    atk-dl6y3c-build-uboot相关资料

    它涵盖了从源码级的系统构建,到实际的固件烧录,再到开发环境中的关键工具——交叉编译器的使用,为全面的设备开发提供了必要的资源。开发者可以根据这些资料逐步学习和实践,实现对硬件的深度控制和优化。

    crosstool-0.43 交叉编译环境的构建之教程

    【交叉编译环境的构建——基于crosstool-0.43】 交叉编译环境是一种特殊的工作环境,它允许开发者在一种硬件平台上构建适用于另一种硬件平台的软件。crosstool-0.43 是一个用于创建这些环境的开源工具,特别适合于...

    (第五部分)华清远见《嵌入式实例开发》

    - **gcc**:用于生成交叉编译器,如arm-linux-gcc,这是搭建交叉编译环境的核心。 - **glibc**:提供了标准的C库,使用户程序能够在目标平台上运行。 **3. 实例操作** 以优龙开发板为例,其开发光盘中包含了预配置...

    gcc编译stm32f103+freeROTS代码

    在Windows环境下,开发基于STM32F103的FreeRTOS应用通常需要借助GCC编译器的变种——armgcc,这是一个专门用于ARM架构的交叉编译工具链。 首先,我们需要理解GCC编译器的基本概念。GCC(GNU Compiler Collection)...

    arm-linux-gnueabihf.7z

    在实际开发中,开发者会使用这个工具链将源代码编译成适用于ARM Linux设备的可执行程序,通过设置环境变量(如`CC`、`CXX`等)指向交叉编译器,然后像在本地编译一样使用`make`命令。同时,`gdb`作为调试工具,也...

    空间结构化查询语言——G_SQL.pdf

    WebG IS系统的结构概述是客户端包括Java Applet,服务器端包括空间数据库,GIS服务器组件包括G_SQL编译器和地理信息操作机,以及外部数据转入组件。客户端的Java组件负责与用户交互。使用直观丰富的地图显示形式显示...

    arm-linux-cross-3.4.4.rar

    本文将详细介绍这款名为"arm-linux-cross-3.4.4"的交叉编译器,以及如何利用它来编译应用程序,如u-boot 1.2.0。 首先,让我们理解一下什么是交叉编译。交叉编译是指在一个平台上生成另一个平台上的可执行代码的...

    NTP网络授时系统设计与实现——NTP服务器端授时服务软件设计与实现.pdf

    安装完成后,需要将交叉编译器的路径添加到环境变量PATH中。 2. **编译μCLinux内核**:获取μCLinux源码,将针对SmartARM2200开发板的补丁应用到源码上,然后通过make config、make menuconfig或make xconfig之一...

    TI_Davinci_DM6446开发攻略——开发环境搭建.pdf

    - 在开发环境中使用的软件工具包括EVM的使用指南(例如sprue66f.pdf),以及交叉编译器工具链,如GCC、DSP BIOS、Code Composer Studio(CCS)等。 - 搭建过程会涉及到多个软件包的安装和配置,包括但不限于DVSDK...

    Vxworks培训讲稿

    - **开发环境**:为了辅助软件开发,需要借助一台通用机作为宿主机(Host),它配备了集成开发环境(IDE)——Tornado。该环境可在Windows或UNIX平台上运行,提供了交叉编译器和交叉调试器。 #### 二、宿主机与目标...

Global site tag (gtag.js) - Google Analytics