本文描述buildroot的详细使用步骤,以恩智浦imx6ull处理器为运行平台。
一、获取buildroot
从https://buildroot.org/链接中下载buildroot:
这里小生选择buildroot-2022.02.6.tar.xz版本:
在Ubuntu20.04下解压缩软件包后,其目录结构大致如下所示:
还是习惯性的剖析一下其目录中的内容:顶层目录下放置了一些都很常见的文件,还是一样的,makefile最重要,Config.in文件是一个makefile文件的配置输入,该文件由makefile读取解析,README文件中描述了buildroot的使用方法:
(1)在arch目录下,以arch.xx的命名方式编写了针对特定架构的配置选项和对应的参数:
(2)在board目录下,大概放置了关于有些芯片厂家硬件平台相关的文件,以目录进行划分和规划。
(3)在boot目录下,放置了关于bootloader的相关目录,目录中放置的是一个Config.in配置输入描述文件和一个具体的makefile描述文件。
(4)在configs目录下,放置了许多与具体芯片厂商板卡的默认配置,在配置buildroot时,可以使用该目录下的文件。
(5)docs目录,肯定是放置了与buildroot的描述文档,熟悉buildroot的必看目录。
(6)在fs目录下,放置buildroot支持的文件系统,以文件系统名称命名,目录中同样放置了Config.in配置输入描述文件和一个具体的makefile文件:
(7)在linux目录下,放置与linux相关的配置文件。
(8)package目录,是buildroot的软件包管理目录,我们知道buildroot支持很多软件包的自动编译构建,不同的软件包如果需要加入到buildroot中,则需要在该目录下添加。该目录下的子目录太多啦。
(9)在system目录下,放置了描述编译构建出的文件系统的配置文件。
(10)在toolchain目录下,放置与编译构建套件相关的配置文件。buildroot支持内部自动编译构建出编译套件,也支持外部的编译构建套件。
(11)在utils目录下,该目录下包含各种与buildroot编译构建相关的工具。
至此,buildroot的目录结构描述完了,可以明确知道在没有开始编译构建之前,她是一个非常小的目录,目录中也没有包含具体的软件包的工程程序,也没有编译过程文件和目标文件等,靠着一系列的配置文件和makefile完成整个构建过程,小而精美。
二、配置buildroot
在buildroot目录下打开终端(一定是要在buildroot目录路径下),输入make menuconfig将编译构建出宿主机上的图形配置界面:
在上图中,可以看见10个配置选项:
(1)Target options:用于为构建目标选择特性和配置参数。
(2)Build options:该选项用于配置编译构建相关的配置参数。
(3)Toolchain:该选项用于配置工具链和编译器特性。
(4)System configuration:该选项用于配置生成的文件系统的配置文件和启动特性。
(5)Kernel:该选项用于配置linux内核特征和参数。
(6)Target packages:该选项用于选择和配置所需要的软件包和软件环境。
(7)Filesystem images:该选项用于配置经buildroot编译构建后的文件系统的镜像格式。
(8)Bootloaders:该选项用于选择和配置启动加载程序。
(9)Host utilities:该选项用于配置是否构建编译出宿主机上的一些工具套件。
(10) Legacy config options:随着历史版本更迭原因,该选项用于配置一些遗留下来的特性。
1、在实际使用中,有些芯片原厂会基于buildroot来进行特定芯片的嵌入式linux软件环境构建。这时候他们往往会创建一个比较大的开发目录,将linux内核、bootloader、buildroot和其他的开发库归入一个目录中,并在该目录下编写自己的构建脚本,形成一个软件开发的SDK,发布给硬件板卡提供商或者第三方的合作商使用。在这种情况下,直接使用写好的脚本构建linux开发环境即可,但是其体量很大,也不知道在里面搞了些啥事情,有时候还要单独构建,哈哈。
2、当然,也有将linux内核和bootloader单独使用的情况,这种情况下,只需要使用buildroot构建出根文件系统,然后再配置自己的软件开发栈就可以了。本文就基于这种情况来描述、记录buildroot的使用。
三、配置过程记录
本文基于恩智浦的imx6ull平台使用buildroot构建根文件系统。小生使用得是 MCIMX6Y2CVM08AB。
MCIMX6Y2CVM08AB是一款主频800MHz的工业级Cortex-A7核心的处理器芯片。自带32KB的L1指令和数据Cache、128KB的L2 Cache,集成NEON,集成双精度硬件浮点计算单元VFPv3,并具有128KB OCRAM、2个通用定时器(GPT)、4个周期定时器(EPIT)、8个PWM、1个SDMA 控制器、4个ECSPI、3个看门狗、3个SAI、4个IIC、7个串口、2个USB(高速,带PHY)、2个FlexCAN、2个12位ADC、1个SPDIF接口、1个 SRTC、1个RTC、2个USDHC接口、1个RGB LCD控制器(ELCDIF)、2个10/100M以太网MAC控制器、1个摄像头接口、1个硬件随机数生成器以及124个通用IO口等。
上面简单介绍恩智浦的这款芯片,小生下文以构建一个轻量级的根文件系统为目标展开:
首先描述一下小生的开发环境:
虚拟机16 + ubuntu20.04
硬件配置:
(磁盘容量最好配置大些,小生这里都有点小了)
(1)配置Target options选项
选项展开比较多,后面的选项配置都会以下列所示的方式描述:等号左边为配置项,等号右边为具体的配置选择:
Target options -> Target Architecture = ARM (little endian) -> Target Binary Format = ELF -> Target Architecture Variant = cortex-A7 -> Target ABI = EABIhf -> Floating point strategy = NEON/VFPv4 -> ARM instruction set = ARM
完成后如下图所示:
(2)Build options配置选项
这里不需要配置。
(3)配置Toolchain选项
由于小生已经准备好了交叉编译工具套件gcc-linaro-5.5.0-2017.10-x86_64_arm-linux-gnueabihf,此处需设置为:
Toolchain -> Toolchain type = External toolchain -> Toolchain = Custom toolchain -> Toolchain origin = Pre-installed toolchain -> Toolchain path = 此处写具体编译构建套件的绝对路径 -> Toolchain prefix = $(ARCH)-linux-gnueabihf。根据具体的编译构建套件的名称填写,$(ARCH)不用修改。 ->External toolchain gcc version = 根据具体的gcc版本对应的版本。(这个配置项需要配置好,如 果选择不合适,可能有些软件库无法选择甚至编译构建过程无法完成,这时候重新选择后再编译就行,直到编译构建通过) ->External toolchain kernel headers series = 根据具体的linux版本选择。 ->External toolchain C library = glibc/eglibc //后面的配置项可以不用选择或者默认即可
配置完成后,如下图所示:
(4)System configuration配置
在该配置选项下选择根文件系统相关的配置。
System configuration ->Root FS skeleton = default target skeleton -> System hontname = 填写系统名称(任意) ->System banner = 填写系统标语(任意) ->Passwords encoding = sha-256 -> Init system = BusyBox //这里构建Busybox启动的根文件系统 ->/dev management = Dynamic using devtmpfs only -> Enable root login with password = 选择/并设置登录密钥(123456) //其他配置选项不变,保持默认即可
(5)Kernel配置
由于此处只编译构建出根文件系统,所以不选择linux kernel配置选项,则不会自动下载和编译构建linux内核。
(6)Target packages配置
本文的构建目标是一个轻量级的根文件系统,所以Target packages下的配置选项则不用选择(默认也是没有选中的)
(7)Filesystem images配置
该选项下用于配置选择文件系统的镜像格式,如果是用nfs或tftp方式挂载根文件系统进行调试,Filesystem images则不用进行任何配置。
(8)Bootloaders配置
Bootloaders选项不用配置。
(9)Host utilities配置
Host utilities选项不用配置。
(10)Legacy config options配置
Legacy config options选项不用配置。
通过以上步骤就根据实际的构建需求对buildroot进行了配置,选择< Save >保存buildroot的配置选项参数。保存后,在终端使用sudo make -j12进行编译构建。
编译构建过程中问题
(1)报错Incorrect selection of kernel headers: expected 4.6.x, got 4.0.x,并终止构建:
出现这个问题的原因是在交叉编译器的路径下有一个内核版本代码,buildroot在执行check-kernel-headers.sh时会检测这个内核版本代码。
该内核版本描述代码定义在路径/gcc-linaro-5.5.0-2017.10-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/usr/include/linux/version.h中:
#define LINUX_VERSION_CODE 262144
十进制262144转换为十六进制则为:40000,在配置buildroot时选择为4.6.x版本:
所以编译构建不能通过,为了解决这个问题,可以直接修改version.h中的LINUX_VERSION_CODE宏定义值为:
#define LINUX_VERSION_CODE 263680 //263680 = 40600(h)
即可解决。
编译构建后结果
在buildroot构建过程中,会连接网络下载对应的软件包源码,下载的这些软件包存放在output/build目录中,如下图所示:
(由于本文构建的根文件系统也没有配置太多的软件包,所以生成的目录就少)
编译构建后生成的目标结果存放于output/images目录中:
(将rootfs.tar解压缩,然后则可以使用nfs/tftp挂载根文件系统进行测试啦)
在测试根文件系统时,会发现进入命令行后,输入命令的时候命令行前面一直都是“#”,如果我们进入到某个目录的话前面也不会显示当前目录路径。这是由于PS1变量参数设置错误造成的,需要重新设置一下,PS1 变量用于设置命令提示符格式,可选参数含义如下所示:
! 显示该命令的历史记录编号。 # 显示当前命令的命令编号。 $ 显示$符作为提示符,如果用户是 root 的话,则显示#号。 \ 显示反斜杠。 d 显示当前日期。 h 显示主机名。 打印新行。 nn 显示 nnn 的八进制值。 s 显示当前运行的 shell 的名字。 显示当前时间。 u 显示当前用户的用户名。 W 显示当前工作目录的名字。 w 显示当前工作目录的路径
修改方法:打开/etc/profile 文件,找到如下所示内容:
if [ "$PS1" ]; then if [ "`id -u`" -eq 0 ]; then export PS1='# ' else export PS1='$ ' fi fi
修改为如下代码:
if [ "$PS1" ]; then if [ "`id -u`" -eq 0 ]; then export PS1='[u@h]:w$#' else export PS1='[u@h]:w$$' fi fi
即可解决。
总结
本文记录了buildroot的使用步骤,描述了针对imx6ull处理器芯片的buildroot的轻量级根文件系统完整构建过程。由于是轻量级的构建,所以大约需要5-6分钟就可以编译构建完成。
相比较于busybox,buildroot构建出的根文件系统功能更加完善,配置文件也更加完整,不用再去手动添加和修改一些linux系统启动必须的文件了,非常适合更复杂的嵌入式linux系统的构建和开发。
编辑:黄飞
评论
查看更多