Buildroot 开发使用技巧
Buildroot是一个简单、高效且易于使用的工具,可以使用它自动构建一个Linux系统。
1.搭建编译环境
buildroot构建Linux系统可以使用内部工具(默认),也可以使用外部工具,这里在Ubuntu上以默认配置的内部工具为例,简单搭建一下开发环境:
1 $ sudo apt update 2 $ sudo apt install build-essential vim flex bison bc texinfo libc6-dev libssl-dev libncurses5-dev gawk zip unzip git wget curl axel file p7zip-full u-boot-tools liblz4-dev
2.下载Buildroot
下载方式有很多,简单列举3种,比如:
2.1 从官方网页下载
[下载] [https://buildroot.org/]
2.2 从官网仓库下载
$ git clone git://git.buildroot.net/buildroot
或者
$ git clone https://git.buildroot.net/buildroot
2.3 从github下载
$ git clone https://github.com/buildroot/buildroot.git
3. 配置、编译buildroot
官方文档:
[跳转] [https://buildroot.org/downloads/manual/manual.text]
下载后目录如下:
CHANGES Config.in DEVELOPERS Makefile README.md board configs fs output support toolchain COPYING Config.in.legacy LICENSE Makefile.legacy arch boot docs linux package system utils
其中,configs中保存了支持项目的配置文件,我们也可以通过如下命令查看支持的项目配置:
$ make list-defconfigs
以树莓派3b为例,配置:
$ make raspberrypi3_64_defconfig
调整配置:
$ make menuconfig
编译:
$ make -j4 2>&1 | tee build.log
另外,还有一些其它配置,和编译方法:
单独配置内核:
$ make linux-menuconfig
单独编译内核:
$ make linux -j4
另外,还有一些常见的举例:
$ make uboot-menuconfig $ make uboot -j4
$ make busybox-menuconfig $ make busybox -j4
$ make uclibc-menuconfig $ make ublibc -j4
4. 开发技巧
构建修改
buildroot构建时会从网络下载源码压缩包,然后解压编译,编译内容既有target端,也有host端,我一般会把它们划分成3个部分,buildroot、dl、output。
这3个部分我放在同一级目录,buildroot中就是原本从git仓库下载的内容,dl是下载源码压缩包存储的地方,output是解压后源码和编译文件,配置文件,目标文件等存放的地方。
首先,修改buildroot根目录Makefile,我下载这个版本的buildroot中一共修改了3处output,就是把$(CURDIR)/output改成$(CURDIR)/../output。
(其实不修改也可以,这样用make o=../output,但是每次输入嫌麻烦)。
@@ -36,7 +36,7 @@ # or avoid confusing packages that can use the O=<dir> syntax for out-of-tree # build by preventing it from being forwarded to sub-make calls. ifneq ("$(origin O)", "command line") -O := $(CURDIR)/output +O := $(CURDIR)/../output endif # Check if the current Buildroot execution meets all the pre-requisites. @@ -160,7 +160,7 @@ # Set variables related to in-tree or out-of-tree build. # Here, both $(O) and $(CURDIR) are absolute canonical paths. -ifeq ($(O),$(CURDIR)/output) +ifeq ($(O),$(CURDIR)/../output) CONFIG_DIR := $(CURDIR) NEED_WRAPPER = else @@ -1079,7 +1079,7 @@ .PHONY: distclean distclean: clean -ifeq ($(O),$(CURDIR)/output) +ifeq ($(O),$(CURDIR)/../output) rm -rf $(O) endif rm -rf $(TOPDIR)/dl $(BR2_CONFIG) $(CONFIG_DIR)/.config.old $(CONFIG_DIR)/..config.tmp \
然后,修改menuconfig
$ make raspberrypi3_64_defconfig $ make menuconfig
menuconfig中做如下修改:
Build options ---> ($(TOPDIR)/../dl) Download dir
之后,就可以编译了。有些源码文件可能国内网络下载不了,自己想办法科学,上网下载了放到dl对应的目录下(如果没有对应目录,则自己在dl下新建)。
成功编译之后,包括linux源码在内的解压源码都在output/build目录下。
内核开发
我写了个arm32的编译脚本,把脚本放到linux源码根目录,使用脚本可以应付简单内核开发。
(版本不同,项目不同,自行参考脚本修改)。
[build_arm2.sh]
1 #!/bin/bash 2 3 #################################### 4 # Example: 5 # ./build_arm2.sh -j4 6 # ./build_arm2.sh menuconfig 7 # ./build_arm2.sh dtbs 8 # ./build_arm2.sh modules 9 # ./build_arm2.sh clean 10 #################################### 11 12 # Buildroot source path. 13 SOURCE_PATH=/home/linux/buildroot 14 15 # Build architecture. 16 ARM_ARCH=arm 17 18 # Cross compilation toolchain. 19 ARM_GCC=output/host/bin/arm-buildroot-linux-uclibcgnueabihf- 20 21 # Build parameter. 22 BUILD_PARAM= 23 24 if [ -n "$1" ] && [ "-h" == $1 ]; then 25 echo "[Example]:"; 26 echo " ./build_arm2.sh -j4"; 27 echo " ./build_arm2.sh menuconfig"; 28 echo " ./build_arm2.sh dtbs"; 29 echo " ./build_arm2.sh modules"; 30 echo " ./build_arm2.sh clean"; 31 elif [ -n "$1" ]; then 32 BUILD_PARAM=$1 33 fi 34 35 START_TIME=`date +%T` 36 37 make ${BUILD_PARAM} ARCH=${ARM_ARCH} CROSS_COMPILE=${SOURCE_PATH}/${ARM_GCC} 38 39 END_TIME=`date +%T` 40 41 echo "======== Completed. Elapsed time: [${START_TIME}] ~ [${END_TIME}]. ========";
驱动开发
写了个Makefile,仅供参考,根据实际版本和项目自行修改:
[Makefile]
1 # Need build object. 2 MODULE = leds-gpio 3 4 # Buildroot source path. 5 SOURCE_PATH = /home/linux/buildroot 6 7 # Build architecture. 8 ARM_ARCH = arm 9 10 # Cross compilation toolchain. 11 ARM_GCC = output/host/bin/arm-buildroot-linux-uclibcgnueabihf- 12 13 # Define kernel path. 14 KERNEL_PATH = output/build/linux-5.12.2 15 16 # Define current path. 17 CUR_PATH = $(shell pwd) 18 19 20 all: 21 make -C ${SOURCE_PATH}/$(KERNEL_PATH) M=$(CUR_PATH) ARCH=${ARM_ARCH} CROSS_COMPILE=${SOURCE_PATH}/${ARM_GCC} modules 22 23 clean: 24 make -C ${SOURCE_PATH}/$(KERNEL_PATH) M=$(CUR_PATH) ARCH=${ARM_ARCH} CROSS_COMPILE=${SOURCE_PATH}/${ARM_GCC} clean 25 26 # Define build object. 27 obj-m = $(MODULE).o
应用开发
写了个Makefile,自行参考修改:
[Makefile]
1 # Application object. 2 APP_OBJ = hello 3 4 # Buildroot source path. 5 SOURCE_PATH = /home/linux/buildroot 6 7 # Cross compilation toolchain. 8 ARM_GCC = output/host/bin/arm-buildroot-linux-uclibcgnueabihf 9 10 all: 11 ${SOURCE_PATH}/${ARM_GCC}-gcc -o $(APP_OBJ) $(APP_OBJ).c 12 13 clean: 14 $(RM) $(APP_OBJ)
向rootfs中添加文件
我们写了驱动和应用,需要添加到rootfs中,方法有很多,文件共享,samba,nfs,tftp,磁盘,挂载,这里简单介绍挂载:
$ sudo mount rootfs.ext2 /mnt $ sudo cp leds-gpio.ko /mnt/root $ sudo umount /mnt