根据我的使用经历就是它可以让你从toolchain,boot,kernel到文件系统及各类应用(如qt,gstream,busybox)一站式make,省去了你编译工具和内核版本的不匹配,glibc库不对啦,每次编译都要去改arch cross_compile等N多烦恼.你也不用在去瞎找各种tarball下载了,它都给你提供了官方的下载途径.总之就是省心省力.具体可看官网说明.
buildroot源码
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
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
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
```
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/
帮助文档,解压出来是空的,可看在线文档
buildroot的编译流程是先从dl/xxx.tar下解压出源码到output/build/xxx,然后它利用本身的配置文件(如果有的话)覆盖output/build/xxx下的配置文件,在开始编译连接完成后安装到output/相应文件夹下.
Buildroot提供两种方式使用toolchain,一种是非Buildroot提供的交叉编译器(external toolthain),另一种就是Buildroot本身编译生成的Buildroot toolchain.这个可以在make menuconfig里的 Toolchain menu–>Toolchain Type中选择.
Toolchain :
( ) Sourcery CodeBench ARM 2014.05
( ) Musl 1.1.12 toolchain
(X) Custom toolchain(用户自己定义的交叉工具)
前面两种是buildroot已知的toolchain,最后一个是用户自己指定的
Toolchain origin(工具来源):
() Toolchain to be downloaded and installed
(X) Pre-installed toolchain(以安装的)
1项:需要下载安装,选中此后,需要你在下一项中填好交叉工具的下载地址–Toolchain URL)
2项:配置好本地的Toolchain path,和Toolchain prefix,以及后面三项gcc version,kernel header series,C library,不知道就默认,按错误提示的修改就行.
使用它的好处就是不用浪费时间再去编译个toolchain了,但缺点就是如果你的toolchain有问题那就相当麻烦.就好比我从Linaro官网下载下来的toolchain,编译内核没问题,但做文件系统时老是kernel panic,开始我还怀疑我内核有问题,又是用busybox,又是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来就可以了.
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,而不使用默认的选项)
在选中编译内核后,指定内核配置文件有两种方式:
(X) Using an in-tree defconfig file
( ) Using a custom (def)config file
Defconfig name
选项叫你填写配置名,只需要填写name,不用全路径,而且也不要带后面的_defconfig;Configuration file path
是全路径,不是绝对路径;make linux-menuconfig
这样就会弹出你上面选中的配置项的配置界面make linux-update-config
命令来保存.config,用make linux-update-defconfig来保存minimal defconfig.如果是指定使用内核的配置则不能用此来保存.make <要编译的包>-<要做什么>
要编译的包:toolchain,busybox,linux,uboot等
要做什么:menuconfig,dirclean,reconfigure,rebuild等
使用make help查看更多
make package-build
不支持Removing a package,是因为buildroot没有记录在output中安装的相应信息,和依赖的包.但只要删了output/build下的相应目录,再make时它就会重新解压配置编译了,所以可以使用如下命令来删除相应目录.
make < package>-dirclean
eg:make linux-custom-dirclean
make < package>-reconfigure:更改配置好重新编译使用
make < package>-rebuild:更改代码文件后重新编译使用
make external-deps:列出所有要用的源码包.当你不知道要下载哪个包时可以查询等.
make source
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
但 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
一启动就停在"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-compile | gcc版本 | kernel header | libc | 指令集 | fs | kernel | hello.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错误.其它的就没试了.
用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
–2018-12-14 14:58:24-- https://download.qt.io/official_releases/qt/5.11/5.11.3/submodules/qtcanvas3d-everywhere-src-5.11.3.tar.xz
正在解析主机 download.qt.io (download.qt.io)… 77.86.229.90
正在连接 download.qt.io (download.qt.io)|77.86.229.90|:443… 已连接。
错误: 无法验证 download.qt.io 的由 “CN=DigiCert SHA2 Secure Server CA,O=DigiCert Inc,C=US” 颁发的证书:
无法本地校验颁发者的权限。
要以不安全的方式连接至 download.qt.io,使用“–no-check-certificate”。
更改wget命令,加上**–no-check-certificate**
Build options --> Commands --> wget....