前言
新冠疫情期间在家里无事可做,奈何手上没有现成的开发板,又想调试学习linux内核,于是就有了这一系列的文章。本系列文章包含以下内容:
- 在家学习嵌入式1-搭建qemu环境
- 在家学习嵌入式2-在qemu环境下使用uboot启动linux
- 在家学习嵌入式3-使用Buildroot构建编译系统
- 在家学习嵌入式4-Versatile Express开发板
- 在家学习嵌入式5-buildroot的使用
编译系统
在前面的文章中,我们分别下载编译uboot、下载编译kernel、下载busybox制作ramdisk、下载toolchain、制作SD卡等。这些步骤比较繁琐,有没有一种方法一键生成所需的镜像并且打包到一起呢?我们先看一下嵌入式系统编译的输入和输出,输入源码,输出二进制镜像。其中就需要Embedded Linux build system
来整合这些步骤,一键就需要依赖这里的build system(编译系统)来实现。目前的编译系统有Yocto/OpenEmbedded, PTXdist, Buildroot, OpenWRT。回想一下,SOC厂商发布BSP的时候,不可能一个个给你发布uboot、kernel的,而是将整个编译系统发布出来,据我所知NXP/MTK是通过Yocto发布,Pana通过Buildroot发布。
本文将使用buildroot作为编译系统,将我们之前使用qemu搭建的虚拟开发环境统一起来,实现一键编译打包。在这之前,我们先介绍一下buildroot。
buildroot介绍
buildroot官方的介绍如下,翻译下来就是buildroot是一个简单以及自动化的工具,可以使用交叉编译为嵌入式系统构建一个完整的linux系统。为了实现这个功能,buildroot可以生成交叉工具链,rootfs,linux kernel镜像和bootloader。buildroot可以独立地用于这些选项的任何组合(例如,您可以使用现有的交叉编译工具链,并仅通过Buildroot来构建根文件系统)。
Buildroot is a tool that simplifies and automates the process of building a complete Linux system for an embedded system, using cross-compilation. In order to achieve this, Buildroot is able to generate a cross-compilation toolchain, a root filesystem, a Linux kernel image and a bootloader for your target. Buildroot can be used for any combination of these options, independently (you can for example use an existing cross-compilation toolchain, and build only your root filesystem with Buildroot).
以下内容将一步步介绍如何配置buildroot作为我们自己的qemu vexpress虚拟开发板的编译系统。
拷贝配置
在configs/qemu_arm_vexpress_defconfig
有关于qemu vexpress-a9的buildroot配置,我们以此为基础,将其拷贝为configs/wowothink_qemu_arm_vexpress_defconfig
文件,然后根据这个文件进行buildroot的配置。在make menuconfig
之前,我们先通过make wowothink_qemu_arm_vexpress_defconfig
生成.config
文件。
配置Target options
这部分内容为默认的,在我们使用qemu_arm_vexpress_defconfig
的配置的时候就已经默认好了,所以无需配置。
1 | Target Architecture (ARM (little endian)) ---> |
配置Build options
这部分内容有一个需要配置的就是Location to save buildroot config
选项,将其指定为我们wowothink_qemu_arm_vexpress_defconfig
配置文件的路径即可。这样子我们每次执行make savedefconfig
就会自动将其保存到该文件。
1 | Commands ---> |
有个小的注意事项,在执行make
的时候,buildroot有可能会从网络上下载包,有些会提示如下的错误:
1 | 错误: 无法验证 releases.linaro.org 的由 “CN=Let's Encrypt Authority X3,O=Let's Encrypt,C=US” 颁发的证书: |
解决办法是在wget
命令中加入--no-check-certificate
的参数,在下面的选项中加入即可。
1 | Build options --->Commands --->(wget --passive-ftp -nd -t 3 --no-check-certificate) Wget command |
配置Toolchain
下面的toolchain是我最终的配置,我尝试使用Buildroot toolchain
的配置,但是由于网络的原因总是下载断开。后面我使用系统自带的arm-linux-gnueabi
,也就是之前安装的交叉工具链,但是在编译的时候会提示以下的错误:
1 | Distribution toolchains are unsuitable for use by Buildroot, |
最终,我不得不预先从https://releases.linaro.org/components/toolchain/binaries/ 下载5.4版本的交叉工具链,然后通过Toolchain path
指定其路径。注意,在buildroot中,所有路径相关的,最后都不能带/
,因为buildroot会自动将其加上。
1 | Toolchain type (External toolchain) ---> |
配置System configuration
这里主要配置为busybox为Init system
,并设置运行一个getty
,这样子系统启动后会有一个console,并且这个console是/bin/sh
,用户名和登陆密码为root
.
1 | Root FS skeleton (default target skeleton) ---> |
配置Kernel
linux kernel配置其从gitee上下载,并且切换到v4.4
的branch上面,使用的kernel的defconfig名字为vexpress
(改名字无需加上_defconfig
的后缀),dtb名字为vexpress-v2p-ca9
。这样子,在编译linux kernel的时候,buildroot就会自动去使用vexpress _defconfig
的配置,并且会去编译生成vexpress-v2p-ca9.dtb
。这样子最终在out/images/
会生成一个zImage
和vexpress-v2p-ca9.dtb
的文件。注意事项:有时候国内的网络不稳定,kernel无法clone下来,经常断开。如果之前有下载过linux kernel,就可以将URL of custom repository
配置为之前linux kernel的路径。
1 | [*] Linux Kernel |
配置Filesystem images
这一步主要配置生成的rootfs是什么格式的,在前面,我们使用了uramdisk.img
的cpio
加上gzip
并且带上uboot
头的文件格式,那么这里就必须配置上cpio/gzip/uboot image
的格式。这样子最终在out/images/
会生成一个rootfs.cpio.uboot
的文件。为了保证名称的一致性,需要将我们前面打入uboot中的patch里面的ramdisk_name=uramdisk.img\0
修改为ramdisk_name=rootfs.cpio.uboot\0
1 | [ ] axfs root filesystem |
配置Bootloaders
这一步主要配置编译uboot,配置uboot源码从gitee上下载,使用v2017.01
的分支,并且使用vexpress_ca9x4
作为uboot的配置文件。Custom U-Boot patches
这个路径是配置uboot的patch路径,如果没有patch打入到uboot中,可以不用配置。
1 | [ ] afboot-stm32 |
配置uboot的二进制文件为u-boot.elf
,由于qemu使用的是elf文件格式的uboot,因此这里必须配置上。
1 | [ ] u-boot.ais |
配置自动生成sdcard.img
在前面的文章中,我们制作了一个vfat格式的sdcard,将所需的zImage
、uramdisk.img
、vexpress-v2p-ca9.dtb
拷贝到该sdcard中,然后再uboot启动的时候从sdcard将其load到DDR中并且启动linux。这个几步在buildroot中可以自动执行完成,需要在System configuration
配置以下两个选项:
1 | (support/scripts/genimage.sh) Custom scripts to run after creating filesystem images |
前者表示创建文件系统后去执行genimage.sh
脚本,后者表示该脚本使用的配置文件,配置文件的内容如下,表示创建一个vfat
格式的sdcard.img
,大小为512M,里面包含3个文件。
1 | Minimal SD card image for the qemu arm vexpress board |
一键编译生成
- 首先从https://releases.linaro.org/components/toolchain/binaries/ 下载5.4版本的交叉工具链;
- 下载我配置好的buildroot源码:
git clone https://gitee.com/wowothink/buildroot.git
; 修改
configs/wowothink_qemu_arm_vexpress_defconfig
文件以下两个宏为自己本地的绝对路径,分别是toolchain的路径以及uboot patch的路径:1
2BR2_TOOLCHAIN_EXTERNAL_PATH="/home/victor/work/toolchain/gcc-linaro-5.4.1-2017.01-x86_64_arm-linux-gnueabi"
BR2_TARGET_UBOOT_PATCH="/home/victor/work/buildroot/buildroot/board/qemu/arm-vexpress/patches/uboot"一键编译生成
一键编译生成 1
2make wowothink_qemu_arm_vexpress_defconfig
make
最终在output/images/
会生成如下文件,qemu就可以用sdcard.img
和u-boot
。
1 | victor@victor-linux:~/work/temp/buildroot$ ll output/images/ |
- 使用
qemu-system-arm
启动1
qemu-system-arm -M vexpress-a9 -m 1024M -kernel /home/victor/work/temp/buildroot/output/images/u-boot -nographic -no-reboot -sd /home/victor/work/temp/buildroot/output/images/sdcard.img