整理Buildroot笔记,包含配置选项注释、目录结构分析、常用命令、构建示例、 使用技巧。
1.Buildroot基本介绍
Buildroot是Linux平台上一个构建嵌入式Linux系统的框架。
整个Buildroot是由Makefile(*.mk)脚本和Kconfig(Config.in)配置文件构成的,因此可以像配置Linux内核一样执行make menuconfig
进行配置,编译出一个完整的、可以直接烧写到机器上运行的Linux系统文件(包含bootloader、kernel、rootfs以及rootfs中的各种库和应用程序)。
回想构建开源软件包的流程,工作流大致如下:
- 获取:获取源代码
- 解压:解压源代码
- 补丁:针对缺陷修复和增加的功能应用补丁
- 配置:根据环境准备构建过程
- 安装:复制二进制和辅助文件到它们的目标目录
- 打包:为在其它系统上安装而打包二进制和辅助文件
可以看到构建每个软件包的工作流几乎是相同的,Buildroot主要就是把这些重复操作自动化,用户只需勾选上所需软件包,便自动完成以上所有操作。
其次,U-boot、Linux Kernel的编译工作流的差不多,只是配置的自定义参数更多,在Buildroot设置好了,也就一并生成。
2.Buildroot配置选项
以Buildroot 2019.02.4
,imx6ull
配置为例,对配置选项进行注释。
执行make menuconfig
进入一级配置菜单:
|
|
后面将依次对每个子菜单进行注释。约定()
内为直接翻译或补充说明,[]
内为示例选项含义。
2.1 Target options(目标选项)
|
|
①:ABI是X86计算机上的,EABI是嵌入式平台上; EABI/EABIhf分别适用于armel和armhf两个不同的架构,armel和armh在对待浮点运算采取了不同的策略(有fpu的arm才能选择EABIhf);
②:ARM浮点体系结构(VFP),VFPvX为历史各版本,比如浮点运算指定为VFP4(vector floating point4)指令或neon向量浮点指令;
2.2 Build options(编译选项)
|
|
2.3 Toolchain(工具链)
|
|
①:受限每行字数,该处完整链接为:https://releases.linaro.org/components/toolchain/binaries/6.2-2016.11/arm-linux-gnueabihf/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf.tar.xz
;
②:可选的有uClibc/uClibc-ng
、glibc/eglibc
、musl (experimental)
,介绍如下:
glibc(GNU C Library)
:常用于桌面、服务器中的GNU/Linux类系统中的C语言标准库,支持多种系统平台,功能齐全,但也相对比较臃肿和庞大;eglibc(Embedded glibc)
:glibc的一种变体,目的在于将glibc用于嵌入式系统;uClibc/uClibc-ng
:uClibc-ng是uClibc的分支,它们都是为嵌入式设计的小型的C语言标准库,适合标准和无MMU的Linux系统上运行;musl
:一个轻量级的C标准库,目前在buildroot里是实验阶段;
对比参考:Comparison of C/POSIX standard library implementations for Linux
③:堆栈粉碎保护(Stack Smashing Protection);
④:远程过程调用(Remote Procedure Call),主要用于NFS;
2.4 System configuration(系统配置)
|
|
①:可选选项有BusyBox
、systemV
、systemd
、None
:
BusyBox init
:
1.不支持运行等级,设置的运行等级将被忽略,要使用运行等级,请使用sysvinit;
2.语法格式:<id>:<runlevels>:<action>:<process>
<id>
:process执行所在的tty设备,内容为/dev目录中tty设备的文件名;<runlevels>
:此字段完全被忽略;<action>
:支持sysinit、respawn、askfirst、wait、once、restart、ctrlaltdel、shutdown;<process>
:指定要执行的进程及其命令行;
3.BusyBox init程序将在启动时读取/etc/inittab
文件,以了解该做什么,默认inittab存储在./package/busybox/inittab
;
4.inittab除了安装几个重要的文件系统之外,还要启动/etc/init.d/rcS
中的shell脚本,并启动一个getty程序(提供一个登录提示);systemV
:
1.使用传统sysvinit程序,之前大多数台式机Linux发行版都使用该方案,现在有些变为了Upstart或Systemd;
2.在/ect目录下会生成init.d、rc0.d、rc1.d、rc2.d、rc3.d、rc4.d、rc5.d、rc6.d、rc.loacl;
init.d里面包含的是真正的服务脚本;
rcN.d里面是链接向init.d里脚本的软链接,N表示运行级别,进入哪个运行级别,就会执行对应rcN.d文件夹的脚本;
当所有的当前运行级别的脚本都运行完了之后,会运行rc.local;
3.脚本的命名规则:以[S|K]+NN+其它
,以S开头的是启动脚本,以K开头的是停止脚本,init进程会按照S或者K后面的数字的顺序来启动或停止服务;
4.sysvinit还使用/etc/inittab
文件(与BusyBox的语法略有不同),默认inittab存储在./package/sysvinit/inittab
;systemd
:
1.systemd是Linux的新一代init系统,以前的运行级别(runlevel)的概念被新的运行目标(target)所取代;
2.支持并行化任务;采用socket式与D-Bus总线式激活服务;按需启动守护进程(daemon);支持快照和系统恢复;
3.功能强大的同时,也带来了相当大数量的大型依赖:dbus,udev等;
Systemd 的简介和特点
②:/dev设备文件的管理方式,可选选项有四个:
Static using device table
: 使用静态的设备表,/dev将根据system/device_table _dev.txt
的内容创建设备,进入系统添加或删除设备时,无法自动更新;Dynamic using devtmpfs only
:在系统启动过程中,会动态生成/dev文件,进入系统添加或删除设备时,无法自动更新;Dynamic using devtmpfs + mdev
:在前面devtmpfs的基础上加入mdev用户空间实用程序,进入系统添加或删除设备时,可以自动更新,自动创建规则在/etc/mdev.conf
;Dynamic using devtmpfs + eudev
:在前面devtmpfs的基础上加入eudev用户空间守护程序,eudev是udev的独立版本,是Systemd的一部分,提供更多的功能也更占用资源;
③:在Linux下编写shell脚本文件时,经常会看到在第一行中标注#!/bin/bash
,这句话的意思是告诉系统强制用bash,避免出现一些不兼容的问题。因此,除了bash外,还有很多shell工具,比如这里可选busybox自带的shell、小巧但功能很少的dash、高效紧凑的mksh、功能强大体积也稍大的zsh。此外,可以通过ls -l /bin/sh
查看当前使用的是何种shell工具。
④:受限每行字数,该处完整路径为board/freescale/common/imx/post-image.sh
。
这里是如何产生sdcard.img,用于sd卡启动的原理部分。
针对我现在imx6ull的情况,board/freescale/common/imx
目录下有两个文件值得关注:genimage.cfg.template
和post-image.sh
。
先来看genimage.cfg.template
:
|
|
该配置文件显示会生成两个文件,一个boot.vfat
,一个sdcard.img
;boot.vfat
由"%FILES%"
所表示内容组成(后面会得知是kernel+dtb);sdcard.img
有四个分区,第一个是空,第二个是偏移1024字节(1k)后,内容为"%UBOOTBIN%"
(u-boot),第三个为偏移8M后,存放前面生成的boot.vfat
(kernel+dtb),最后存放rootfs.ext2
。
此时分区情况如下:
分区类型和数值的对应关系可通过该文章查询:List of partition identifiers for PCs or Listing of MBR/EBR Partition Types
此时将sd卡插入Windows电脑,可以发现只能识别存放boot.vfa
t(kernel+dtb)的分区,因为该分区为FAT32格式,Windows可以识别,而存放rootfs.ext2
的分区为ext2/3/4,Windows是无法识别的,与生活常识是吻合的。
另外,如果想在SD卡创建其它自定义分区,可以再加一个partition:
|
|
再来看看post-image.sh
是如何解析genimage.cfg.template
:
|
|
可以在main
看到,FILES
为dtb和kernel,UBOOTBIN
为u-boot,再传入配置文件。
最后使用genimage
生成,genimage
在后面2.9Host utilities(主机工具)
部分需要勾选上,它的作用是给定根文件系统树,生成多个文件系统和闪存镜像的工具。
2.5 Kernel(内核配置)
|
|
①:受限每行字数,该处完整链接为https://git.dev.tencent.com/weidongshan/imx6ull_kernel.git
;
②:分别介绍下这几个内核镜像格式,以及一些其它格式:
vmlinuz·
:静态编译出来的最原始的ELF文件,包括了内核镜像、调试信息、符号表等内容;其中 “vm” 代表 “Virtual Memory”;Image
:将所有的符号和重定位信息都删除,只剩下二进制数据的内核代码,此时还没经过压缩;zImage
:是vmlinux加上解压代码(用于自解压)经过gzip压缩后的文件,适用于小内核,常见于ARM;bzImage
:是vmlinux加上解压代码(用于自解压)经过gzip压缩后的文件,适用于大内核,常见于x86,“bz”表示 “big zImage”;uImage
:是U-Boot专用的镜像文件,使用mkimage工具在zImage之前加上一个长度为0x40的头信息(tag),在头信息内说明了该镜像文件的类型、加载位置、生成时间、大小等信息;
参考资料:linux内核镜像格式
③:使用新的ABI,弃用sysfs;
2.6 Target packages(目标包配置)
目标包配置内容有点多,二级目录如下:
|
|
接下来对每个二级目录的子目录注释。
2.6.1 Audio and video applications
|
|
2.6.2 Compressors and decompressors
|
|
2.6.3 Debugging, profiling and benchmark
|
|
2.6.4 Development tools
|
|
2.6.5 Filesystem and flash utilities
|
|
2.6.6 Fonts, cursors, icons, sounds and themes
|
|
2.6.7 Games
|
|
2.6.8 Graphic libraries and applications (graphic/text)
|
|
2.6.9 Hardware handling
|
|
2.6.10 Interpreter languages and scripting
|
|
2.6.11 Libraries(待完善)
|
|
2.6.12 Mail
|
|
2.6.13 Miscellaneous
|
|
2.6.14 Networking applications (待完善)
|
|
2.6.15 Package managers
|
|
2.6.16 Real-Time
|
|
2.6.17 Security
|
|
2.6.18 Shell and utilities
|
|
2.6.19 System tools
|
|
2.6.20 Text editors and viewers
|
|
2.7 Filesystem images(文件系统)
|
|
借此机会,把几个文件系统给记录一下。
1.什么是文件系统
文件系统,就是文件的储存方式。简单说,它就是一个门牌系统,为储存设备划分门牌号,每个文件分配一个门牌,然后就能按照门牌找到文件。
没有文件系统的硬盘,就是一块荒地。如果有人住在那里,你只能说那里有人住,精确位置你说不出来。只有划分了路牌,你才能说出,这个人住在”人民路15号”,这样才能精确定位。文件系统就是路牌的划分方法。
储存设备都需要指定文件系统,计算机才能读写。所谓”格式化”,就是为硬盘安装文件系统。不同的操作系统有不同的文件系统,Linux使用ext4,OSX使用HFS+,Windows使用NTFS,Solaris和Unix使用ZFS。如果计算机不认识某个文件系统,就会显示这块盘无法读写。
2.Windows的文件系统
Windows里的文件系统主要有三种:FAT32、NTFS、exFAT。
FAT32是最老的文件系统,所有操作系统都支持,兼容性最好。但是,它是为32位计算机设计的,单个文件不能超过2的(32-1)次方个字节,也就是不能超过4GB,分区不能超过8TB。也就是为什么一些U盘无法一次性拷贝4G以上的大文件;
NTFS是Windows的默认文件系统,用来替换FAT32,Windows的系统盘只能使用这个文件系统;
exFAT可以看作是FAT32的64位升级版,ex就是extended的缩写,表示”扩展的FAT32”,功能不如NTFS,但是解决了文件和分区的大小问题,最大分区可以到8PB;
3.分区表
硬盘分区,是指一块硬盘上面,同时存在多个文件系统。
每个文件系统管理的区域,就称为一个分区(partition),比如一块100GB的硬盘,可以一半是NTFS分区,另一半是exFAT分区。
硬盘必须先分区,才能指定每个区的文件系统。分区大小、起始位置、结束位置、文件系统等信息,都储存在分区表里面。
分区表也分成两种所谓硬盘分区,就是指一块硬盘上面,同时存在多个文件系统。每个文件系统管理的区域,就称为一个分区(partition)。比如,一块 100 GB 的硬盘,可以一半是 NTFS 分区,另一半是 exFAT 分区。
硬盘必须先分区,才能指定每个区的文件系统。分区大小、起始位置、结束位置、文件系统等信息,都储存在分区表里面。
分区表也分成两种格式:MBR 和 GPT。前者是传统格式,兼容性好;后者更现代,功能更强大。一般来说,都推荐使用 GPT格式:MBR和GPT。前者是传统格式,兼容性好;后者更现代,功能更强大。一般来说,都推荐使用GPT。
4.buildroot中提到的几种文件系统
- xfs:XFS最早针对IRIX操作系统开发,是一个高性能的日志型文件系统,能够在断电以及操作系统崩溃的情况下保证文件系统数据的一致性。它是一个64位的文件系统,后来进行开源并且移植到了Linux操作系统中。XFS引入分配组、B+树、extent等方法来改进海量高并发小文件场景下性能。
- btrfs:通常念成Butter FS,Better FS或B-treeFS,由Oracle于2007年宣布并进行中的COW(copy-on-write式)文件系统。继ext3/4文件系统之后,比较强大的Linux文件系统,具有快照,内建磁盘阵列(RAID)支持,支持子卷等功能,允许在线调整文件系统大小。
- cramfs:一个压缩式的文件系统,它并不需要一次性地将文件系统中的所有内容都解压缩到内存之中,而只是在系统需要访问某个位置的数据的时侯,马上计算出该数据在cramfs中的位置,将其实时地解压缩到内存之中,然后通过对内存的访问来获取文件系统中需要读取的数据。
- romfs:一种简单的只读文件系统,主要是用来当做初始文件系统来使用的,在嵌入式linux或是uclinux中通常使用这中文件系统来作为引导系统的文件系统,甚至uclinux有时就直接把ROMFS作为其根文件系统,而不是将其作为系统启动中的过渡文件系统。
- squashfs:一个只读的文件系统,它可以将整个文件系统压缩在一起,存放在某个设备,某个分区或者普通的文件中。如果将其压缩到一个设备中,那么可以将其直接mount起来使用,而如果它仅仅是个文件的话,您可以将其当为一个loopback设备使用。
- f2fs:Flash-Friendly File System是一种闪存文件系统,主要由三星集团研发,适合Linux内核使用。此文件系统起初是为了NAND闪存的存储设备设计(诸如固态硬盘、eMMC和SD卡),这些设备广泛存在于自移动设备至服务器领域。
- jffs2:磁盘文件系统(ext2, FAT)设计运行在磁盘上,在运行在闪存上时,需要闪存转换层(Flash Translation Layer), 它的功能就是将底层的闪存模拟成一个具有512字节扇区大小的标准块设备(block device),从而模仿磁盘。这势必带来写操作性能的下降,更好的解决问题的方法就是实现一个特别针对闪存的文件系统,而JFFS2就是一个这样的文件系统。
- yaffs2:Yet Another Flash File System,是一种类似于JFFS/JFFS2的专门为Flash设计的嵌入式文件系统。与JFFS相比,它减少了一些功能, 因此速度更快、占用内存更少。
- ubifs:无序区块映像文件系统(Unsorted Block Image File System),一种用于固态硬盘存储设备的文件系统,它与LogFS相互竞争,是JFFS2的后继文件系统之一。UBIFS在设计与性能上均较YAFFS2、JFFS2更适合大容量的NAND flash。
5.其它提到名词解释
- cloop:cloop是一个Linux内核模块,支持压缩回环文件系统。有了它,您可以安装压缩文件系统,如块设备,并在访问时无缝解压缩其数据。
- cpio:cpio是一个非常古老的归档工具。已逐渐被tar替代,但是有些功能是tar不存在的。
参考资料:
exFAT 文件系统指南
如何选择文件系统:EXT4、Btrfs 和 XFS
深入理解ext4等Linux文件系统
JFFS2 文件系统及新特性介绍 - IBM
UBI文件系统详细介绍
2.8 Bootloaders(引导程序)
|
|
①:受限每行字数,该处完整链接为:https://git.dev.tencent.com/weidongshan/imx6ull_uboot.git
;
2.9 Host utilities(主机工具)
|
|
2.10 Legacy config options(旧版配置选项)
一些陆续被移除buildroot的配置选项,忽略。
3.Buildroot目录结构
使用一个编译过imx6ull的buildroot,在此基础上分析目录结构。
执行dir -AFl --group-directories-first
可按先目录、后文件的顺序显示buildroot根目录的所有文件。
在分析目录内容之前,先简单了解下*.mk
和Config.in/Config.in.host
这两类文件,能加快后面分析、理解。Config.in/Config.in.host
:包含配置信息,即执行make menuconfig
,出现选项内容,Config.in
用于目标,Config.in.host
用于主机;*.mk
:根据前面的配置信息执行相应动作;
|
|
打开Config.in
,可以看到如下内容:
|
|
结合执行make menuconfi
显示的一级菜单,可以发现本Config.in
串联起了所有Config.in
,在用户配置完后,生成.config
,.*mk
就根据.config
的配置内容,进行对应的构建。
配置选项 | 文件路径 |
---|---|
Target options | arch/Config.in |
Build options | ./Config.in |
Toolchain | toolchain/Config.in |
System configuration | system/Config.in |
Kernel | linux/Config.in |
Target packages | package/Config.in |
Filesystem images | fs/Config.in |
Bootloaders | boot/Config.in |
Host utilities | package/Config.in.host |
Legacy config options | ./Config.in.legacy |
以上目录中,有几个需要详细说明下,下面开始分析。
3.1 board目录
在The Buildroot user manual
的9.1. Recommended directory structure
章节,有该目录的推荐结构。
根据手册内容,在该目录下创建自定义文件。
①:在board/
目录下新建hceng/
(自定义公司名),再在hceng/
下创建imx6ull/
(单板名);
②:在imx6ull/
下,应存放uboot、linux、busybox等的配置文件,在分别设置好BR2_TARGET_UBOOT_CUSTOM_CONFIG_FILE
、BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE
、BR2_PACKAGE_BUSYBOX_CONFIG
后,如果修改了配置,分别执行make uboot-update-defconfig
、make linux-update-defconfig
、make busybox-update-config
可以更新该目录下的配置文件。这里的uboot、linux是通过git下载,选择的自带的配置文件,BR2_TARGET_UBOOT_CUSTOM_CONFIG_FILE
、BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE
也就没有指定,因此没采用把配置文件放在该目录的方法。busybox使用默认配置文件路径package/busybox/busybox.config
,也没有移动处理。
③:除配置文件,还应放sd卡制作脚本等,参考board/freescale/common/imx/
和board/freescale/imx6ulevk/
目录,将前面提到用于sd卡制作的genimage.cfg.template
和post-image.sh
复制到本目录下;最后,在System configuration
->Custom scripts to run after creating filesystem images
设置脚本路径board/hceng/imx6ull/post-image.sh
;
④:除了配置文件、sd卡制作脚本,该目录还要存放根文件系统覆盖文件,新建目录rootfs_overlay/
,里面可以创建/etc/init.d/S01xx
,用于放置开机启动脚本。最后,在System configuration
->Root filesystem overlay directories
设置覆盖文件路径board/hceng/imx6ull/rootfs_overlay
;
⑤:除此之外,还可以放各类patches/
补丁文件,并在配置文件指定路径;
可以看出,board/
就是存放某个具体单板紧密相关的文件,比如内核配置文件、sd卡制作脚本、rootfs覆盖文件等,设置后的目录结构如下:
|
|
3.2 output目录
output
目录下有以下几个目录:build
:存放着解压后的各种软件包编译完后的现场;graphs
:执行make graph-build
等命令后,生成的相关图形化文档;host
:制作好的交叉编译工具链;images
:各种最终生成的镜像;staging
:包含了根文件系统的层次结构,编译生成的所有头文件和库,以及其他开发文件,体积较大;target
:已经rootfs_overlay/
处理过的根文件系统,但没有创建/dev/
下的设备节点;
3.3 package目录
package
目录是存放所有软件包构建脚本*.mk、配置选项Config.in的目录,这里添加一个自定义APP,来理解实现原理。
①:在package/
目录下,创建一个hceng_app
目录;
②:在hceng_app/
目录下,创建文件Config.in
和hceng_app.mk
,注意*.mk
的文件名不能乱取,只能是app名字,且为小写;Config.in
的内容如下:
|
|
这里的配置变量BR2_PACKAGE_HCENG_APP
不能乱取,只能是BR2_PACKAGE_
+APP
名字大写;
bool是变量的类型,选中为ture编译,不选中为false不编译,与Linux Kernel的Kconfig文件规则是一样的;
help是在配置界面,按下h
出现的帮助提示信息;
hceng_app.mk
的内容如下:
|
|
需要注意的几点:
Ⅰ.严格按照示例的格式,1-5行的样式不能省略,第3行为app名字;
Ⅱ.7-8行和11-13行,为获取app的两种方式,二选一即可。7-8行是本地获取,需要提前将app文件放在HCENG_APP_SITE
指定的路径,这里为dl/hceng_app
;11-13行是git获取,需要提前将app文件放到git仓库,注意HCENG_APP_SITE
的格式,它会调用package/pkg-download.mk
,三个参数依次为用户名、包名、版本号;
Ⅲ.HCENG_APP_BUILD_CMDS
是构建过程,给应用源码的Makefile传递编译、链接参数,并调用应用源码的Makefile执行;
Ⅳ.HCENG_APP_INSTALL_TARGET_CMDS
是编译完成后,自动安装到指定目录;
③:在package/Config.ini
中添加:
|
|
新创建了一个菜单Private package
,显示的配置文件为前面创建的package/hceng_app/Config.in
;
④:创建app程序和Makefile
APP参考:
|
|
Makefile参考:
|
|
根据自己需求,将这两个文件放在本地(hceng_app.mk指定的路径)或者git仓库。
⑤:编译
执行make menuconfig
,勾选上自定义APPTarget packages ---> Private package ---> [*] hceng_app
;
然后执行make hceng_app
或make all
,将编译和安装自定义APP,可以在output/target/usr/bin/
下看到安装的自定义APP,最后重新烧写系统,即可使用自定义APP。
4.buildroot常用命令
在buildroot根目录执行make help
,即可获得buildroot常用命令的提示信息,内容如下:
|
|
5.构建示例
5.1准备buildroot
以stm32mp157为例(ST首款运行Linux的处理器),展示如何使用buildroot来构建系统的思路。
开发板使用的是米尔科技生产的MYC-YA157C。
在开始之前,思考从哪里获取支持MYC-YA157C的buildroot。
①.开发板厂家提供
购买了某个开发板厂家的开发板,看其提供的资料有没有buildroot,如果有,请无脑直接使用开发板厂家的,能够为你剩下一大堆时间去做其它的。
如果开发板厂家没有提供,比如米尔提供的是Yocto构建系统,目前没有buildroot,继续参考下面的方法。
②.buildroot官网
如果使用的是芯片原厂的公版/比较火的开发板,很可能buildroot有原生支持。
但buildroot不可能对某个开发板一直维护,因此每个开发板都有生命周期,比如firefly-rk3288开发板,在2016.02加入buildroot,2018.03被移除不再维护,因此我们如果要使用现成的配置文件,就得下载2016.02至2018.03这个时间段之间的buildroot。
可以通过查询buildroot的log msg来获取这些变化信息。
我手里这款目前来看,buildroot原生支持没戏。
③.Github搜索
作为全球最大的“同性交友”网站,可以去搜搜板子名字,看是否有类似的buildroot仓库,有的话clone下来验证试试。
我手里这款还没批量开卖,Github自然没有。
找了一圈,目前应该没有直接支持MYC-YA157C的buildroot,因此需要自己尝试添加该开发板。
添加开发板也不是从头开始添加,先尝试找找类似的板子,节约配置时间。
在GitHub上,找到一个支持stm32mp157的仓库,在buildroot官网的log msg也搜到了在2019.08添加了stm32mp157_dk
的配置文件(STM32MP157C-DK是STM32的原厂公板),到目前也没被移除。
这里准备在官方最新buildroot,添加MYC-YA157C单板。
5.2准备交叉编译工具链、U-boot、Linux Kernel
①.交叉编译工具链
可以使用开发板厂家提供资料的交叉编译工具链,也可以尝试使用stm32mp157_dk
的配置文件所使用的交叉编译工具链。
②.U-boot、Linux Kernel
建议直接使用开发板厂家所提供U-boot、Linux Kernel。
如果主线U-boot、Linux Kernel有对MYC-YA157C的原生支持,或者知道MYC-YA157C和STM32MP157C-DK2公版的差异且能移植,才考虑用其它的U-boot、Linux Kernel。
本文主要是分析buildroot,对U-boot、Linux Kernel的移植不深究,因此这里直接使用开发板厂家所提供U-boot、Linux Kernel。
找到开发板厂家所提供U-boot,创建个uboot-stm32mp
目录,将U-boot源码放在里面,压缩为uboot-stm32mp.tar.gz
,同时,根据提供的文档,得知U-boot配置文件为stm32mp15_basic_defconfig
。
同理,对提供的Linux Kernel进行类似操作,得到linux-stm32mp.tar.gz
,得知内核配置文件为multi_v7_defconfig
,设备树文件为stm32mp157c-myir.dts
。
注意,源码解压出来一定要有个总文件夹包含源码,不能解压后当前目录就是源码,不然后面buildroot使用时会出错。
5.3设置buildroot
①.下载官方buildroot,使用公板配置文件
获取主线buildroot:
|
|
查询公板的配置文件:
|
|
使用公板的配置文件:
|
|
②.按需修改配置
执行make menuconfig
进入配置界面,挨个进行修改。
Target options --->
和CPU紧密相关,这里和公板使用的同一CPU,这里就不需要修改。Build options --->
修改新配置文件保存路径和名字:12原:(/work/buildroot/configs/stm32mp157_dk_defconfig)) Location to save buildroot config新:(/work/buildroot/configs/stm32mp157_myir_defconfig)) Location to save buildroot configToolchain --->
交叉编译工具链可以考虑是开发板厂家提供的,这里先暂时使用公板配置文件的,后面编译如果出了问题再回来修改。System configuration --->
设置根文件系统目录要覆盖/添加的文件路径:12原:(board/stmicroelectronics/stm32mp157-dk/overlay/)) Root filesystem overlay directories新:(board/stmicroelectronics/stm32mp157-myir/overlay/)) Root filesystem overlay directories
注:配置中出现的新目录/文件,后面统一再创建。
设置制作SD卡启动的脚本配置信息路径:
|
|
Kernel --->
内核的来源可以有多种,比如从kernel官网自动下载,从自定义github仓库下载,或者使用本地内核包。
这里选择本地包的方式,以及设置对应的内核配置文件:1234567891011原: Kernel version (Custom tarball) --->($(call github,STMicroelectronics,linux,v4.19-stm32mp-r1.5)/linux-v4.19-stm32mp-r1.5.tar) URL of custom kernel tarball() Custom kernel patchesKernel configuration (Using a custom (def)config file) --->(board/stmicroelectronics/stm32mp157-dk/linux.config) Configuration file path新: Kernel version (Custom tarball) --->(dl/linux/linux-stm32mp.tar.gz)/linux-v4.19-stm32mp-r1.5.tar() Custom kernel patchesKernel configuration (Using an in-tree defconfig file) --->(multi_v7) Defconfig name
以及选择对应设备树文件:
|
|
Target packages --->
软件包根据需求添加,这里保持默认即可。Filesystem images --->
根文件系统看了下,也没啥需要特殊修改的,保持默认。Bootloaders --->
U-boot也是有多种来源方式,这里选择本地包的方式:123456789101112原: U-Boot Version (Custom version) --->($(call github,STMicroelectronics,u-boot,v4.19-stm32mp-r1.5)/linux-v4.19-stm32mp-r1.5.tar.gz) URL of custom kernel tarball() Custom U-Boot patchesU-Boot configuration (Using an in-tree board defconfig file) --->(stm32mp15_basic) Board defconfig(board/stmicroelectronics/stm32mp157-dk/uboot-fragment.config) Additional configuration fragment files新: U-Boot Version (Custom tarball) --->(dl/uboot/uboot-stm32mp.tar.gz) URL of custom U-Boot tarball() Custom U-Boot patchesU-Boot configuration (Using an in-tree board defconfig file) --->(stm32mp15_basic) Board defconfig() Additional configuration fragment filesHost utilities --->
一般保持默认,编译过程中遇到主机缺什么,再来勾选上。
Legacy config options
不用看。
最后,保存,退出,执行make savedefconfig
将会生成configs/stm32mp157_myir_defconfig
。
使用公板的配置文件后,很多配置就可以默认即可,主要关注的是Toolchain
、Kernel
、Bootloaders
。
③.为配置准备文件
前面对配置做了一系列修改,新增了不少目录和文件,接下来要依次添加。
- 准备board目录的单板紧密相关的文件
参考stm32mp157-dk/
目录,生成自己板子目录:1cp board/stmicroelectronics/stm32mp157-dk/ board/stmicroelectronics/stm32mp157-myir/ -r
修改overlay/boot/extlinux/extlinux.conf
:
|
|
在生成根文件系统时,board/stmicroelectronics/stm32mp157-myir/overlay/boot/extlinux/extlinux.conf
将会添加到根文件系统的/boot/extlinux/
下,U-boot在启动内核前,会读取extlinux.conf
文件,得知内核、设备树所在路径。
- 准备U-boot和Linux Kernel12345mkdir dl/uboot/cp uboot-stm32mp.tar.gz dl/uboot/mkdir dl/linux/cp linux-stm32mp.tar.gz dl/linux/
5.4 编译、烧写
执行make all
,编译完后,将在output/images/
生成以下文件:
|
|
随后将SD卡接入Linux主机,将sdcard.img
写入SD卡(/dev/sdb):
|
|
写入完成后,将SD卡插入板子上,启动开关选择SD卡启动,上电即可看到打印输出:
6.使用技巧
- ①.添加启动脚本
很多时候,需要系统启动后自动运行一些程序,这就需要添加启动脚本。
在前面的board/stmicroelectronics/stm32mp157-myir/
下有个overlay
目录,就是切入点。
可以利用overlay
会覆盖根文件系统相关目录的特性,加上初始化系统方案采用systemV
来实现。
在overlay
里创建个etc/init.d
目录,再在目录里创建S35app
之类的文件,开机后即会自动运行该脚本。
- ②.调整根文件系统大小
在前面示例里,Filesystem images ---> (120M) exact size
,即根文件系统空间设置的120MB,使用一个8G的SD卡烧写后启动,执行df -h
看到整个根文件系统也只是120MB,无法扩展。
如果改为Filesystem images ---> (4096M) exact size
,生成的sdcard.img文件也将是4G,烧写会非常的慢。
一个可行的方案:
设置exact size
任然为120MB,修改board/stmicroelectronics/stm32mp157-myir/genimage.cfg
,将rootfs
分区的size
改为4096M
。
这样生成的sdcard.img文件大小不会变太大,进入系统后,执行resize2fs /dev/mmcblk0p4
(rootfs在SD卡第4分区),即可看到系统空间变为了4G。
再将resize2fs /dev/mmcblk0p4
命令添加到启动脚本里,通过一定的判断,在首次进入系统时执行扩容即可。
另外,如果提示没有resize2fs
命令,在Target packages --->Filesystem and flash utilities --->[*] e2fsprogs --->[*] resize2fs
勾选上即可。
資料來源: https://hceng.cn/2019/09/05/Buildroot%E7%AC%94%E8%AE%B0/
沒有留言:
張貼留言