Linux系统构建工具buildroot手册

hello buildroot

概要

     buildroot 是一个构建嵌入式Linux系统的的框架,它可以简化系统构建流程(相比传统uboot kernel busybox方式)、自动打包等。他和kernel类似,整个编译系统由Makefile脚本和Kconfig配置文件构成的。你可以和编译Linux内核一样,通过buildroot配置,menuconfig修改,编译出一个完整的可以直接烧写到机器上运行的Linux系统软件(包含boot、kernel、rootfs以及rootfs中的各种库和应用程序)。

下载

        1、可以通过官方网站下载  http://buildroot.org/downloads/.

        2、通过git 下载 git clone git://git.buildroot.net/buildroot

        如果国内比较慢,我是用迅雷下载的添加连接下载的,也可以使用gitee加速。我下载的是最新版本buildroot-2021.08-rc2.tar.bz2

构建

        buildroot 推荐使用普通用户构建,以免对系统造成不良影响。

        首先安装必要的工具

        sudo apt install gcc build-essential bison flex gettext tcl sharutils libncurses-dev zlib1g-dev exuberant-ctags g++ texinfo patch vim libtool bc git wget

         指定编译平台,本次以qemu为例

tar -xvf buildroot-2021.08-rc2.tar.bz2

cd buildroot-2021.08-rc2

make qemu_aarch64_virt_defconfig

make  

运行

         经过编译在output/images/下生成可以运行的镜像,

output/images/
├── Image
├── rootfs.ext2
├── rootfs.ext4 -> rootfs.ext2
└── start-qemu.sh

 更人性化的是他们还给了一个脚本start-qemu.sh:

#!/bin/sh
(
BINARIES_DIR="${0%/*}/"
cd ${BINARIES_DIR}

if [ "${1}" = "serial-only" ]; then
    EXTRA_ARGS='-nographic'
else
    EXTRA_ARGS=''
fi

export PATH="/home/lucky/buildroot/buildroot-2021.08-rc2/output/host/bin:${PATH}"
exec qemu-system-aarch64 -M virt -cpu cortex-a53 -nographic -smp 1 -kernel Image -append "rootwait root=/dev/vda console=ttyAMA0" -netdev user,id=eth0 -device virtio-net-device,netdev=eth0 -drive file=rootfs.ext4,if=none,format=raw,id=hd0 -device virtio-blk-device,drive=hd0  ${EXTRA_ARGS}
)

我们运行一下:

./start-qemu.sh

 到此一个buildroot已经运行起来,不纠结细节的同学可以不用往下看了。下面主要介绍一下各个功能模块。

常用模块

工程结构

        buildroot包含一个完整的嵌入式系统构建组件,包括工具链、配置、boot、kernel 和rootfs等,结构如下图所示:

buildroot-2021.08-rc2
├── arch
├── board
├── boot
├── CHANGES
├── Config.in
├── Config.in.legacy
├── configs
├── COPYING
├── DEVELOPERS
├── dl
├── docs
├── fs
├── linux
├── Makefile
├── Makefile.legacy
├── output
├── package
├── README
├── support
├── system
├── toolchain
└── utils
目录含义
arch体系结构相关的配置,
board各种平台使用的一些配置,在构建系统时,board默认的boot和Linux kernel配置文件,以及一些板相关特殊构建流程的脚本,都在该目录下,等待自动构建时调用。
bootboot相关的一些配置
configs
dl编译过程中下载的一些包,第一次下载,后面从这里面取
docs文档目录
fs文件系统相关
linuxkernel相关配置
output

编译输出目录

package应用软件相关的配置
support存放着一些固定的流程脚本,以备构建时调用执行
system存放着文件系统目录的和设备节点的模板
toolchain

存放着各种制作工具链的脚本,buildroot可以选择从0开始,用gcc和linux 内核,glibc、uclibc库等原材料制作一个自己工具链,也可以下载第三方制作好的开源工具

工具链 toolchain

        所谓的工具链(toolchain),包含工具和链两部分含义:

  •  工具:tool ,用来干活的家伙,这里要干的活:生成(可以运行的)程序或库文件而为了达成此目标,内部的执行过程和逻辑主要包含了:
    1. 编译:

      编译的输入(对象)是:程序代码

      编译输出(目标)是:目标文件

      编译所需要的工具是:编译器

      编译器,常见的编译器,即为gcc

    2. 链接

      链接的输入(对象)是:(程序运行时所依赖的,或者某个库所依赖的另外一个)库(文件)

      链接的输出(目标)是:程序的可执行文件,或者是可以被别人调用的完整的库文件

      链接所需要的工具是:链接器

      链接器,即ld

         此处,为了将程序代码,编译成可执行文件,涉及到编译,链接(等其他步骤),要依赖到很多相关的工具,最核心的是编译器gcc,链接器ld。

  • 链:chain,之所以能称为链,你是说明不止一个东西,然后,按照对应的逻辑,串在一起,链在一起而对应的,涉及到的:
  1. 不止一个东西,指的是就是前面所说的那个工具,即:和程序编译链接等相关的gcc,binutils等工具
  2. 按照对应的逻辑,指的就是,按照程序本身编译链接的先后顺序,即:先编译,后链接,再进行后期其他的处理等等,比如用objcopy去操作相应的目标文件等等。

    如此的,将:和程序编译链接等相关的gcc,binutils等工具按照先编译后链接等相关的编译程序的内在逻辑串起来,就成了我们所说的:工具链

     下面我们简单看一下linux 一个应用程序的编译过程

gcc -v -o  test test.c #使用 -v 选型可以看到完整的编译过程

 /usr/lib/gcc/x86_64-linux-gnu/9/cc1 -quiet -v -imultiarch x86_64-linux-gnu test.c -quiet -dumpbase test.c -mtune=generic -march=x86-64 -auxbase test -version -fasynchronous-unwind-tables -fstack-protector-strong -Wformat -Wformat-security -fstack-clash-protection -fcf-protection -o /tmp/cchCtUAT.s 

 as -v --64 -o /tmp/ccr7QQVW.o /tmp/cchCtUAT.s

 /usr/lib/gcc/x86_64-linux-gnu/9/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/9/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/9/lto-wrapper -plugin-opt=-fresolution=/tmp/ccOUOoYU.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o test /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/9/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/9 -L/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/9/../../.. /tmp/ccr7QQVW.o -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/x86_64-linux-gnu/9/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/crtn.o

 根据gcc 输出可以看出来,对于一个简单C程序来说,从源码构建出C程序来讲,主要经过以下三步:

  1. 编译:使用cc1 进行编译产生汇编代码/tmp/cchCtUAT.s 
  2. 汇编:使用as进行汇编,产生目标文件 /tmp/ccr7QQVW.o
  3. 链接:使用collect2 (最终调用ld)进行链接,产生我们最终需要的可执行程序

buildroot工具链 

在我们嵌入式开发过程中有宿主机目标机的角色之分:宿主机是执行编译链接嵌入式软件的计算机;目标机是运行嵌入式软件的硬件平台。例如,如果您的主机系统使用x86,而目标系统使用ARM,那么主机上的常规编译工具链运行在x86上并生成针对x86的代码,而交叉编译工具链运行在x86上并生成针对ARM的代码。

Buildroot为交叉编译工具链提供了两种解决方案:

  • 内部工具链后端(Internal toolchain backend),在配置界面中称为Buildroot工具链(Buildroot toolchain)。
  • 外部工具链后端(External toolchain backend),在配置界面中称为外部工具链(External toolchain)。

使用Toolchain菜单中的Toolchain Type选项可以在这两个解决方案之间进行选择。一旦选择了一个解决方案,就会出现许多配置选项,以下部分将详细介绍这些选项。

Internal toolchain backend:

选择这个代表您要从零开始用原材料软件包自动构造工具链,这个过程比较复杂,如果想深入去看推荐一本书《深度探索Linux操作系统:系统构建和原理解析》--王柏生,介绍的很详细。我这里简单介绍一下buildroot相关的知识。最重要的是以下选项:

  • 更改用于构建工具链的Linux内核头文件的版本。这一项值得作一些解释。在构建交叉编译工具链的过程中,正在构建C库。这个库提供了用户空间应用程序和Linux内核之间的接口。为了知道如何与Linux内核“对话”,C库需要访问Linux内核的头文件(即来自内核的.h文件),它定义了用户空间和内核之间的接口(系统调用、数据结构等)。因为这个接口是向后兼容的,所以用于构建工具链的Linux内核头的版本不需要与您打算在嵌入式系统上运行的Linux内核的版本完全匹配。它们只需要一个与您要运行的Linux内核版本相同或更老的版本即可。如果您使用的内核头比您在嵌入式系统上运行的Linux内核更新,那么C库可能使用的接口不是由您的Linux内核提供的。
  • 更改GCC编译器、binutils和C库的版本
  • 选择一些工具链选项(仅限uClibc):工具链是否应该有RPC支持(主要用于NFS)、宽字符支持、区域支持(用于国际化)、c++支持或线程支持。根据您选择的选项,可见于Buildroot菜单中的用户空间应用程序和库的数量将会改变:许多应用程序和库需要启用某些工具链选项。当需要某个工具链选项来启用这些包时,大多数包都会显示注释。如果需要,您可以通过运行make uClibc -menuconfig来进一步优化uClibc配置。但是请注意,Buildroot中的所有包都是根据默认的uClibc配置进行测试的:如果你通过从uClibc中删除特性而偏离这个配置,一些包可能不再构建。

 External toolchain backend

外部工具链后端允许使用现有的预构建的交叉编译工具链。Buildroot知道许多著名的交叉编译工具链(从Linaro for ARM、Sourcery CodeBench for ARM、x86-64、PowerPC和MIPS),并且能够自动下载它们,或者它可以指向一个定制的工具链,可以下载或在本地安装。

目前,你有三个解决方案来使用外部工具链:

  • 使用预定义的外部工具链概要文件,并让Buildroot下载、提取和安装工具链。Buildroot已经知道一些CodeSourcery和Linaro工具链。只需在Toolchain中从可用的工具链概要文件中选择工具链概要文件。这绝对是最简单的解决方案。
  • 使用一个预定义的外部工具链概要文件,但是不必让Buildroot下载和提取工具链,您可以告诉Buildroot您的工具链已经安装在系统的哪个位置。只需在Toolchain中选择工具链配置文件,取消选择自动下载工具链,并在Toolchain path文本条目中填写交叉编译工具链的路径。
  • 使用完全自定义的外部工具链。这对于使用crosstool-NGBuildroot本身生成的工具链特别有用。为此,在Toolchain列表中选择Custom toolchain解决方案。您需要填充Toolchain pathToolchain prefixExternal toolchain C library选项。然后,你必须告诉Buildroot你的外部工具链支持什么。如果您的外部工具链使用glibc库,您只需告诉您的工具链是否支持c++,以及它是否有内置的RPC支持。如果您的外部工具链使用了uClibc库,那么您必须告诉Buildroot它是否支持RPC、宽字符、区域设置、程序调用、线程和c++。在执行的开始,Buildroot将告诉您所选择的选项是否与工具链配置不匹配。

buildroot编译模块

make

默认情况下,Buildroot不支持顶级并行构建,所以没有必要运行make -jN,要启动构建过程,只需运行:

make

make 命令一般执行如下步骤:

  • 下载源文件
  • 配置、构建和安装交叉编译工具链,或者简单地导入外部工具链;
  • 配置、构建和安装选定的目标包;
  • 如果选择,构建一个内核映像;
  • 如果选择,构建一个引导加载程序映像;
  • 以选定的格式创建根文件系统。

 有用的命令

命令解释
clean 删除编译产生所有文件
distclean删除编译产生所有文件以及配置文件
make source 如果你打算进行离线构建,并且只是想下载你之前在配置器(menuconfig, nconfig, xconfig或gconfig)中选择的所有源代码
make O=/tmp/build所有输出文件将位于/tmp/build目录下。如果O路径不存在,Buildroot将创建它

 

Makefile

Buildroot基本上是一组makefile文件,它们使用正确的选项下载、配置和编译软件。它还包括各种软件包的补丁——主要是交叉编译工具链(gcc、binutils和uClibc)中涉及的补丁。每个目录至少包含2个文件:

  • something.mk: 是一个Makefile,用来下载,配置,编译和安装包什么的。
  • Config.in 是配置工具描述文件的一部分。它描述了包相关的选项。         

主Makefile执行以下步骤(一旦配置完成):

  • 在输出目录中创建所有输出目录:staging, target, build等(默认是output/,可以使用O=指定另一个值)
  • 生成工具链目标。当使用内部工具链时,这意味着生成交叉编译工具链。当使用外部工具链时,这意味着检查外部工具链的特性并将其导入Buildroot环境。
  • 生成targets变量中列出的所有目标。该变量由所有独立组件的makefile填充。生成这些目标将触发用户空间包(库、程序)、内核、引导加载程序的编译,以及根文件系统映像的生成,具体取决于配置。

环境变量

buildroot 内核

buildroot文件系统

 输出

Buildroot输出存储在单个目录output/中。这个目录包含几个子目录:

output/
├── build # 所有组件都是在这里构建的(这包括Buildroot在主机上需要的工具和为目标编译的包)。这个目录 
|         包含每个组件的一个子目录。
├── host #包含为该主机构建的工具和目标工具链的sysroot。前者是为正确执行Buildroot所需的主机编译的        
|          工具的安装,包括交叉编译工具链。后者是类似于根文件系统层次结构的层次结构。它包含所有提供 
|          和安装其他包使用的库的用户空间包的头和库。但是,这个目录并不打算作为目标的根文件系统:它 
|         包含大量开发文件、未剥离的二进制文件和库,这使得它对于嵌入式系统来说太大了。这些开发文件 
|         用为依赖于其他库的目标编译库和应用程序。
├── images # 存储所有映像(内核映像、引导加载程序映像和根文件系统映像)的地方。这些是您需要放到目标系    
|             统中的文件
├── staging  #指向host/内部目标工具链sysroot的符号链接,它的存在是为了向后兼容。
└── target  #几乎包含了目标的完整根文件系统:所有需要的东西都存在,除了/dev/中的设备文件(Buildroot 
            不能创建它们,因为Buildroot不是作为root运行的,也不想作为root运行)。此外,它没有正确 
           的权限(例如busybox二进制文件的setuid)。因此,不应该在目标上使用这个目录。相反,您应该 
          使用images/目录中构建的映像。如果您需要根文件系统的解压映像以用于在NFS上引导,那么使用 
           images/中生成的tarball映像并将其解压为根文件。与staging/相比,target/只包含运行所选目 
          标应用程序所需的文件和库:开发文件(头文件等)不存在,二进制文件被剥离调试信息。

buildroot 文件系统

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值