正点原子嵌入式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官网链接,打开以后的官网界面如下图所示:

点击上图中的"DOWNLOAD"按钮即可打开buildroot的下载界面,如下图所示:

可以看出,正点原子教程中最新的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 |

打开后的图形化配置界面如下图所示:

接下来就开始配置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 |

配置完成后如下图所示:

配置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选项! |

如下图所示:

接着禁止编译Uboot,配置如下:

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

如下图所示:

配置Target packages

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

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

上面的配置是使能内核模块相关的操作命令,比如depmod等,如下图所示:

至于其他的第三方库这里就先不选择了,先编译一下最基本的根文件系统,如果没有问题的话再重新配置选择第三方库和软件。否则编译出问题的时候都不知道怎么找问题。

保存配置项

和uboot、Linux kernel一样,通过图形化界面配置好buildroot以后最好保存一下配置项,防止清除工程以后将配置项给删除掉。buildroot的默认配置项都保存在configs目录下,配置完成以后选择 <Save>,然后输入要设置的配置项名字,如下图所示:

将配置项命名为"stm32mp1_atk_defconfig",以后要重新配置buildroot的话就可以直接输入:

|-----------------------------|
| make stm32mp1_atk_defconfig |

保存完成以后就会在buildroot的configs目录下看到"stm32mp1_atk_defconfig",如下图所示:

编译buildroot

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

|------------------|
| make -j8 //多线程编译 |

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

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

buildroot因为要从网上下载源码,因此可能存在有些源码无法下载或下载很慢的情况,比如下图所示:

可以看出上图中正在下载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编译出来的根文件系统,可以通过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'' |

设置好以后启动系统,进入根文件系统以后如下图所示:

在上图中,首先要进入到/lib/modules目录,但是默认没有,因此需要自行创建此目录。buildroot构建的根文件系统启动以后会输出前面设置的欢迎语"Welcome to alientek STM32MP157"。然后需要输入用户名和密码,用户名是"root",如果配置 buildroot的时候设置了密码,那么就需要输入密码,这里没有设置密码,因此输入用户名就行了,如下图所示:

可以看出的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源码,文件内容如下图所示:

如果想要修改busybox源码的话就直接在上图中找到相应的文件,然后修改即可。现在是要配置buildroot下的busybox,因此肯定要打开busybox的配置界面,在buildroot源码根目录下输入如下命令:

|-------------------------|
| make busybox-menuconfig |

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

busybox中文字符支持

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

编译busybox

配置好以后就可以重新编译buildroot下的busybox,进入到buildroot源码目录下,输入如

下命令查看当前buildroot所有配置了的目标软件包,也就是packages:

|-------------------|
| make show-targets |

结果如下图所示:

上图中列出了当前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所在目录 |

如下图所示:

上图中"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,如下图所示:

从上图可以看出,此时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 |

如下图所示:

使能SSH

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

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

如下图所示:

等待编译完成就可以使用新的根文件系统进行测试了,将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命令 |

如下图所示:

默认情况下depmod命令是使能了的,但是如果输入depmod命令以后发现不存在,那么就自行重新配置一下buildroot下的busybox,按照上面的方法使能depmod命令并编译一次即可,最后使用新的buildroot根文件系统启动,输入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,如下图所示:

上图中这三个文件不需要操作,系统会自行使用这三个文件。

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了,如下图所示:

最后在开发板上使用adduser命令新建一个用户要来完成FTP登录 ,如下图所示:

创建完成以后就会在/home目录下存在"zuozhongkai"用户目录,如下图所示:

设置完成以后重启开发板,vsftpd服务默认会使能!启动log信息如下图所示:

从上图可以看出,开机以后vsftpd默认已经启动了,可以输入"ps"命令查看一下,结果如下图所示:

至此vsftpd服务已经正常运行了,可以使用FileZilla来登录开发板,用户名使用前面

创建的"zuozhongkai"即可,如下图所示:

设置好就可以连接了,连接成功后如下所示:

至此,开发板FTP服务就搭建完成了。

sshd测试

SSHD不仅包含SSH服务,也包含scp指令,SSHD不需要进行配置,只需要创建一个登陆用户即可,前面在FTP设置中已经创建了一个名为" zuozhongkai"的用户,所以这里就不用再创建用户了,直接使用"zuozhongkai"这个用户即可(这一部分根据自己之前开辟的用户) 。 SSHD默认会启动开启,然后在后台运行,开发板linux系统启动的时候会输出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测试方法很简单,使用MobaXterm软件通过SSH服务登录即可 ,打开MobaXterm软

件,点击"Session"按钮,在弹出的"Session settings"界面上选择"SSH"。打开以后在"Remote Host"栏填写开发板的IP地址,勾选后面的"Specify username",并且填写登录用户名,配置完成以后如下图所示:

配置好以后点击"OK"按钮,此时就会打开ssh会话框,并且要求输入用户密码,如下图所示:

输入sshd用户密码,可能会弹出是否保存密码对话框,选择保存即可。如果密码正确的话就会登录到开发板上,如下图所示:

同样的,也可以在ubuntu下通过ssh命令登录开发板,输入如下命令:

|-------------------------------|
| ssh zuozhongkai@192.168.1.250 |

其中"zuozhongkai"为登录账户名字,192.168.1.250是开发板的IP地址。用户名和开发板IP地址之间用"@"符号链接起来 (IP地址和用户名都是自己设置的)。第一次与开发板建立连接的时候会需要进行确认,输入"yes"就行,如下图所示:

输入"yes"以后就会需要输入"zuozhongkai"用户密码,如下图所示:

如果密码正确的话就会登录进开发板,可以对开发板进行各种操作,如下图所示:

输入"exit"命令即可退出SSH会话。

创建自启动文件夹

前面在测试busybox的根文件系统的时候都是直接在/etc/init.d/rcS里面添加自启动相关命令的,但是buildroot构建的根文件系统中就不需要直接在/etc/init.d/rcS中添加自启动命令了,默认情况下buildroot构建的根文件系统中rcS文件内容如下图示:

从上图中可以看出,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脚本就会被rcS调用,进而运行test软件。

显示路径

这里重点看另外一个问题,使用buildroot构建的根文件系统启动以后会发现,输入命令的时候命令行前面一直都是"#",如果进入到某个目录的话前面并不会显示当前目录路径,如下图所示:

从上图可以看出,当前所处的目录是/etc,但是前面的提示符一直是"#",这样不利于查看自己当前所处的路径。

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

|--------------|
| PS1 = '命令列表' |

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

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

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

c 复制代码
示例代码 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里面添加如下所示内容:

c 复制代码
示例代码 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如下图所示:

myprofile.sh文件创建完成以后重启开发板,这个时候假如到某个目录的时候命令行就会有提示,如下图所示:

从上图可以看出,命令提示符显示正常了,完整的显示除了用户名、主机名和当前路径。至此,buildroot构建根文件系统就已经全部完成了,当然了,很多第三方软件本章并没有使能,可以自行根据实际需求选择对应的第三方软件和库。

使能sysfs debug目录

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

c 复制代码
mount -t debugfs none /sys/kernel/debug

如下图所示:

上述命令是挂载/sys/kernel/debug目录,文件系统为debugfs。修改完成以后重启开发板,进入到/sys/kernel/debug目录,此时此目录下就有很多子目录,如下图所示:

从上图可以看出,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 |

启动以后如下图所示:

从EMMC启动的话默认是不开启网络的,需要自行开启,输入"ifconfig -a"命令查看当前开发板所有网卡信息,如下图所示:

从上图可以看出,当前开发板有两个网卡:eth0和lo,其中eth0就是开发板的千M有线网卡,lo是回测用的。但是eth0这个网卡默认是没有启用的,输入"ifconfig"命令可以查看当前正在工作的网卡,如下图所示:

从上图可以看出,当前系统就只启用了lo网卡,eth0网卡并没有启用,所以需要手动打开eth0网卡,输入如下命令:

|-----------------------------|
| ifconfig eth0 up //打开eth0网卡 |

输入以上命令就会打开eth0网卡,如下图所示:

从上图可以看出, eth0网络连接成功,网速为1Gbps。注意!如果开发板连接的路由器或交换机是百M的,那么网速可能为100Mbps。

再次输入"ifconfig"命令就可以看到eth0网卡打开了,如下图所示:

从上图可以看出,此时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地址即可,如下图所示:

从上图可以看出,开发板通过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有的外设,就直接跳过了,不会跟现在一样这么详细做笔记了。现在的笔记非常详细,基本就是拷贝的文档,来加深自己的印象。之后的话就注重实用性了,学过的知识就不记录了。

相关推荐
Olrookie35 分钟前
若依前后端分离版学习笔记(二十)——实现滑块验证码(vue3)
java·前端·笔记·后端·学习·vue·ruoyi
请你喝好果汁6411 小时前
Conda_bashrc 初始化机制学习笔记
笔记·学习·conda
maxruan2 小时前
PyTorch学习
人工智能·pytorch·python·学习
MYX_3092 小时前
第三章 线型神经网络
深度学习·神经网络·学习·算法
_李小白2 小时前
【Android Gradle学习笔记】第八天:NDK的使用
android·笔记·学习
-指短琴长-2 小时前
Namespace隔离实战【Linux】
linux
PegasusYu2 小时前
STM32配置读取激光测距传感器VL6180X距离数据
stm32·vl6180·接近传感器·stm32g030·激光测距·飞行时间·vl6180x
摇滚侠2 小时前
Spring Boot 3零基础教程,WEB 开发 自定义静态资源目录 笔记31
spring boot·笔记·后端·spring
摇滚侠2 小时前
Spring Boot 3零基础教程,WEB 开发 Thymeleaf 遍历 笔记40
spring boot·笔记·thymeleaf
心灵宝贝2 小时前
申威(sw_64)架构下如何安装java-1.8.0-swjdk的rpm包?
linux·运维·服务器