buildroot的使用简介【转】

本文转载自:http://blog.csdn.net/flfihpv259/article/details/51996204

 

1 buildroot简介

1.1 Buildroot at a glance

根据我的使用经历就是它可以让你从toolchain,boot,kernel到文件系统及各类应用(如qt,gstream,busybox)一站式make,省去了你编译工具和内核版本的不匹配,glibc库不对啦,每次编译都要去改arch cross_compile等N多烦恼.你也不用在去瞎找各种tarball下载了,它都给你提供了官方的下载途径.总之就是省心省力.具体可看官网说明.

1.2下载

buildroot源码

1.3目录说明

anzyelay@ubuntu:buildroot-2016.05$ ls
arch   build    dl    linux   output   support
board  CHANGES   configs  docs  Makefile         package  system    boot   Config.in  COPYING       fs     README   toolchain
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3
  • Makefile,Config.in,arch等就不说了
  • toolchain/ , boot/ , fs/ , Linux
    这几个目录里都是Config.in 和相关的xxx.mk文件. Config.in就是配置文件, xxx.mk呢就是指定相应的源码包位置和下载地址之类的.

  • output/ 
    make后的所有文件都安装在此处,如下:

    anzyelay@ubuntu:buildroot-2016.05$ ls output/
    build  host  images  staging  target
    • 1
    • 2
    • 1
    • 2
    • build:所有源码包解压出来的文件存放地和编译的发生地
    • host:是由各类源码编译后在你主机上运行的工具(build for host)的安装目录,如arm-linux-gcc就是安装在这里. 
      1 编译出来的主机工具在host/usr下, 
      2 根目录所需要的库及一些基本目录就在host/< tuple >/sysroot/或host/usr/< tuple >/sysroot/里 (< tuple >:arm-buildroot-linux-gnueabi),如果是外部toolchain,比如lirano的就在libc里,名字不一样而矣,

    • staging:软链接到host/< tuple >/sysroot/ 就是上面说到的文件系统需要的库等目录,方便查看

    • images:生成的文件系统,内核在此处,

    • target:根文件系统的存放地,但这不能用来nfs mount到开发板,因为buildroot不是root权权运行的,所以现dev/,etc/等一些文件无法创建,所以目录还不完整,要用images/里的rootfs.tar解压出来的根文件目录才能mount.使用如下命令

      sudo tar -C /destination/of/extraction -xf images/rootfs.tar
      • 1
      • 1
  • dl/ 
    所有默认的下载包都在这里,当这里缺少需要的包时就会自动下载,当然本身下载通常都是很慢的,你可以手动找到相关包下载后放到这里就OK了,make时会自动检测这个目录.

  • system/ 
    这里就是根目录的主要骨架了和相关的启动初始化配置,当制作根目录时就是将此处的文件cp到output里去.然后再安装toolchain的动态库和你勾选的package的可执行文件之类的.

  • package/ 
    ▶ all the user space packages (1800+) 
    ▶ busybox/, gcc/, qt5/, etc. 
    ▶ pkg-generic.mk, core package infrastructure 
    ▶ pkg-cmake.mk, pkg-autotools.mk, pkg-perl.mk, etc. 
    Specialized package infrastructures

  • configs/ 
    默认的不同平台的配置文件

  • board/ 
    存放了一些默认开发板的配置补丁之类的

  • support/ 
    ▶ misc utilities (kconfig code, libtool patches, download helpers, 
    and more.)

  • docs/ 
    帮助文档,解压出来是空的,可看在线文档

2 使用

buildroot的编译流程是先从dl/xxx.tar下解压出源码到output/build/xxx,然后它利用本身的配置文件(如果有的话)覆盖output/build/xxx下的配置文件,在开始编译连接完成后安装到output/相应文件夹下.

2.1 平台配置

  • Target options 
    首先你要选配好你的开发目标平台的一些基本项

2.2 Toolchains in Buildroot

Buildroot提供两种方式使用toolchain,一种是非Buildroot提供的交叉编译器(external toolthain),另一种就是Buildroot本身编译生成的Buildroot toolchain.这个可以在make menuconfig里的 Toolchain menu–>Toolchain Type中选择.

2.2.1. external toolthain:

  • Toolchain :

    ( ) Sourcery CodeBench ARM 2014.05 
    ( ) Musl 1.1.12 toolchain 
    (X) Custom toolchain(用户自己定义的交叉工具)
    • 1
    • 2
    • 3
    • 1
    • 2
    • 3

    前面两种是buildroot已知的toolchain,最后一个是用户自己指定的

  • Toolchain origin(工具来源):

    () Toolchain to be downloaded and installed
    (X) Pre-installed toolchain(以安装的)
    • 1
    • 2
    • 1
    • 2
    • 1项:需要下载安装,选中此后,需要你在下一项中填好交叉工具的下载地址–Toolchain URL)
    • 2项:配置好本地的Toolchain path,和Toolchain prefix,以及后面三项gcc version,kernel header series,C library,不知道就默认,按错误提示的修改就行.

    使用它的好处就是不用浪费时间再去编译个toolchain了,但缺点就是如果你的toolchain有问题那就相当麻烦.就好比我从Linaro官网下载下来的toolchain,编译内核没问题,但做文件系统时老是kernel panic,开始我还怀疑我内核有问题,又是用busybox,又是buildroot,内核,文件系统搞了好久,才发现是toolchain的问题.

2.2.2. Buildroot toolchain:

  • custom toolchain vendor name:就是设置arm-xxx-linux-gnueabi-中的xxx
  • Kernel Headers:最好跟你要编译的内核一致,如果提供选项上没有就选Manually specified,然后在linux version项填版本号, 
    看官网说明,这些头文件是libc库编译文件时用来连接内核的,C库用该头文件来构建用户空间与内核的通信接口,重点是这个库接口是向后兼容,也就是说你不知道选哪个就选旧版的吧.选太新的是不能识别旧版的内核通信,但选旧版头文件仍可以和新版内核通信,详细说明如下:

    Change the version of the Linux kernel headers used to build the toolchain. This item deserves a few explanations. In the process of building a cross-compilation toolchain, the C library is being built. This library provides the interface between userspace applications and the Linux kernel. In order to know how to “talk” to the Linux kernel, the C library needs to have access to the Linux kernel headers (i.e. the .h files from the kernel), which define the interface between userspace and the kernel (system calls, data structures, etc.). Since this interface is backward compatible, the version of the Linux kernel headers used to build your toolchain do not need to match exactly the version of the Linux kernel you intend to run on your embedded system. They only need to have a version equal or older to the version of the Linux kernel you intend to run. If you use kernel headers that are more recent than the Linux kernel you run on your embedded system, then the C library might be using interfaces that are not provided by your Linux kernel.

  • Custom kernel headers series:与上面相同

  • C library 
    ( ) uClibc:专为嵌入式简化的C库,小巧精简,但不兼容glibc,是独立的实现的. 
    ( ) glibc:GNU C Library 支持很多种系统平台,功能很全,但是也相对比较臃肿和庞大的C库 
    ( ) musl (experimental)

    这样填好后它会自动去下载相应version的内核源码,如果下载不了,可以自己下载后放到DL目录下就好.

    选择这个的好处就是配置简单,后续build 它里面的文件系统,第三方应用很轻松,不存在兼容性问题.缺点就是费时间,因为你make clean后所有output里的文件都没了,下次编译时又要重新再编译一次toolchain.因此,你可以第一次用它编译出来然后保存到别的地方,再选择external toolchain来就可以了.

2.3 Root filesystem in Buildroot

  • 编译流程图 
    编译流程

  • System configuration

    • /dev management 
      此处提供四种选择 
      1.Static using device table(不能动态生成dev/节点,文件系统有什么就是什么) 
      2.Dynamic using devtmpfs only(在启动时能动态生成,后面就不行了) 
      3.Dynamic using devtmpfs + mdev(嵌入式选择这个,当有新设备时能动态生成或删除节点文件,/etc/mdev.conf它的配置文件) 
      4.Dynamic using devtmpfs + eudev(比mdev要大要耗费资源,但..肯定要好些了) 
      要想能Dynamic using还要内核配置上CONFIG_DEVTMPFS 和 CONFIG_DEVTMPFS_MOUNT.如果是使用buildroot编译内核,它会根所你的选择自动检测这两项.
    • Root FS skeleton:默认就好,或者你自己有现在的文件系统框架
    • Root filesystem overlay directories(如果你要使用自己或厂商提供的文件系统,可以在此填上,它会在制作镜像时复盖本身编译的文件系统)
  • Filesystem images(选择你要生成的镜像类型)

    • [*] tar the root filesystem 
      要做目录版的文件系统,就是用来nfs mount的,就选中此,然后解压出来就是了,其它默认就好,完了就make吧,OK之后在output/image下就是你要的文件系统了,
  • make busybox-menuconfig(可以用于配置busybox,而不使用默认的选项)

2.4 Managing the Linux kernel configuration

  • 在选中编译内核后,指定内核配置文件有两种方式:

    (X) Using an in-tree defconfig file
    ( ) Using a custom (def)config file
    • 1
    • 2
    • 1
    • 2
    1. 第一项是使用内核 arch/< ARCH >/configs里自带的deconfig配置,好处就是无需修改就可使用,选中此项后会出现Defconfig name选项叫你填写配置名,只需要填写name,不用全路径,而且也不要带后面的_defconfig
    2. 第二项是使用自己配置的一个完整的.config或者minimal defconfig,选中此项后,需要指定配置路径Configuration file path是全路径,不是绝对路径;
  • Additional fragments 
    如果上述配置还不够需要添加也额外的配置可以用这个
  • 如何修改配置: 
    1. 使用命令 make linux-menuconfig这样就会弹出你上面选中的配置项的配置界面
    2. 你所作的修改会保存在$(O)/build/linux-< version>/,它们在clean后不会保留下来
    3. 当你指定配置时用的是custom的方式,那可以通过make linux-update-config命令来保存.config,用make linux-update-defconfig来保存minimal defconfig.如果是指定使用内核的配置则不能用此来保存.

2.5 编译

make <要编译的包>-<要做什么> 
要编译的包:toolchain,busybox,linux,uboot等 
要做什么:menuconfig,dirclean,reconfigure,rebuild等 
使用make help查看更多

2.5.1 如何编译一个单独的包

make package-build

2.5.2 如何删除一个单独的包

不支持Removing a package,是因为buildroot没有记录在output中安装的相应信息,和依赖的包.但只要删了output/build下的相应目录,再make时它就会重新解压配置编译了,所以可以使用如下命令来删除相应目录. 
make < package>-dirclean 
eg:make linux-custom-dirclean

2.5.3 如何重新编译

make < package>-reconfigure:更改配置好重新编译使用 
make < package>-rebuild:更改代码文件后重新编译使用

2.5.4 如何查询要使用的包

make external-deps:列出所有要用的源码包.当你不知道要下载哪个包时可以查询等.

3 问题记录

3.1 将buildroot编译出的toolchain移动到本地使用出现arm-linux-gcc.br_real: No such file or directory

anzyelay@ubuntu:/$ cd /usr/local/arm/
anzyelay@ubuntu:arm$ 4.9.3/bin/arm-linux-gcc -v
/usr/local/arm/usr/bin/arm-linux-gcc.br_real: No such file or directory
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

但 arm-linux-gcc.br_real这个文件是有的,看了下,gcc的链接是链接到一个toolchain-wrapper,估计是这个文件处理之后又找到的arm-linux-gcc.br_real,后来仔细一看提示发现目录也不对呀,我只好在4.9.3下加个usr目录,把其它文件都移动到里面,就是保持buildroot里的原样目录,这样就可以了

anzyelay@ubuntu:usr$ bin/arm-linux-gcc -v
Using built-in specs.
COLLECT_GCC=/usr/local/arm/4.9.3/usr/bin/arm-linux-gcc.br_real
COLLECT_LTO_WRAPPER=/usr/local/arm/4.9.3/usr/bin/../libexec/gcc/arm-buildroot-linux-gnueabi/4.9.3/lto-wrapper
Target: arm-buildroot-linux-gnueabi
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

3.2 使用buildroot编译出的toolchain工具能成功编译出的内核及文件系统,但将内核下载无法到开发板无法正常启动

一启动就停在”Uncompressing Linux…done,booting the kernel”,用外部的编译器编译的同一份源码的内核是能正常启动的,所以应该就是内核完全无法执行,并不是以前碰到的无法输出打印信息到console里,但奇怪的是编译出的文件系统居然能正常使用…..对比外部工具链和buildroot的工具链的编译配置信息发现一个疑点:–with-mode=thumb与–with-mode=arm,更改为thumb后,问题依然.在附加选项添加上一些选项后也是一样,有几个一添加就会出错, 还是打算用网上下载的lirano版gcc试试.记得以前这个是可以成功编译运行但编译出的文件系统会kernel panic.这回将平台指令换成thumb再编译次试试.

测试结果是:
测试的内核版本3.6.6,(4.2.16也试过,这里主要以3.6.6说明),linaro的是下载的可执行版,没有自己编译,所以其它项没有变化.
cross-compilegcc版本kernel headerlibc指令集fskernelhello.c编译执行情况
arm-buildroot-gcc 4.9.3 3.6.6 eglibc arm Y N N
arm-buildroot-gcc 4.9.3 3.2.x eglibc arm Y N Y
arm-buildroot-gcc 4.9.3 3.6.6 uClibc arm Y N N
arm-buildroot-gcc 4.9.3 3.2.x uClibc arm Y N Y
arm-buildroot-gcc 4.9.3 3.6.6 eglibc thumb Y N N
arm-buildroot-gcc 4.9.3 3.2.x eglibc thumb Y N Y
arm-linaro-gcc 4.9.4 4.0.0 eglibc thumb N Y N

由上知buildroot自制的arm-buildroot-gcc(无论是arm/thumb,uclibc/glibc,不同的kernel header等)编译的内核都无法启动,但可以编译出可执行的文件系统,同时用它编译出的可执行文件也可以执行(用3.6.6头文件会出现缺少库函数无法编译的现象),如果是arm-linaro-gcc编译出的内核可以启动,但编译出的文件系统出现Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b,用其编译的程序会出现segment fault错误.其它的就没试了.

3.3 修改为无账号密码登录

用buildroot编译的文件系统默认是需要输入账号的,如何开机自动登录shell呢? 
如果你删除账户的话那就无法 登录了,buildroot默认使用的是getty登录的,这个程序好像非要有账户号才能运行。即使我在inittab中给它加了-a user参数也不行,buildroot编译出来的不支持这个参数。那直接改为-bin/sh就行了,如下:

etc/inittab修改部分的内容:

 26 # Put a getty on the serial port
 27 #ttySAC0::respawn:/sbin/getty -L  ttySAC0 115200 vt100 # GENERIC_SERIAL
 28 ::respawn:-/bin/sh
 29 # Stuff to do for the 3-finger salute
 30 #::ctrlaltdel:/sbin/reboot
posted @ 2017-07-03 15:08  请给我倒杯茶  阅读(5050)  评论(0编辑  收藏  举报