以下内容源于朱有鹏嵌入式课程的学习与整理,如有侵权请告知删除。
参考博客:buildroot详解和分析_Alex-wu的博客-CSDN博客_buildroot
板级支持包(BSP,Board Support Package),是由引导程序(Bootload)、内核( Kernel)、根文件系统(Rootfs)、工具链(Toolchain)等软件组成的资源包。x210开发板的BSP:下载地址
一、BSP的整体介绍
1、嵌入式linux产品的BSP介绍
芯片厂家或板卡厂家在交付时会提供BSP。
ARM+linux形式的BSP,其内容和结构都是相似的。
2、X210的linux+QT bsp整体介绍
文件或文件夹 描述 tslib_x210_qtopia.tgz 用来支持QT的触摸屏操作的应用层库 xboot和uboot文件夹 X210支持的2个bootloader源代码 kernel文件夹 内核源代码 buildroot文件夹 用来构建根文件系统的文件夹 tools文件夹 一些有用工具 mk文件 用来管理和编译整个bsp
二、mk文件
1、mk文件的内容
#!/bin/sh
#
# Description : Build Qt Script.
# Authors : jianjun jiang - jerryjianjun@gmail.com
# Version : 0.01
# Notes : None
#CPU_NUM=$(cat /proc/cpuinfo |grep processor|wc -l)
CPU_NUM=$((CPU_NUM+1))SOURCE_DIR=$(cd `dirname $0` ; pwd)RELEASE_DIR=${SOURCE_DIR}/release/
BOOTLOADER_XBOOT_CONFIG=arm32-x210ii
QT_KERNEL_CONFIG=x210ii_qt_defconfig
INITRD_KERNEL_CONFIG=x210ii_initrd_defconfig
BUILDROOT_CONFIG=x210_defconfigsetup_environment()
{cd ${SOURCE_DIR};mkdir -p ${RELEASE_DIR} || return 1;
}build_bootloader_xboot()
{if [ ! -f ${RELEASE_DIR}/zImage-initrd ]; thenecho "not found kernel zImage-initrd, please build kernel first" >&2return 1fiif [ ! -f ${RELEASE_DIR}/zImage-qt ]; thenecho "not found kernel zImage-qt, please build kernel first" >&2return 1fi# copy zImage-initrd and zImage-qt to xboot's romdisk directorycp -v ${RELEASE_DIR}/zImage-initrd ${SOURCE_DIR}/xboot/src/arch/arm32/mach-x210ii/romdisk/boot || return 1;cp -v ${RELEASE_DIR}/zImage-qt ${SOURCE_DIR}/xboot/src/arch/arm32/mach-x210ii/romdisk/boot || return 1;# compiler xbootcd ${SOURCE_DIR}/xboot || return 1make TARGET=${BOOTLOADER_XBOOT_CONFIG} CROSS=/usr/local/arm/arm-2012.09/bin/arm-none-eabi- clean || return 1;make TARGET=${BOOTLOADER_XBOOT_CONFIG} CROSS=/usr/local/arm/arm-2012.09/bin/arm-none-eabi- || return 1;# rm zImage-initrd and zImage-qtrm -fr ${SOURCE_DIR}/xboot/src/arch/arm32/mach-x210ii/romdisk/boot/zImage-initrdrm -fr ${SOURCE_DIR}/xboot/src/arch/arm32/mach-x210ii/romdisk/boot/zImage-qt# copy xboot.bin to release directorycp -v ${SOURCE_DIR}/xboot/output/xboot.bin ${RELEASE_DIR}echo "" >&2echo "^_^ xboot path: ${RELEASE_DIR}/xboot.bin" >&2return 0
}build_bootloader_uboot_nand()
{cd ${SOURCE_DIR}/uboot || return 1make distcleanmake x210_nand_configmake -j${CPU_NUM}mv u-boot.bin uboot_nand.binif [ -f uboot_nand.bin ]; thencp uboot_nand.bin ${RELEASE_DIR}/uboot.bincd ${RELEASE_DIR}${SOURCE_DIR}/tools/mkheader uboot.binecho "^_^ uboot_nand.bin is finished successful!"exitelseecho "make error,cann't compile u-boot.bin!"exitfi
}build_bootloader_uboot_inand()
{cd ${SOURCE_DIR}/uboot || return 1make distcleanmake x210_sd_configmake -j${CPU_NUM}mv u-boot.bin uboot_inand.binif [ -f uboot_inand.bin ]; then cp uboot_inand.bin ${RELEASE_DIR}/uboot.bincd ${RELEASE_DIR}${SOURCE_DIR}/tools/mkheader uboot.binecho "^_^ uboot_inand.bin is finished successful!"exitelseecho "make error,cann't compile u-boot.bin!"exitfi
}build_kernel()
{cd ${SOURCE_DIR}/kernel || return 1# make ${INITRD_KERNEL_CONFIG} || return 1# make -j${threads} || return 1# dd if=${SOURCE_DIR}/kernel/arch/arm/boot/zImage of=${RELEASE_DIR}/zImage-initrd bs=2048 count=8192 conv=sync;make ${QT_KERNEL_CONFIG} || return 1make -j${threads} || return 1dd if=${SOURCE_DIR}/kernel/arch/arm/boot/zImage of=${RELEASE_DIR}/zImage-qt bs=2048 count=8192 conv=sync;echo "" >&2# echo "^_^ initrd kernel path: ${RELEASE_DIR}/zImage-initrd" >&2echo "^_^ qt kernel path: ${RELEASE_DIR}/zImage-qt" >&2return 0
}build_rootfs()
{cd ${SOURCE_DIR}/buildroot || return 1make ${BUILDROOT_CONFIG} || return 1make || return 1# copy rootfs.tar to release directorycp -v ${SOURCE_DIR}/buildroot/output/images/rootfs.tar ${RELEASE_DIR} || { return 1; }
}# must root user
gen_qt_rootfs_ext3()
{if [ ! -f ${RELEASE_DIR}/rootfs.tar ]; thenecho "not found rootfs.tar, please build rootfs" >&2return 1fiecho "making ext3 qt4.8 rootfs now,wait a moment..."cd ${RELEASE_DIR}rm -rf rootfsmkdir -p rootfstar xf rootfs.tar -C rootfsrm rootfs_qt4.ext3rm -rf rootfs_imgmkdir -p rootfs_imgdd if=/dev/zero of=rootfs_qt4.ext3 bs=1024 count=262144mkfs.ext3 rootfs_qt4.ext3mount -o loop rootfs_qt4.ext3 ./rootfs_imgcp ./rootfs/* ./rootfs_img -arumount ./rootfs_imgecho "^_^ make rootfs_qt4.ext3 successful!"
}# must root user
gen_qt_rootfs_jffs2()
{if [ ! -f ${RELEASE_DIR}/rootfs.tar ]; thenecho "not found rootfs.tar, please build rootfs" >&2return 1fiecho "making jffs2 qt4.8 rootfs now,wait a moment..."cd ${RELEASE_DIR}rm -rf rootfsmkdir -p rootfstar xf rootfs.tar -C rootfs[ -e "rootfs" ] ||{ echo "error!can't find rootfs dir"; exit;}mkfs.jffs2 -r rootfs -o rootfs_qt4.jffs2 -e 0x20000 -s 0x800 --pad=0x5000000 -necho "^_^ make rootfs_qt4.jffs2 successful!"
}gen_qt_update_bin()
{# check image filesif [ ! -f ${RELEASE_DIR}/xboot.bin ]; thenecho "not found bootloader xboot.bin, please build bootloader" >&2return 1fiif [ ! -f ${RELEASE_DIR}/zImage-initrd ]; thenecho "not found kernel zImage-initrd, please build kernel first" >&2return 1fiif [ ! -f ${RELEASE_DIR}/zImage-qt ]; thenecho "not found kernel zImage-qt, please build kernel first" >&2return 1fiif [ ! -f ${RELEASE_DIR}/rootfs.tar ]; thenecho "not found rootfs.tar, please build rootfs" >&2return 1firm -fr ${RELEASE_DIR}/tmp || return 1;rm -fr ${RELEASE_DIR}/qt-update.bin || return 1;mkdir -p ${RELEASE_DIR}/tmp || return 1;# copy image filescp ${RELEASE_DIR}/xboot.bin ${RELEASE_DIR}/tmp/;cp ${RELEASE_DIR}/zImage-initrd ${RELEASE_DIR}/tmp/;cp ${RELEASE_DIR}/zImage-qt ${RELEASE_DIR}/tmp/;cp ${RELEASE_DIR}/rootfs.tar ${RELEASE_DIR}/tmp/;# create md5sum.txtcd ${RELEASE_DIR}/tmp/;find . -type f -print | while read line; doif [ $line != 0 ]; thenmd5sum ${line} >> md5sum.txtfidone# mkisofsmkisofs -l -r -o ${RELEASE_DIR}/qt-update.bin ${RELEASE_DIR}/tmp/ || return 1;cd ${SOURCE_DIR} || return 1 rm -fr ${RELEASE_DIR}/tmp || return 1;return 0;
}threads=4;
xboot=no;
uboot_inand=no;
uboot_nand=no;
kernel=no;
rootfs=no;
rootfs_ext3=no;
rootfs_jffs2=no;
update=no;if [ -z $1 ]; thenxboot=yesuboot_inand=no;uboot_nand=no;kernel=yesrootfs=yesrootfs_ext3=no;rootfs_jffs2=no;update=yes
fiwhile [ "$1" ]; docase "$1" in-j=*)x=$1threads=${x#-j=};;-x|--xboot)xboot=yes;;-ui|--uboot_inand)uboot_inand=yes;;-un|--uboot_nand)uboot_nand=yes;;-k|--kernel)kernel=yes;;-r|--rootfs)rootfs=yes;;-re|--rootfs_ext3)rootfs_ext3=yes;;-rj|--rootfs_jffs2)rootfs_jffs2=yes;;-U|--update)update=yes;;-a|--all)xboot=yeskernel=yesrootfs=yesupdate=yes;;-h|--help)cat >&2 <<EOF
Usage: mk [OPTION]
Build script for compile the source of telechips project.-j=n using n threads when building source project (example: -j=16)-x, --xboot build bootloader xboot from source file-ui,--uboot_inand build uboot for emmc-un,--uboot_nand build uboot for nand flash-k, --kernel build kernel from source file and using default config file-r, --rootfs build root file system-re,--rootfs_ext3 build rootfs for emmc,used with uboot-rj,--rootfs_jffs2 build rootfs for nand,used with uboot-U, --update gen update package update.bin,used with xboot-a, --all build all, include anything-h, --help display this help and exit
EOFexit 0;;*)echo "build.sh: Unrecognised option $1" >&2exit 1;;esacshift
donesetup_environment || exit 1if [ "${kernel}" = yes ]; thenbuild_kernel || exit 1
fiif [ "${xboot}" = yes ]; thenbuild_bootloader_xboot || exit 1
fiif [ "${uboot_inand}" = yes ]; thenbuild_bootloader_uboot_inand || exit 1
fiif [ "${uboot_nand}" = yes ]; thenbuild_bootloader_uboot_nand || exit 1
fiif [ "${rootfs}" = yes ]; thenbuild_rootfs || exit 1
fiif [ "${rootfs_ext3}" = yes ]; thengen_qt_rootfs_ext3 || exit 1
fiif [ "${rootfs_jffs2}" = yes ]; thengen_qt_rootfs_jffs2 || exit 1
fiif [ "${update}" = yes ]; thengen_qt_update_bin || exit 1
fiexit 0
2、mk文件的作用
mk脚本主要用来指导编译。BSP可以完整编译,也可以通过参数来指定想要编译的内容。
命令 描述 mk -a 编译所有的bsp源代码 mk -x 只编译xboot mk -ui 只编译uboot针对inand版本开发板的源代码 mk -r 只编译buildroot,得到文件夹形式的rootfs mk -re 编译buildroot并且制作得到ext3格式的rootfs镜像 mk -rj 编译buildroot并且制作得到jffs2格式的rootfs镜像 mk -h 查看mk的帮助信息
2、如何选择性地编译
用一个函数来完成某块内容的编译。比如编译内核用build_kernel函数,编译inand版本的uboot用build_bootloader_uboot_inand。
然后用相应的一些变量来控制这个函数要不要被编译。比如uboot_inand变量=yes,则表示要编译inand版本的uboot,=no则表示不编译。
编译时通过“./mk -xxx”来传参时,这些传参会影响这些变量的值=yes或者=no。
如果直接./mk并不传参,则$1为空,这时候按照一套默认的配置来编译。
三、buildroot文件夹
1、buildroot的作用
buildroot是一个集成包,集成了制作交叉编译工具链、构建rootfs等功能。
之前的交叉编译工具链arm-linux-gcc,都是从soc官方直接拿来使用的,但官方的工具链从何而来?实际上交叉编译工具链都是由gcc配置编译生成的。
在构建根文件系统中介绍了从零开始构建根文件系统,但是步骤麻烦。使用buildroot可以很简便的得到一个做好的文件夹形式的根文件系统。
buildroot移植了kernel的make xxx_defconfig、make menuconfig的2步配置法。在buildroot的配置界面下完成配置,然后直接make,最终可以得到文件夹形式的rootfs。
2、buildroot的目录
├── arch: 存放CPU架构相关的配置脚本,如arm/mips/x86,这些CPU相关的配置,在制作工具链时,编译uboot和kernel时很关键. ├── board 存放了一些默认开发板的配置补丁之类的 ├── boot ├── CHANGES ├── Config.in ├── Config.in.legacy ├── configs: 放置开发板的一些配置参数. ├── COPYING ├── DEVELOPERS ├── dl: 存放下载的源代码及应用软件的压缩包. ├── docs: 存放相关的参考文档. ├── fs: 放各种文件系统的源代码. ├── linux: 存放着Linux kernel的自动构建脚本. ├── Makefile ├── Makefile.legacy ├── output: 是编译出来的输出文件夹. │ ├── build: 存放解压后的各种软件包编译完成后的现场. │ ├── host: 存放着制作好的编译工具链,如gcc、arm-linux-gcc等工具. │ ├── images: 存放着编译好的uboot.bin, zImage, rootfs等镜像文件,可烧写到板子里, 让linux系统跑起来. │ ├── staging │ └── target: 用来制作rootfs文件系统,里面放着Linux系统基本的目录结构,以及编译好的应用库和bin可执行文件. (buildroot根据用户配置把.ko .so .bin文件安装到对应的目录下去,根据用户的配置安装指定位置) ├── package:下面放着应用软件的配置文件,每个应用软件的配置文件有Config.in和soft_name.mk,其中soft_name.mk(这种其实就Makefile脚本的自动构建脚本)文件可以去下载应用软件的包。 ├── README ├── support ├── system └── toolchain
3、配置与编译过程
配置编译
(1)make x210_defconfig
root@ubuntu:/home/xjh/iot/embedded_basic/bsp/buildroot/configs# ls x210_defconfig //由这里可以知道是make x210_defconfigroot@ubuntu:/home/xjh/iot/embedded_basic/bsp/buildroot# ls arch CHANGES configs docs Makefile package system board Config.in COPYING fs Makefile.legacy S99qttest toolchain boot Config.in.legacy dl linux output support root@ubuntu:/home/xjh/iot/embedded_basic/bsp/buildroot# make x210_defconfig //省略部分内容 # # configuration written to /home/xjh/iot/embedded_basic/bsp/buildroot/.config # root@ubuntu:/home/xjh/iot/embedded_basic/bsp/buildroot#
(2)make menuconfig
因为移植的时候已经配置好了,这个步骤可以省略。
(3)make
编译出错
直接make会遇到很多错误,这些错误原因都是因为ubuntu中缺乏一些必要软件包造成的。
解决方案是先安装这些必要的软件包。
编译过程会需要从网上下载一些软件包,因此整个编译过程需要在联网状态下进行。
You must install 'bison' on your build machine //sudo apt-get bisonYou must install 'flex' on your build machine //sudo apt-get flexYou must install 'makeinfo' on your build machine makeinfo is usually part of the texinfo package in your distribution //sudo apt-get install makeinfo //sudo apt-get install texinfoYou must install 'git' on your build machine //sudo apt-get install gitYou must install 'hg' on your build machine //sudo apt-get install hg E: 无法定位软件包 hg //sudo apt-get install hgsubversion //这个是由“apt-cache search hg”查询得知的You need the 'mkpasswd' utility to set the root password (in Debian/ubuntu, 'mkpasswd' provided by the whois package) //sudo apt-get install whois
编译结果
编译生成的文件夹格式的rootfs,位于buildroot/output/images/rootfs.tar。