Use buildroot to create your own cross-compilation toolchain

Use buildroot to create your own cross-compilation toolchain

Keywords: buildroot cross-compilation

Author: chad 
Mail: [email protected]

Development environment: deepin 14.03 + mini2440 (using the original linux2.6.29)

  Once, for a long time, I always had a doubt: why the program I compiled with the at91sam9260 cross-compilation toolchain can only run on the at91sam9260, but not on the mini2440? Conversely, programs compiled with the cross-compilation toolchain for mini2440 will not run on at91? Both mini2440 and at91sam9260 are arm platforms, and they also use linux system. Why can't binary programs be universal?

  This article will answer these questions. We don't recommend reinventing the wheel, but if we don't invent it once, we'll never know how the wheel came about.

  The first step in embedded Linux development is to create a cross-compilation toolchain. For a long time in the past, building a cross-compilation toolchain was a nightmare for embedded developers, because they had to manually Track dependencies between various source packages (and their updates). Until the advent of buildroot changed that fact.

  Buildroot is a command set of Makefiles and patches, which can generate a cross-compilation toolchain and root file system for your target system very simply. The whole creation process is like compiling the Linux kernel.

1. Download buildroot

Download the latest source package directly from the official website: http://buildroot.net/downloads/

2. Install dependent libraries and software packages

The following is an excerpt from the buildroot official website operation instructions :

1. Build tools:

gcc (version 2.95 or any later)
g++ (version 2.95 or any later)
python (version 2.6 or 2.7)

2. dependencies packages:

下面的自己根据需要安装
ncurses5   ;menuconfig 使用
qt4        ;xconfig 使用
glib2, gtk2 and glade2  ;gconfig 使用
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

3. Unzip the buildroot archive

4. Enter the source code directory, make menuconfig configuration

Take a look at the excerpt of the s3c2440 data sheet before matching: 
write picture description here 
Next, a few more important options are briefly explained:

Target Architecture      --->     用于选择目标的架构,我这里选择ARM (little endian)(s3c2440可以运行在小端模式和大端模式,默认是小端模式)
Target Architecture Variant  --->      内核类型(arm920t)
Target ABI (EABI)       --->     目标使用的应用程序二进制接口,其中有两个选择EABI(Embedded ABI)    我们选EABI.OABI(Old ABI)

Build options           --->   主要是一些编译时用到的选项,比如dl的路径,下载代码包使用的路径,同时运行多个编译的上限,是否使能编译器缓冲区等等,这里按照默认就行了.

Toolchain       --->   工具链选项
   Toolchain type (Buildroottoolchain)      ---> 工具链类型,这里我们没使用外部Buildroot,默认 .

    *** Kernel Header Options ***        
    Kernel Headers (Linux 3.18.x kernel headers)  --->  
    C library (glibc)  --->  有uclibc/glibc等选项,此处我选择glibc,后面会解释原因               
    glibc version (2.20)  --->        
    *** Binutils Options ***     
    Binutils Version (binutils 2.24)  --->     
    ()  Additional binutils options         
    *** GCC Options ***                         
    GCC compiler Version (gcc 4.8.x)  --->    
    ()  Additional gcc options                
[*] Enable C++ support                     
[ ] Enable compiler OpenMP support       
[ ] Enable libmudflap support            
[ ] Enable graphite support        
[ ] Build cross gdb for the host        
[ ] Purge unwanted locales             
()  Generate locale data               
[ ] Copy gconv libraries                
[*] Enable MMU support                  
()  Target Optimizations                 
()  Target linker options      
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

5、保存退出,生成.config 文件

6、编译

$make

这里不能使用make-jN,因为Buildroot不支持top-levelparallel make , 反之 , 使用BR2_JLEVEL选项来告诉Buildroot运行编译每一个package使用make -JN.

使用make命令之后会执行下面几个步骤:
     ①下载源文件(所要求的)
     ②配置,编译和安装cross-compiling toolchain(如果使用内部工具链),或者输出一个toolchain(如果一个外部工具链使用)
     ③构建/安装杯选择的目标包
     ④构建内核镜像(如果有选择)
     ⑤构建启动代码镜像(如果有选择)
     ⑥创建根文件系统(如果有选择)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

7、输出文件介绍

输出文件全部在output/目录下:

  • images/ — 存放编译后产生的所有镜像文件( 内核镜像 , 加载引导镜像 和 根文件系统镜像)
  • build/ — 存放所有的组件除了构建交叉编译工具链的组件 , 在这个目录里面每一个功能对应一个子目录存放他们各自的组件.
  • staging/ — 包含一个类似于根文件系统等级层次的层级 . 这个目录包含了 安装的交叉编译工具链 和 所有被选择用于目标板的所有用户空间包.
  • target/ — 包含了根文件系统,但不能用于你的开发板的
  • host/ — 包含了我们需要的交叉编译工具集

我们可以在host/usr/bin/里面看到很多我们需要的二进制文件,如下所示: 
# cd host/usr/bin/ 
write picture description here

8、修改环境变量

在/etc/profile文件里加入:

# vim/etc/profile
添加上:         exportPATH=$PATH:/home/chad/works/binutils/buildroot-2015.02/output/host/usr/bin
保存之后,执行以下命令使其生效:
# source/etc/profile
  • 1
  • 2
  • 3
  • 4

9、测试arm-linux-gcc

打印出版本号说明编译成功: 
write picture description here

10、hello.c测试

编写一个hello.c程序,使用arm-linux-gcc编译并下载到开发板进行测试。 
write picture description here

write picture description here

按照上文的配置,程序运行肯定是正常的。 
但是如果上面选择的是uclibc,duang!程序运行就会出错!

C library (uclibc)  --->  有uclibc/glibc等选项,此处如果选择uclibc
  • 1

如果我们用hexdump 查看hello的二进制文件,会发现如下信息:

#hexdump -C hello
  • 1

write picture description here 
write picture description here

然后我们用同样的方法查看能正确执行的二进制程序的信息,随便打开一个信息如下: 
write picture description here

发现区别没?mini2440默认调用的是glibc库,而不是uclibc库。

需要注意的是,buildroot编译效率很低,一次编译完成后,如果你想修改某些东西,则必须重新全部编译!!也即先make clean 再 make。


如何重新编译软件包?

  After the first complete compilation, if we need to reconfigure the source code package, we cannot make directly in the root directory on buildroot. Buildroot does not know that you have reconfigured the source code, it will only compile the first time The resulting file is packaged again into a root file system image file. However, we can modify the configuration of the source code in the following two ways.

  1. Directly delete the source package. For example, if we want to recompile openssh, then we can directly delete the output/build/openssh-vesion folder, then when you make, it will automatically extract the source package from the dl folder, and re- Install
  2. Taking openssh as an example, if we don't want to recompile and just want to reconfigure, that is, ./configure, 
    we can directly delete .stamp_configured in the output/build/openssh-version directory. 
    If you just want to reinstall, you can delete 
    .stamp_target_install make can remove .stamp_built

Summarize:

Why is the cross-compilation toolchain for mini2440 not compatible with the cross-compilation toolchain for at91sam9260?

Look at the important parameters that we specified in the cross-compilation toolchain we made earlier:

Target Architecture ---> 目标的架构,s3c2440 与 at9260 都是arm,这个相同
Target Architecture Variant  ---> 内核类型(s3c2440[arm920t] 而 at91sam9260[arm926EJ-S],但是配置时选择arm926t),此处不同
Target ABI (EABI)   --->     目标使用的应用程序二进制接口,此处不同
       ①EABI(Embedded ABI)    mini2440的选择。
       ②OABI(Old ABI)         at91sam9260的选择

    Kernel Headers (Linux 3.18.x kernel headers)  --->  此处差别影响不大
    C library (glibc)  --->  都选择的是glibc    
    glibc version (2.20)  --->  版本不一样      
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

So far, I think the reason why the cross-compilation toolchains of the two platforms are not universal should be clear.

—————–2015-05-21

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325766417&siteId=291194637