正点原子嵌入式linux驱动开发——Buildroot根文件系统构建

上一小节学习了如何使用busybox来构建根文件系统,但是busybox构建的根文件系统不齐全,很多东西需要自行添加,比如lib库文件。在后面的驱动开发中很多第三方软件也需要自己去移植,这些第三方软件有很多又依赖其他的库文件,导致移植过程非常的繁琐。本章来学习一下另外一种更加实用的根文件系统构建方法,那就是使用buildroot来构建根文件系统

buildroot简介

buildroot简介

在上一篇笔记讲解了如何使用busybox构建文件系统,busybox仅仅只是构建好了一些常用的命令和文件,像lib库、/etc目录下的一些文件都需要自己手动创建,而且busybox构建的根文件系统默认没有用户名和密码设置。在后续的实验中,还要自己去移植一些第三方软件和库,比如alsa、iperf、mplayer等等。那么有没有一种傻瓜式的方法或软件,它不仅包含了busybox的功能,而且里面还集成了各种软件,需要什么软件就选择什么软件,不需要自己去移植。buildroot就是这样一种工具, buildroot比busybox更上一层楼,buildroot不仅集成了busybox,而且还集成了各种常见的第三方库和软件,需要什么就选择什么。buildroot极大的方便了嵌入式Linux开发人员构建实用的根文件系统

从busybox开始一步一步的构建根文件系统适合学习、了解根文件系统的组成,但是不适合做产品(主要是自己构建的话会有很多不完善、没有注意到的细节)。buildroot会处理好各种细节,根文件系统也会更加的合理、有效。因此在做产品的时候推荐使用buildroot来构建自己的根文件系统,当然了,类似buildroot的软件还有很多,比如yocto,一般半导体厂商会选择yocto来制作系统包,但是由于国内的网络环境,yocto编译起来会有很多问题!

buildroot和uboot、kernel很类似,需要到其官网上下载源码,然后对其进行配置,比如设置交叉编译器、设置目标CPU参数等,最主要的就是选择所需要的第三方库或软件。一切配置好以后就可以进行编译,编译完成了以后就会在一个文件夹里面存放好编译结果,也就是根文件系统。

注意!buildroot制作的根文件系统也是放到ubuntu的nfs目录下的rootfs文件夹,因此如果rootfs文件夹已经存放了前面busybox制作的根文件系统,那么请大家对其做一份备份,然后清空rootfs文件夹。

buildroot下载

buildroot源码肯定是要从buildroot官网下载,官网地址为buildroot官网链接,打开以后的官网界面如下图所示:
正点原子嵌入式linux驱动开发——Buildroot根文件系统构建_第1张图片
点击上图中的“DOWNLOAD”按钮即可打开buildroot的下载界面,如下图所示:
正点原子嵌入式linux驱动开发——Buildroot根文件系统构建_第2张图片
可以看出,正点原子教程中最新的LTS(长期支持版)版buildroot为2020.02.8,分为.gz和.bz2两种压缩格式,这里就使用右侧的.bz2压缩格式的源码,选中以后下载即可。但是教程中测试使用2020.02.6版本的,就用这个版本就行。开发光盘中是提供这个源码的,就是buildroot-2020.02.6.tar.bz2,一切准备好以后就可以使用buildroot构建根文件系统了。

buildroot构建根文件系统

配置buildroot

将buildroot源码buildroot-2020.02.6.tar.bz2拷贝到ubuntu中,拷贝完成以后对其进行解压,命令如下:

tar -vxjf buildroot-2020.02.6.tar.bz2

解压完成以后就会得到一个名为“buildroot-2020.02.6”的目录,此目录就是解压得到
的buildroot源码。

buildroot和uboot、Linux kernel一样也支持图形化配置,输入如下命令即可打开图形化配置界面:

make menuconfig

打开后的图形化配置界面如下图所示:
正点原子嵌入式linux驱动开发——Buildroot根文件系统构建_第3张图片
接下来就开始配置buildroot。

配置Target options

首先配置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

配置完成后如下图所示:
正点原子嵌入式linux驱动开发——Buildroot根文件系统构建_第4张图片

配置Toolchain

此配置项用于配置交叉编译工具链,也就是交叉编译器,这里设置为自己所使用的交叉编译器即可。buildroot其实是可以自动下载交叉编译器的,但是都是从国外服务器下载的,鉴于国内的网络环境,强烈推荐设置成自己所使用的交叉编译器。需要配置的项目和其对应的内容如下:

Toolchain
-> Toolchain type = External toolchain
-> Toolchain = Custom toolchain //用户自己的交叉编译器
-> Toolchain origin = Pre-installed toolchain //预装的编译器
-> Toolchain path = /usr/local/arm/gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf
-> Toolchain prefix = $(ARCH) -none-linux-gnueabihf //前缀
-> External toolchain gcc version = 9.x
-> External toolchain kernel headers series = 4.20.x //交叉编译器 的 linux版本号
-> External toolchain C library = glibc/eglibc
-> [*] Toolchain has SSP support? (NEW) //选中
-> [*] Toolchain has RPC support? (NEW) //选中
-> [*] Toolchain has C++ support? //选中
-> [*] Enable MMU support (NEW) //选中

Toolchain下几个比较重要的选项需要说明一下,如下所示:

Toolchain:设置为Custom toolchain,表示使用用户自己的交叉编译器。

Toolchain origin:设置为Pre-installed toolchain,表示使用预装的交叉编译器。

Toolchain path:设置自己安装的交叉编译器绝对路径,buildroot要用到。

Toolchain prefix:设置交叉编译器前缀,要根据 自己实际所使用的交叉编译器来设置,比如这里使用的是arm-none-linux-gnueabihf-gcc,因此前缀就是$(ARCH)-none-linux-gnueabihf,其中ARCH前面已经设置为了arm。

External toolchain kernel headers series:这个设置的是交叉编译器所对应的linux内核版本号,gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf所对应的linux内核版本号为 4.20,因
此这里需要设置为4.20.x!一定要根据自己所使用的交叉编译器来设置,否则编译的时候会报版本不一致的错误。

配置System configuration

此选项用于设置一些系统配置,比如开发板名字、欢迎语、用户名、密码等。需要配置的项目和其对应的内容如下:

System configuration
-> System hostname = ATK-stm32mp1 //平台名字,自行设置
-> System banner = Welcome to alientek STM32MP157 //欢迎语
-> Init system = BusyBox //使用 busybox
-> /dev management = Dynamic using devtmpfs + mdev //使用 mdev
-> [*] Enable root login with password (NEW) //使能登录密码
-> Root password = 123456 //登录密码为 123456

在System configuration选项中可以配置平台名字,登录密码等信息。可以看出buildroot里面可以设置登录密码,但是作为实验,不建议设置登录密码,否则开发板每次重启都要输入密码,不方便开发。

配置Filesystem images

此选项配置最终制作的根文件系统为什么格式的,配置如下:

-> Filesystem images
-> [*] ext2/3/4 root filesystem //如果是 EMMC或 SD卡的话就用 ext3/ext4
-> ext2/3/4 variant = ext4 //选择 ext4格式
-> exact size =1G //ext4格式根文件系统 1GB(根据实际情况修改 )
-> [*] ubi image containing an ubifs root filesystem //如果使用 NAND的话就用 ubifs

可以看出,buildroot可以直接制作出ext4格式的根文件系统,但是一般会自行往根文件系统里面添加很多其他的文件,所以产品开发完成以后需要自行打包根文件系统,然后烧写到开发板里面。不管是针对EMMC的ext4格式的根文件系统还是针对NAND的ubi格式的根文件系统,都要设置相应的大小,比如这里设置的ex4格式根文件系统大小为 1GB。

禁止编译Linux内核和uboot

buildroot不仅仅能构建根文件系统,也可以编译linux内核和uboot。当配置buildroot,使能linux内核和uboot以后buildroot就会自动下载最新的linux内核和uboot源码并编译。但是一般都不会使用buildroot下载的linux内核和uboot,因为buildroot下载的linux和uboot官方源码,里面会缺少很多驱动文件,而且最新的linux内核和uboot会对编译器版本号有要求,可能导致编译失败。因此需要配置buildroot,关闭linux内核和uboot的编译,只使用buildroot来构建根文件系统,首先是禁止Linux内核的编译,配置如下:

-> Kernel
-> [ ] Linux Kernel //不要选择编译 Linux Kernel选项!

如下图所示:
正点原子嵌入式linux驱动开发——Buildroot根文件系统构建_第5张图片
接着禁止编译Uboot,配置如下:

-> Bootloaders
-> [ ] U-Boot //不要选择编译 U-Boot选项!

如下图所示:
正点原子嵌入式linux驱动开发——Buildroot根文件系统构建_第6张图片

配置Target packages

此选项用于配置要选择的第三方库或软件、比如alsa-utils、ffmpeg、iperf等工具,这里先只选择内核的模块加载相关软件,配置如下:

-> Target packages
-> System tools -> [*] kmod //使能内核模块相关命令

上面的配置是使能内核模块相关的操作命令,比如depmod等,如下图所示:
正点原子嵌入式linux驱动开发——Buildroot根文件系统构建_第7张图片
至于其他的第三方库这里就先不选择了,先编译一下最基本的根文件系统,如果没有问题的话再重新配置选择第三方库和软件。否则编译出问题的时候都不知道怎么找问题。

保存配置项

和uboot、Linux kernel一样,通过图形化界面配置好buildroot以后最好保存一下配置项,防止清除工程以后将配置项给删除掉。buildroot的默认配置项都保存在configs目录下,配置完成以后选择 ,然后输入要设置的配置项名字,如下图所示:
正点原子嵌入式linux驱动开发——Buildroot根文件系统构建_第8张图片
将配置项命名为“stm32mp1_atk_defconfig”,以后要重新配置buildroot的话就可以直接输入:

make stm32mp1_atk_defconfig

保存完成以后就会在buildroot的configs目录下看到“stm32mp1_atk_defconfig”,如下图所示:
保存好的buildroot配置文件

编译buildroot

配置完成以后就可以编译buildroot了,编译完成以后buildroot就会生成编译出来的根文件系统压缩包,可以直接使用。输入如下命令开始编译:

make -j8 //多线程编译

buildroot编译的时候会先从网上下载所需的软件源码,有些软件源码可能下载不下来,这个时候就需要自行处理,后面会详细的讲解。

buildroot编译过程会很耗时,因为所需要的所有软件要先从网上下载源码,很多软件都是从外网下载的,速度比较慢,在加上电脑配置的不同,整个编译过程可能需要几十分钟甚至数小时!

buildroot因为要从网上下载源码,因此可能存在有些源码无法下载或下载很慢的情况,比如下图所示:
正点原子嵌入式linux驱动开发——Buildroot根文件系统构建_第9张图片
可以看出上图中正在下载cmake-3.8.2.tar.gz这个压缩包,大小是7.2MB,当前下载网速是1.6KB/S,需要用时71分钟,显然这是无法忍受的!可以自行到cmake-3.8.2下载这个网站上去将cmake-3.8.2.tar.gz这个源码下载下来,然后拷贝到buildroot源码目录下的dl文件夹中 dl文件夹专用用于存放下载下来的源码。拷贝进去以后重新编译buildroot,此时就不会在从网上下载cmake-3.8.2.tar.gz了,而是自己使用dl目录下已经存在的cmake-3.8.2.tar.gz压缩包,加快编译度!

等待编译完成,编译完成以后就会在buildroot-2020.02.6/output/images下生成根文件系统,如下图所示:
编译生成的根文件系统
从上图可以看出,编译出来了多种格式的rootfs,比如ext2、ext4、ubi等。rootfs.ext4就是可以直接使用STM32CubeProgrammer烧写到开发板中的。但是后面的开发都是通过nfs挂载的方式,所以就使用rootfs.tar进行测试。将rootfs.tar拷贝到在nfs目录下的rootfs文件夹中并解压,命令如下:

cd /home/zuozhongkai/linux/tool/buildroot-2020.02.6/output/images
cp rootfs.tar /home/zuozhongkai/linux/nfs/rootfs/ -f //拷贝rootfs.tar
cd /home/zuozhongkai/linux/nfs/rootfs/ //进入到rootfs目录下
tar -vxf rootfs.tar //解压缩rootfs.tar
rm rootfs.tar //删除rootfs.tar

解压缩完成后的rootfs目录如下图所示:
使用buildroot编译出来的根文件系统
上图就是使用buildroot编译出来的根文件系统,可以通过nfs挂载到开发板上,然后对其进行测试。

buildroot根文件系统测试

buildroot制作出来的根文件系统已经准备好了,接下来就是对其进行测试。测试方法也是通过nfs挂载的方式,启动uboot,修改bootargs环境变量,设置nfsroot目录为Ubuntu中的rootfs目录,命令如下:

setenv bootargs console=ttySTM0,115200 root=/dev/nfs nfsroot=192.168.1.249:/home/zuozhongkai/linux/nfs/rootfs,proto=tcp rw ip=192.168.1.250:192.168.1.249:192.168.1.1:255.255.255.0::eth0:off''

设置好以后启动系统,进入根文件系统以后如下图所示:
正点原子嵌入式linux驱动开发——Buildroot根文件系统构建_第10张图片
在上图中,首先要进入到/lib/modules目录,但是默认没有,因此需要自行创建此目录。buildroot构建的根文件系统启动以后会输出前面设置的欢迎语“Welcome to alientek STM32MP157”。然后需要输入用户名和密码,用户名是“root”,如果配置 buildroot的时候设置了密码,那么就需要输入密码,这里没有设置密码,因此输入用户名就行了,如下图所示:
正点原子嵌入式linux驱动开发——Buildroot根文件系统构建_第11张图片
可以看出的buildroot构建的根文件系统运行基本没有问题,但是这个根文件系统是最简单的,并没有在buildroot里面配置任何第三方的库和软件,接下来就配置buildroot,使能一些常见的第三方软件。

buildroot下的busybox配置

busybox配置

buildroot在构建根文件系统的时候也是要用到busybox的,既然用到了busybox那么就涉及到busybox的配置。buildroot会自动下载busybox压缩包,buildroot下载的源码压缩包都存放在/dl目录下,在dl目录下就有一个叫做“busybox”的文件夹,此目录下保存着busybox压缩包。

可以看出,buildroot下载的 busybox版本为1.31.1。要想编译busybox,必须对压缩包进行解压缩,buildroot会对其进行解压!buildroot将所有解压缩后的软件保存在/output/build软件中,可以在找到/output/build/busybox-1.31.1这个文件夹,此文件夹就是解压后的busybox源码,文件内容如下图所示:
正点原子嵌入式linux驱动开发——Buildroot根文件系统构建_第12张图片
如果想要修改busybox源码的话就直接在上图中找到相应的文件,然后修改即可。现在是要配置buildroot下的busybox,因此肯定要打开busybox的配置界面,在buildroot源码根目录下输入如下命令:

make busybox-menuconfig

输入以后就会打开buildroot下的busybox配置界面,可以直接参考上一篇笔记的配置。

busybox中文字符支持

busybox对中文字符显示做了限制,因此必须要修改相关的文件,具体修改过程参考上一篇笔记即可,这里就不再赘述了。

编译busybox

配置好以后就可以重新编译buildroot下的busybox,进入到buildroot源码目录下,输入如
下命令查看当前buildroot所有配置了的目标软件包,也就是packages:

make show-targets

结果如下图所示:
正点原子嵌入式linux驱动开发——Buildroot根文件系统构建_第13张图片
上图中列出了当前buildroot中所有使能了的packages包,其中就包括busybox,如果想单独编译并安装busybox的话执行下面命令即可:

make busybox

上述命令就会重新编译busybox。编译完成以后重新编译buildroot,主要是对其进行打包,输入如下命令:

make -j8

重新编译完成以后查看一下output/images目录下rootfs.tar的创建时间是否为刚刚编译的,如果不是的话就删除掉rootfs.tar,然后重新执行“sudo make”重新编译一下即可。最后使用新的rootfs.tar启动Linux系统。

使用自己的busybox源码

buildroot会自行下载busybox并编译,但是有时候不想要buildroot自带的busybox,想要使用自己配置好的busybox,比如之前笔记中已经配置好的busybox。这个可以在buildroot中实现,只要进行相应的配置,指定要使用的busybox源码目录即可。这个要自己编写buildroot的local.mk文件,在此文件里面指定busybox目录,在buildroot的configs目录下新建一个名为“local.mk”的文件,然后在里面输入如下格式内容:

XXXXXX_OVERRIDE_SRCDIR='具体路径'

比如指定busybox路径就使用:

BUSYBOX_OVERRIDE_SRCDIR=/home/zuozhongkai/linux/busybox/busybox-1.32.0

local.mk准备好以后就可以配置buildroot,使用local.mk,打开buildroot的配置界面需要配置的项目和其对应的内容如下(“=”号后面是配置项要选择的内容!):

-> Build options
-> location of a package override file = ./configs/local.mk 指定local.mk所在目录

如下图所示:
正点原子嵌入式linux驱动开发——Buildroot根文件系统构建_第14张图片
上图中“location of a package override file”选项就是设置local.mk路径的,这里设置为“./configs/local.mk”。重新编译buildroot,此时buildroot会将BUSYBOX_OVERRIDE_SCRDIR指定的busybox源码拷贝到buildroot的output/build/busybox-custom目录下。编译完成以后使用新的根文件系统启动,输入“busybox”命令查看 busybox版本号是否为1.32.0,如下图所示:
使用自定义busybox源码
从上图可以看出,此时buildroot中的busybox版本号变为了1.32.0。为了方便开发,建议使用 buildroot自带的busybox,也就是1.31.0版本的。

buildroot第三方软件和库的配置

上一小节通过buildroot制作了一个最基本的根文件系统,本节来学习一下如何配置buildroot使能一些第三放软件或库,比如FTP和SSH服务等。

使能VSFTPD服务

可以在开发板上搭建一个FTP服务器,这样就可以使用FileZilla软件直接向开发板拷贝文件,或者将开发板中的文件拷贝到电脑中。这里通过使能buildroot中的vsftpd软件来完成FTP服务器的搭建,配置路径如下:

-> Target packages
-> Networking applications
-> [*] vsftpd //使能 vsftpd

如下图所示:

正点原子嵌入式linux驱动开发——Buildroot根文件系统构建_第15张图片

使能SSH

有时候需要远程登录开发板,这个时候就可以通过网络登录,要用到SSH服务,OpenSSH是SSH的开源免费版本。直接使能buildroot中的OpenSSH即可,配置路径如下:

-> Target packages
-> Networking applications
-> [*] openssh //使能 openssh

如下图所示:
正点原子嵌入式linux驱动开发——Buildroot根文件系统构建_第16张图片
等待编译完成就可以使用新的根文件系统进行测试了,将ouput/images/rootfs.tar拷贝到nfs目录下的rootfs目录中,然后重新解压。注意,以前自己添加的文件并不会被删除掉的,解压命令如下:

tar -vxf rootfs.tar

解压完成以后就可以使用FTP和SSH等相关的软件了,由于FTP和SSH都是通过网络进行数据传输的,因此需要先配置网络,如果是通过nfs挂载的根文件系统,那么网络已经初始化完成了,因此可以直接使用。如果是烧写到EMMC里面的,那么就需要先配置网络相关功能。

buildroot根文件系统测试

buildroot的根文件系统制作好以后就是测试工作了,基本测试内容和之前的busybox测试一样,这里就不赘述了,重点讲解一下其他的测试内容。

depmod命令测试

depmod命令非常重要,后面学习Linux驱动的时候需要使用此命令分析模块的依赖性,此命令需要在busybox中使能,路径如下:

-> Linux Module Utilities
-> [*] depmod //使能 depmod命令

如下图所示:
正点原子嵌入式linux驱动开发——Buildroot根文件系统构建_第17张图片
默认情况下depmod命令是使能了的,但是如果输入depmod命令以后发现不存在,那么就自行重新配置一下buildroot下的busybox,按照上面的方法使能depmod命令并编译一次即可,最后使用新的buildroot根文件系统启动,输入depmod命令,一般会有如下图所示错误提示:
depmod命令错误提示
从上图可以看出,depmod命令提示没有找到“lib/modules/5.4.31”目录(后面的5.4.31是和具体的Linux内核版本相关的,正点原子教程使用的Linux内核版本为5.4.31。如果使用其他版本的Linux内核,那么这里就是相应的内核版本名字)。一般将驱动模块放到lib/modules/5.4.31目录下,既然当前根文件系统不存在这个目录,那么就手动创建此
目录,命令如下:

mkdir /lib/modules/5.4.31 -p

创建好以后在执行depmod命名就不会报错了,并且depmod命令会lib/modules/5.4.31目录下生成三个文件:modules.alias、modules.dep、modules.symbols,如下图所示:
depmod命令产生三个文件
上图中这三个文件不需要操作,系统会自行使用这三个文件。

vsftpd测试

接下来测试一下用vsftpd搭建的FTP服务器,在测试之前要先进行一些设置,首先需要对vsftpd进行配置,打开/etc/vsftpd.conf文件,将下面两行前面的“#”去掉:

local_enable=YES //取消掉前面的‘#’
write_enable=YES //取消掉前面的‘#’

接下来需要修改/etc/vsftpd.conf文件的所属用户,默认为sshd用户,我们要将其改为root用户,输入如下命令:

chown root:root /etc/vsftpd.conf //修改 vsftpd.conf文件所属用户

必须修改vsftpd.conf的所有用户以及所属用户组,否则vsftpd运行的时候会报错!修改以后的vsftpd.conf所属用户以及用户组就都是root了,如下图所示:
修改后的vsftpd.conf所属用户和用户组
最后在开发板上使用adduser命令新建一个用户要来完成FTP登录,如下图所示:
正点原子嵌入式linux驱动开发——Buildroot根文件系统构建_第18张图片
创建完成以后就会在/home目录下存在“zuozhongkai”用户目录,如下图所示:
用户目录
设置完成以后重启开发板,vsftpd服务默认会使能!启动log信息如下图所示:
正点原子嵌入式linux驱动开发——Buildroot根文件系统构建_第19张图片
从上图可以看出,开机以后vsftpd默认已经启动了,可以输入“ps”命令查看一下,结果如下图所示:
后台运行的vsftpd软件
至此vsftpd服务已经正常运行了,可以使用FileZilla来登录开发板,用户名使用前面
创建的“zuozhongkai”即可,如下图所示:
正点原子嵌入式linux驱动开发——Buildroot根文件系统构建_第20张图片

设置好就可以连接了,连接成功后如下所示:
正点原子嵌入式linux驱动开发——Buildroot根文件系统构建_第21张图片
至此,开发板FTP服务就搭建完成了。

sshd测试

SSHD不仅包含SSH服务,也包含scp指令,SSHD不需要进行配置,只需要创建一个登陆用户即可,前面在FTP设置中已经创建了一个名为“ zuozhongkai”的用户,所以这里就不用再创建用户了,直接使用“zuozhongkai”这个用户即可(这一部分根据自己之前开辟的用户)。 SSHD默认会启动开启,然后在后台运行,开发板linux系统启动的时候会输出SSHD开启信息,如下图所示:
SSHD服务自启动
从上图可以看出,SSHD服务开机自启动了,如果SSHD启动失败并且提示“sshd: /var/empty must be owned by root and not group or world-writable.”,此时需要修改/var/empty目录所属用户以及用户组,输入如下命令:

chown root:root /var/empty

完成后重启开发板即可,进入系统后通过“ps”命令查看sshd后台服务,如下图所示:
后台运行的sshd
sshd测试方法很简单,使用MobaXterm软件通过SSH服务登录即可,打开MobaXterm软
件,点击“Session”按钮,在弹出的“Session settings”界面上选择“SSH”。打开以后在“Remote Host”栏填写开发板的IP地址,勾选后面的“Specify username”,并且填写登录用户名,配置完成以后如下图所示:
正点原子嵌入式linux驱动开发——Buildroot根文件系统构建_第22张图片
配置好以后点击“OK”按钮,此时就会打开ssh会话框,并且要求输入用户密码,如下图所示:
SSH登录
输入sshd用户密码,可能会弹出是否保存密码对话框,选择保存即可。如果密码正确的话就会登录到开发板上,如下图所示:
正点原子嵌入式linux驱动开发——Buildroot根文件系统构建_第23张图片
同样的,也可以在ubuntu下通过ssh命令登录开发板,输入如下命令:

ssh [email protected]

其中“zuozhongkai”为登录账户名字,192.168.1.250是开发板的IP地址。用户名和开发板IP地址之间用“@”符号链接起来(IP地址和用户名都是自己设置的)。第一次与开发板建立连接的时候会需要进行确认,输入“yes”就行,如下图所示:
确认建立连接
输入“yes”以后就会需要输入“zuozhongkai”用户密码,如下图所示:
正点原子嵌入式linux驱动开发——Buildroot根文件系统构建_第24张图片
如果密码正确的话就会登录进开发板,可以对开发板进行各种操作,如下图所示:
正点原子嵌入式linux驱动开发——Buildroot根文件系统构建_第25张图片
输入“exit”命令即可退出SSH会话。

创建自启动文件夹

前面在测试busybox的根文件系统的时候都是直接在/etc/init.d/rcS里面添加自启动相关命令的,但是buildroot构建的根文件系统中就不需要直接在/etc/init.d/rcS中添加自启动命令了,默认情况下buildroot构建的根文件系统中rcS文件内容如下图示:
正点原子嵌入式linux驱动开发——Buildroot根文件系统构建_第26张图片
从上图中可以看出,rcS默认会在/etc/init.d目录下查找所有以‘S’开头的脚本,然后依次执行这些脚本。所以可以自己创建一个以‘S’开头的自启动脚本文件,比如创建一个名为“Sautorun”的自启动文件,命令如下:

cd /etc/init.d/ //进入/etc/init.d目录
touch Sautorun //使用 touch命令创建Sautorun脚本
chmod 777 Sautorun //给予Sautorun脚本可执行权限

最后在Sautorun脚本里面输入要执行的命令,比如要开机自启动test这软件,那么Sautorun脚本内容如下图所示:
Sautorun脚本内容
设置好以后重启开发板,此时Sautorun脚本就会被rcS调用,进而运行test软件。

显示路径

这里重点看另外一个问题,使用buildroot构建的根文件系统启动以后会发现,输入命令的时候命令行前面一直都是“#”,如果进入到某个目录的话前面并不会显示当前目录路径,如下图所示:
正点原子嵌入式linux驱动开发——Buildroot根文件系统构建_第27张图片
从上图可以看出,当前所处的目录是/etc,但是前面的提示符一直是“#”,这样不利于查看自己当前所处的路径。

这个是可以设置的,不过首先要先了解一下“PS1”这个环境变量,PS1用于设置命令提示符格式,格式如下:

PS1 = '命令列表'

命令列表中可选参数如下:

\!:显示该命令的历史记录编号。
\#:显示当前命令的命令编号。
\$:显示$符作为提示符,如果用户是root的话,则显示#号。
\\:显示反斜杠。
\d:显示当前日期。
\h:显示主机名。
\n:打印新行。
\nnn:显示nnn的八进制值。
\s:显示当前运行的shell的名字。
\t:显示当前时间。
\u:显示当前用户的用户名。
\W:显示当前工作目录的名字。
\w:显示当前工作目录的路径。

打开/etc/profile文件,文件内容如下所示:

示例代码 19. 5.5.1 /etc/profile 文件要屏蔽的内容
1 export PATH="/bin:/sbin:/usr/bin:/usr/sbin" 
2 
3 if [ "$PS1" ]; then
4     if [ "`id -u`" -eq 0 ]; then 
5         export PS1='# ' 
6     else 
7         export PS1='$ ' 
8     fi 
9 fi 
10 
11 export EDITOR='/bin/vi' 
12 
13 # Source configuration files from /etc/profile.d 
14 for i in /etc/profile.d/*.sh ; do 
15     if [ -r "$i" ]; then 
16         . $i 
17     fi 
18 done 
19 unset i

第3-9行就是设置PS1环境变量的值,可以直接修改这部分代码,但是不建议这么做,因为即使修改正常了,但是后续如果重新编译buildroot并解压以后,/etc/profile文件又会被重新替换掉,又得修改/etc/profile。

第14-17行,从这里可以看出,/etc/profile文件执行的时候会遍历/etc/profile.d目录下的所示.sh脚本文件,然后执行这些.sh脚本文件。所以可以在/etc/profile.d目录下创建一个自定义的.sh脚本文件,然后在此脚本文件里面添加PS1初始化代码就行了,这样即使后面重新编译了buildroot也不用担心此.sh脚本会被替换掉。

在/etc/profile.d目录下新建一个名为“myprofile.sh”的shell脚本文件,并且给予此文件可执行权限,命令如下:

cd /etc/profile.d/ //进入/etc/profile.d目录
touch myprofile.sh //创建myprofile.sh文件
chmod 777 myprofile.sh //给予myprofile.sh可执行权限

最后在myprofile.sh里面添加如下所示内容:

示例代码 19. 5.5.2 /etc/profile添加的内容 
1 #!/bin/sh 
2 
3 PS1='[\u@\h]:\w$ ' 
4 export PS1

重点是第3行,也就是设置PS1环境变量,格式就是:

[user@hostname]:currentpath$:
  • user:用户名。
  • hostname:主机名。
  • currentpath:当前所处目录绝对路径。

设置好以后得myprofile.sh如下图所示:
正点原子嵌入式linux驱动开发——Buildroot根文件系统构建_第28张图片
myprofile.sh文件创建完成以后重启开发板,这个时候假如到某个目录的时候命令行就会有提示,如下图所示:
命令提示符
从上图可以看出,命令提示符显示正常了,完整的显示除了用户名、主机名和当前路径。至此,buildroot构建根文件系统就已经全部完成了,当然了,很多第三方软件本章并没有使能,可以自行根据实际需求选择对应的第三方软件和库。

使能sysfs debug目录

后续调试驱动的时候可能要用到/sys/kernel/debug目录,默认没有挂载debugfs文件系统,所以/sys/kernel/debug目录下没有任何文件,挂载方法很简单。在之前创建的Sautorun文件中添加如下代码:

mount -t debugfs none /sys/kernel/debug

如下图所示:
挂载debugfs
上述命令是挂载/sys/kernel/debug目录,文件系统为debugfs。修改完成以后重启开发板,进入到/sys/kernel/debug目录,此时此目录下就有很多子目录,如下图所示:
正点原子嵌入式linux驱动开发——Buildroot根文件系统构建_第29张图片
从上图可以看出,debug目录下有很多子目录和文件,分别对应不同的设备。

烧写根文件系统到EMMC

至此,一个最基本的buildroot根文件系统就制作好了,可以将其打包烧写到开发板中。虽然编译buildroot的时候已经生成了rootfs.ext4格式的根文件系统,但是!实际上还在自行创建了一些文件,因此buildroot编译出来的rootfs.ext4不实用,所以还是需要我们对上面测试过的根文件系统打包,然后再烧写

根文件系统打包

首先对/home/zuozhongkai/linux/nfs/rootfs目录下的根文件系统打包,打包方法和上一篇笔记中对busybox打包一模一样,这里不再赘述,最终得到一个名为“rootfs.ext4”的根文件系统包。

烧写到EMMC

打包完成以后就可以使用STM32CubeProgrammer软件烧写到开发板EMMC中,烧写方法也跟之前busybox一样。

EMMC启动测试

烧写完成以后就可以从EMMC启动测试了,需要设置uboot下面的bootcmd和bootargs这两个环境变量,命令如下:

setenv bootcmd 'ext4load mmc 1:2 c2000000 uImage;ext4load mmc 1:2 c4000000 stm32mp157d-atk.dtb;bootm c2000000 - c4000000' setenv bootargs 'console=ttySTM0,115200 root=/dev/mmcblk1p3 rootwait rw'
saveenv
boot

启动以后如下图所示:
正点原子嵌入式linux驱动开发——Buildroot根文件系统构建_第30张图片
从EMMC启动的话默认是不开启网络的,需要自行开启,输入“ifconfig -a”命令查看当前开发板所有网卡信息,如下图所示:
正点原子嵌入式linux驱动开发——Buildroot根文件系统构建_第31张图片
从上图可以看出,当前开发板有两个网卡:eth0和lo,其中eth0就是开发板的千M有线网卡,lo是回测用的。但是eth0这个网卡默认是没有启用的,输入“ifconfig”命令可以查看当前正在工作的网卡,如下图所示:
正点原子嵌入式linux驱动开发——Buildroot根文件系统构建_第32张图片
从上图可以看出,当前系统就只启用了lo网卡,eth0网卡并没有启用,所以需要手动打开eth0网卡,输入如下命令:

ifconfig eth0 up //打开eth0网卡

输入以上命令就会打开eth0网卡,如下图所示:
正点原子嵌入式linux驱动开发——Buildroot根文件系统构建_第33张图片
从上图可以看出, eth0网络连接成功,网速为1Gbps。注意!如果开发板连接的路由器或交换机是百M的,那么网速可能为100Mbps。

再次输入“ifconfig”命令就可以看到eth0网卡打开了,如下图所示:
正点原子嵌入式linux驱动开发——Buildroot根文件系统构建_第34张图片
从上图可以看出,此时eth0网卡已经打开了,但是此时开发板网络还不能使用,因为我们还没有配置eth0网卡地址信息,如果开发板没有连接路由器,而是直接连接的交换机或者电脑,那么只能手动设置eth0网卡地址信息,命令如下:

ifconfig eth0 192.168.1.250 netmask 255.255.255.0

如果需要开机自动设置静态IP地址,那就可以在/etc/init.d/Sautorun中添加如下两行:

ifconfig eth0 up //打开eth0
ifconfig eth0 192.168.1.250 netmask 255.255.255.0 //设置 IP地址

修改完Sautorun文件以后执行一次sync命令,确保修改的内容写入到Sautorun文件里面,而不是写入到缓存中。最后重启开发板,此时系统启 动的时候就会自动打开eth0网卡,并且设置静态IP地址。

如果开发板连接路由器的话就更简单了,不需要手动设置静态IP地址,直接使用“udhcpc”命令从路由器获取动态IP地址即可,如下图所示:
正点原子嵌入式linux驱动开发——Buildroot根文件系统构建_第35张图片
从上图可以看出,开发板通过udhcpc命令获取到了192.168.1.157这个IP地址。

总结

这一章主要是使用buildroot来配置根文件系统,这样的话就不用像busybox一样累死累活自己手动加lib了,可以直接通过使能来添加第三方库和软件

配置buildroot

首先解压然后图形化配置:

tar -vxjf buildroot-2020.02.6.tar.bz2
make menuconfig

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

Toolchain
-> Toolchain type = External toolchain
-> Toolchain = Custom toolchain //用户自己的交叉编译器
-> Toolchain origin = Pre-installed toolchain //预装的编译器
-> Toolchain path = /usr/local/arm/gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf
-> Toolchain prefix = $(ARCH) -none-linux-gnueabihf //前缀
-> External toolchain gcc version = 9.x
-> External toolchain kernel headers series = 4.20.x //交叉编译器的linux版本号
-> External toolchain C library = glibc/eglibc
-> [*] Toolchain has SSP support? (NEW) //选中
-> [*] Toolchain has RPC support? (NEW) //选中
-> [*] Toolchain has C++ support? //选中
-> [*] Enable MMU support (NEW) //选中

System configuration
-> System hostname = ATK-stm32mp1 //平台名字,自行设置
-> System banner = Welcome to alientek STM32MP157 //欢迎语
-> Init system = BusyBox //使用 busybox
-> /dev management = Dynamic using devtmpfs + mdev //使用 mdev
-> [*] Enable root login with password (NEW) //使能登录密码
-> Root password = 123456 //登录密码为123456

-> Filesystem images
-> [*] ext2/3/4 root filesystem //如果是 EMMC或 SD卡的话就用 ext3/ext4
-> ext2/3/4 variant = ext4 //选择 ext4格式
-> exact size =1G //ext4格式根文件系统 1GB(根据实际情况修改 )
-> [*] ubi image containing an ubifs root filesystem //如果使用 NAND的话就用 ubifs

-> Kernel
-> [ ] Linux Kernel //不要选择编译 Linux Kernel选项!

-> Bootloaders
-> [ ] U-Boot //不要选择编译 U-Boot选项!

-> Target packages
-> System tools -> [*] kmod //使能内核模块相关命令

make stm32mp1_atk_defconfig
make -j8

以上就是对buildroot的配置,配置完成后保存在./configs文件夹下的stm32mp1_atk_defconfig中,然后通过最后一行命令编译一下就可以成成.config文件了。

编译完成后,找到buildroot编译好之后生成的output/images文件夹下的rootfs.tar然后复制到nfs的rootfs文件夹下解压出来就可以了。然后进入开发板uboot,设置环境变量来挂载nfs:

setenv bootargs console=ttySTM0,115200 root=/dev/nfs nfsroot=192.168.1.249:/home/zuozhongkai/linux/nfs/rootfs,proto=tcp rw ip=192.168.1.250:192.168.1.249:192.168.1.1:255.255.255.0::eth0:off''

之后就可以了。

配置buildroot下的busybox

make busybox-menuconfig

通过以上命令然后配置,最后make一下就可以了。

buildroot配置第三方库

这里主要使能网络功能FTP和SSH:

-> Target packages
-> Networking applications
-> [*] vsftpd //使能 vsftpd

-> Target packages
-> Networking applications
-> [*] openssh //使能 openssh

测试

这个就不赘述了,直接看上面的笔记就好了。

总结之总结

这一章节学习完之后,就正式结束了系统移植的工作,正式进入linux驱动的抑制了!!!之后如果又碰到一些stm32有的外设,就直接跳过了,不会跟现在一样这么详细做笔记了。现在的笔记非常详细,基本就是拷贝的文档,来加深自己的印象。之后的话就注重实用性了,学过的知识就不记录了。

你可能感兴趣的:(linux学习,linux,驱动开发,stm32,学习,笔记)