欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

从0到1学会Buildroot根文件系统构建

时间:2023-05-16

需要注意的是,以下文档内容由于自己水平有限,避免不了错误。所以要保持一个思考的头脑,遇到问题能够尽快解决并且积累经验。

1、 buildroot简介

官网首页对buildroot的定义,和特点有非常明确的介绍。
1)、buildroot的宗旨为了让嵌入式linux开发更容易。
2) 、管理一切!为嵌入式设备生成交叉编译工具链,文件系统,交叉编译bootloader和kernel image。
3) 、易用!所有配置通过像linux一样的menuconfig,gconfig和xconfig。
4)、支持丰富的package资源,构建你需要的rootfs。

Buildroot是Linux平台上一个构建嵌入式Linux系统的框架,整个Buildroot是由Makefile脚本和Kconfig配置文件构成。可以和编译Linux内核一样,通过buildroot配置,menuconfig修改,编译出一个完整的可以直接烧写到机器上运行的Linux系统软件(包含boot、kernel、rootfs以及rootfs中的各种库和应用程序)。制作的rootfs通常需要包含很多第三方软件,比如busybox,udhcpc,tftp,apache,sqlite,PHP,iptable,DNS等,为避免复杂的移植工作,在buildroot中通过menuconfig配置我们根文件系统中需要的功能,将不需要的去掉,再执行make编译,buildroot就会自动从指定的服务器上下载源码包,自动编译,自动搭建我们所需要的嵌入式根文件系统。

2、 buildroot下载

buildroot 源码肯定是要从 buildroot 官网下载,官网地址为 https://buildroot.org/,打开以后的官网界面如下图所示:

点击上图中“DOWNLOAD”按钮即可打开 buildroot 的下载界面,如下图所示:

我目前选的是最新的版本的buildroot,下载好后,将其拷贝至Ubuntu或者其他Linux环境里,利用命令tar –vxf buildroot-2021.08-rc2.tar.bz2解压其压缩包。

3、 buildroot目录介绍

我们想要了解一个代码的用途和怎么使用,我想先去了解一下目录构成,不会一个不错的开始.

buildroot├── arch: 存放CPU架构相关的配置脚本,如arm/mips/x86,这些CPU相关的配置,在制作工具链时,编译uboot和kernel时很关键├── board:在构建系统时,board默认的boot和kernel配置文件,以及一些板级相关脚本,存放一些默认开发板的配置补丁之类├── boot:bootloader配置脚本目录,可以选择使用uboot作为bootloader├── build:所有源码包解压出来的文件存放目录和编译过程的发生目录├── configs: 板级配置文件,该目录下的配置文件记录着该机器平台或者方案使用的工具链,boot,kernel,各种应用软件包的配置├── dl: download的简写,一些开源包下载后存在该目录;首次下载后,下次不会再从官网下载,而从dl/目录拿开源包,以节约时间 ├── docs: 存放相关的参考帮助文档├── fs: 各种文件系统的自动构建脚本 ├── linux: 存放着kernel的自动构建脚本├── output: 是编译出来的输出文件夹│ ├── build: 存放解压后的各种软件包编译完成后的现场,包括主机上Buildroot所需的工具和针对目标编译的软件包│ ├── host: 存放着制作好的编译工具链,如gcc、arm-linux-gcc等工具│ ├── images: 存放着编译好的uboot.bin, zImage, rootfs等镜像文件,可烧写到板子里, 让linux系统跑起来│ ├── staging:是到内部目标工具链host/的符号链接│ └── target: 用来制作rootfs文件系统,存放Linux系统基本的目录结构,以及编译好的应用库和bin可执行文件。(buildroot根据用户配置把.ko .so .bin文件安装到对应目录中)├── package:下面放着应用软件的配置文件,每个应用软件的配置文件有Config.in和soft_name.mk├── support:公共的支持文档(kconfig code, libtool patches, download helpers, and more)├── system:根目录主要骨架和相关启动初始化配置,存放文件系统目录的和设备节点的模板,这些模板会被拷贝到output/目录下,用于制作根文件系统rootfs├── toolchain:目录中存放着各种制作工具链的脚本├── utils:常用工具├── CHANGES├── Config.in├── Config.in.legacy├── COPYING├── DEVELOPERS├── Makefile├── Makefile.legacy└── README

4、 构建根文件系统 4.1、配置buildroot

在下载完并且解压完以后会得到名为buildroot-2021.08-rc2的目录,这就是我们buildroot源码目录,进到这个目录中,此目录如下所示:

buildroot 和 uboot、Linux kernel 一样也支持图形化配置,输入如下命令即可打开图形化配置界面:

make menuconfig

打开以后,图形化配置界面如下所示:

我们先来了解一下每一个选项的意思是什么:

Target options ---> 选择目标板架构特性。Build options ---> 配置编译选项。Toolchain ---> 配置交叉工具链,使用buildroot工具链还是外部提供。System configuration ---> 配置生成的根文件系统中所需功能Kernel ---> 配置kernel是否编译以及编译选项Target packages ---> 配置生成的根文件系统中的工具以及库Filesystem images ---> 配置生成的根文件系统的格式,是ext2还是其他Bootloaders ---> 配置使用哪种bootloader以及编译选项,uboot只是其中一种Host utilities ---> 主机使用功能Legacy config options ---> 以前遗留的配置选项

接下来就是我们依次来配置buildroot,配置完以后就可以进行编译了。
1)、配置Target options
首先配置Target options选项,以RV1109为例,需要配置的项目和其对应的内容如下(“=”号后面是配置项要选择的内容)

Target options//目标架构,这里选择 ARM(little endian),ARM小端模式-> Target Architecture = ARM (little endian)//二进制格式,为 ELF-> Target Binary Format = ELF//架构变体为cortex-A7,内核类型-> Target Architecture Variant = cortex-A7//应用程序二进制接口,为EABI-> Target ABI = EABIhf//浮点数的策略,选择为 Soft float-> Floating point strategy = NEON/VFPv4// arm 汇编指令集,选择 ARM-> ARM instruction set = ARM

配置完成以后如下图所示:

2)、配置Toolchain
此配置项用于配置交叉编译工具链,也就是交叉编译器,这里设置为我们自己所使用的交叉编译器即可。buildroot 其实是可以自动下载交叉编译器的,但是都是从国外服务器下载的,鉴于国内的网络环境,强烈推荐大家设置成自己所使用的交叉编译器。需要配置的项目和其对应的内容如下:

Toolchain-> Toolchain type = External toolchain-> Toolchain = Custom toolchain //用户自己的交叉编译器-> Toolchain origin = Pre-installed toolchain //预装的编译器-> Toolchain path =/home/zhaixing/rv1109/prebuild/gcc-> Toolchain prefix = $(ARCH)-linux-gnueabihf //前缀-> External toolchain gcc version = 8.x-> External toolchain kernel headers series = 4.19.x-> External toolchain C library = glibc/eglibc-> [*] Toolchain has SSP support? (NEW) //选中-> [*] Toolchain has RPC support? (NEW) //选中-> [*] Toolchain has C++ support? //选中-> [*] Enable MMU support (NEW) //选中

Toolchain 下几个比较重要的选项需要说明一下,如下所示:
Toolchain:设置为 Custom toolchain,表示使用用户自己的交叉编译器。
Toolchain origin:设置为 Pre-installed toolchain,表示使用预装的交叉编译器。
Toolchain path:设置自己安装的交叉编译器绝对路径!buildroot 要用到。
Toolchain prefix:设置交叉编译器前缀,要根据自己实际所使用的交叉编译器来设置,比如我们使用的是 arm-linux-gnueabihf-gcc,因此前缀就是$(ARCH)-linux-gnueabihf,其中 ARCH我们前面已经设置为了 arm。
3)、 配置 System configuration
此选项用于设置一些系统配置,比如开发板名字、欢迎语、用户名、密码等。需要配置的项目和其对应的内容如下:

System configuration-> System hostname = zhaixing_rv1109//平台名字,自行设置-> System banner = Welcome to rv1109 //欢迎语-> Init system = BusyBox //使用 busybox-> /dev management = Dynamic using devtmpfs + eudev //使用 eudev-> [*] Enable root login with password (NEW) //使能登录密码-> Root password = 123456 //登录密码为 123456

配置好的图形化界面如下截图:

在 System configuration 选项中可以配置平台名字,登录密码等信息。
4)、配置 Filesystem images
此选项配置我们最终制作的根文件系统为什么格式的,配置如下:

-> Filesystem images-> [*] ext2/3/4 root filesystem //如果是 EMMC 或 SD 卡的话就用 ext3/ext4-> ext2/3/4 variant = ext4 //选择 ext4 格式-> [*] ubi image containing an ubifs root filesystem //如果使用 NAND 的话就用 ubifs

5)、禁止编译Linux内核和uboot
buildroot 不仅仅能构建根文件系统,也可以编译 linux 内核和 uboot。当配置 buildroot,使能 linux 内核和 uboot 以后 buildroot 就会自动下载最新的 linux 内核和 uboot 源码并编译。但是我们一般都不会使用 buildroot 下载的 linux 内核和 uboot,因为 buildroot 下载的 linux 和 uboot官方源码,里面会缺少很多驱动文件,而且最新的 linux 内核和 uboot 会对编译器版本号有要求,可能导致编译失败。因此我们需要配置 buildroot,关闭 linux 内核和 uboot 的编译,只使用buildroot 来构建根文件系统,首先是禁止 Linux 内核的编译,配置如下:

-> Kernel-> [ ] Linux Kernel //不要选择编译 Linux Kernel 选项!

接着禁止编译 Uboot,配置如下:

-> Bootloaders-> [ ] U-Boot //不要选择编译 U-Boot 选项!

6 )、配置 Target packages
此选项用于配置要选择的第三方库或软件、比如 alsa-utils、ffmpeg、iperf 等工具,现在在这里就举个例子怎么添加第三方库,但是我们先不选择第三方库,防止编译不下去!先编译一下最基本的根文件系统,如果没有问题的话再重新配置选择第三方库和软件。否则一口吃太多会容易撑着的,编译出问题的时候都不知道怎么找问题。
举个例子,我们要配置alsa-lib,可以根据下面路径来配置,当然要先make menuconfig。

Target packages-> Libraries-> Audio/Sound-> -*- alsa-lib ---> 此配置项下的文件全部选中

4.2、编译buildroot

在配置好上面的选项后,我们就可以开始编译了,直接make就好。编译好的文件都会在output目录下,如下所示:

我们需要用到的是image目录下的文件,其文件内容如下:

我们现在只需要将其中的一个文件烧入到板子里就可以开始验证了。我这里使用的是rootfs.ext4。

5、根文件系统测试

打开RV1109专用的烧录工具,如下图所示:

只需要单独烧录rootfs就好,怎么使用这个工具,可以去看这方面的文档。如上图右边区域可知,rootfs烧录成功,接下来我们去看一下Linux启动日志,看我们构建的根文件系统有没有起来。如果看到类似如下日志,welcome to rv1009,说明这个文件系统是可以正常起来的。

接下来我们登录一开始我们配置好的账户和密码:root/123456,登录后如下所示:

这里要注意的是进去以后,直接ls是没有任何目录显示的,需要先进到根目录底下,使用命令cd /。这样我们就可以看到一个完整的根文件系统了。

其实到这,我们已经成功的构建了一个根文件系统,但是还是有一些小问题的。所以还需要稍微完善一下这个根文件系统,细心的可能已经发现了,我们目前这个文件系统,光标前是不显示路径的。所以需要去解决这个问题,解决办法就是修改etc目录下的profile文件,要进行修改的部分如下图所示:

这里修改的就是PS1这个命令,PS1 用于设置命令提示符格式。是原始的设置 PS1 环境变量的配置代码,就是它将命令提示符设置为了固定的“#”,这就导致了我们现在不会显示路径,我们将其修改为第3行,w这个参数就是显示当前工作目录的路径。PS1命令还有很多参数,感兴趣的可以上网查一查。
修改完这个文件后,保存退出。重新启动板子,我们就可以看到,已经显示路径了,如下图所示:

6、buildroot其它使用 6.1、添加具体board到buildroot

这一部分我们可以参考文档buildrootdocsmanualadding-board-support.txt。里面翻译过来就是两步骤:
一、 先make menuconfig配置好buildroot以后,它会在buildroot顶层目录下生成.config文件,这也就是我们后面编译make用到的真正配置文件。然后,将.config文件复制到buildrootconfigs文件夹下,并重新命名boardname_deconfig,其中boardname就是具体板子或者平台的名字。其实到这一步,我们已经可以开始编译了,已经算是成功添加了具体board到buildroot里了。然后编译的步骤就是make boardname_deconfig,这一步目的是将boardname_deconfig文件里的内容拷贝到顶层目录下的.config里;接着就直接输入make编译就好了。
二、 在第一步已经说过了,很多在第一步已经可以配置好了。但是在一些复杂的项目,还需要增加一些内核与uboot的配置或者补丁,这时候就需要在board目录下创建具体的目录,例如board/rockchip。

6.2、添加APP到buildroot

对目标板文件系统内容进行配置主要通过make menuconfig进入Target packages选项中进行修改,但首先需要将自己的APP添加进Buildroot框架中。要添加自己的本地APP,首先需要在package/Config.in中添加指向新增APP目录的Config.in;然后在package中创建新增APP目录,并在里面添加Config.in和xxx.mk文件;最后创建对应的APP源码目录,并在里面添加.c源文件和Makefile文件。
例如:创建本地应用helloworld过程
1、在package/Config.in修改并添加如下:

menu "Daniel private app package" source "package/helloworld/Config.in"endmenu

2、创建并修改buildroot/package/helloworld/Config.in如下:

config BR2_PACKAGE_HELLOWORLD bool "helloworld" help This is a demo to add local app.

3、创建并修改buildroot/package/helloworld/helloworld.mk如下:

####################################################### helloworld######################################################HELLOWORLD_VERSION:= 1.0.0HELLOWORLD_SITE:= $(TOPDIR)/../app/helloworldHELLOWORLD_SITE_METHOD:=localHELLOWORLD_INSTALL_TARGET:=YES define HELLOWORLD_BUILD_CMDS $(MAKE) CC="$(TARGET_CC)" LD="$(TARGET_LD)" -C $(@D) allendef define HELLOWORLD_INSTALL_TARGET_CMDS $(INSTALL) -D -m 0755 $(@D)/helloworld $(TARGET_DIR)/binendef define HELLOWORLD_PERMISSIONS /bin/helloworld f 4755 0 0 - - - - - endef $(eval $(generic-package))

注意:
_VERSION结尾的变量是源码的版本
_SITE结尾变量是源码的下载地址
_SITE_METHOD结尾的变量是源码下载方法
_BUILD_CMDS结尾的变量会在buildroot框架编译的时候执行,用于给源码的Makefile传递编译选项和链接选项,调用源码的Makefile。
_INSTALL_TARGET_CMDS结尾的变量是在编译完之后,自动安装执行,一般是让buildroot把编译出来的的bin或lib拷贝到指定目录。
$(eval $(generic-package))最核心的就是这个,一定不能漏掉,不然源码不会被编译,该函数就是把整个.mk构建脚本,通过Buildroot框架的方式,展开到buildroot/目录下的Makfile中,生成的构建目标。
4、创建并修改buildroot/../app/helloworld/helloworld.c如下:

#include int main(int argc, char *argv[]){ printf("Hello world.n"); return 0;}

5、创建并修改buildroot/../app/helloworld/Makefile如下:

CPPFLAGS +=LDLIBS += all: helloworld analyzestack: helloworld.o $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS) clean: rm -f *.o helloworld .PHONY: all clean

6、修改buildroot/configs/rockchip_rv1126_rv1109_defconfig中添加内容如下:

BR2_PACKAGE_HELLOWORLD=y

7、这样之后就可编译Buildroot,命令行中执行./build.sh rootfs即可,会在buildroot/output/rockchip_rv1126_rv1109/build/helloworld-1.0.0中执行编译,然后安装到buildroot/output/rockchip_rv1126_rv1109/target/bin中。

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。