8 Buildroot root file system construction

1. Introduction to root file system

  The root file system is also generally called rootfs, which is part of the Linux kernel.

  The root file system is first of all a file system. This file system not only has the function of storing data files like an ordinary file system, but its special feature compared to ordinary file systems is that it is mounted when the kernel starts (mount ), the image file of the kernel code is stored in the root file system. The system boot program will load some initialization scripts (such as rcS, inittab) and services into the memory after the root file system is mounted. run. We need to understand that the file system and the kernel are two completely independent parts. When the kernel transplanted in the embedded system is downloaded to the development board, there is no way to actually start the Linux operating system, and an error that the file system cannot be loaded will occur.

2. buildroot

  Buildroot is an open source embedded Linux system automatic building framework on the Linux platform, which uses cross-compilation to generate Linux systems. The entire Buildroot is composed of Makefile script and Kconfig configuration file.

1. buildroot source code download

  Official website:Buildroot - Embedded Linux made simple

  Since my Ubuntu version is lower, I use the 2020.02.6 version recommended by Zhengdian.

2. buildroot builds the root file system

① Configure buildboot

  First copy buildroot-2020.02.6.tar.bz2 to the linux/tool ​​path of Ubuntu. The decompression command is as follows:

tar -vxjf buildroot-2020.02.6.tar.bz2

  buildroot also supports graphical configuration:

make menuconfig

1. Configure Target options

  The items that need to be configured and their corresponding contents are as follows (after the "=" sign is the content to be selected for the configuration item! ): 

-> 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

# 目标架构:ARM
# 目标二进制格式:ELF
# 目标架构变体:cortex-A7
# 目标ABI:EABIhf
# 浮点策略:NEON/VFPv4
# ARM指令集:ARM

 2. Configure Toolchain

  This configuration item is used to configure the cross-compilation tool chain, that is, the cross-compiler. It can be set to the cross-compiler we use ourselves. The items that need to be configured and their corresponding contents are as follows: 

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)
    
# 工具链类型:外部工具链
# 工具链:自定义工具链
# 工具链来源:预安装的工具链
# 工具链路径:/usr/local/arm/gcc-arm-9.2-2019.12-x86_64-arm-none-linuxgnueabihf
# 工具链前缀:$(ARCH)-none-linux-gnueabihf
# 外部工具链gcc版本:9.x
# 外部工具链内核头文件系列:4.20.x
# 外部工具链C库:glibc/eglibc
# 工具链是否支持SSP(堆栈保护):选中
# 工具链是否支持RPC:选中
# 工具链是否支持C++:选中
# 是否启用MMU支持:选中

3. Configuration System configuration 

  This option is used to set some system configurations, such as development board name, welcome message, user name, password, etc. The items that need to be configured and their corresponding contents are as follows: 

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

# 可以设置密码,但是每次重启都要输入密码很麻烦,所以我这里是失能的。

 4. Configure Filesystem images

  This option configures the format of the root file system we finally create. The configuration is as follows: 

-> 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 can directly create a root file system in ext4 format, but generally we will add many other files to the root file system by ourselves. Therefore, after product development is completed, we need to package the root file system by ourselves and then burn it into the development board. Whether it is the ext4 format root file system for EMMC or the ubi format root file system for NAND, the corresponding size must be set. For example, the size of the ex4 format root file system we set here is 1GB.​ 

5. It is forbidden to compile Linux kernel and uboot

  buildroot can not only build the root file system, but also compile the linux kernel and uboot. We generally do not use the linux kernel and uboot downloaded by buildroot, because the official source code of linux and uboot downloaded by buildroot will lack many driver files, and the latest linux kernel and uboot will have compiler version number requirements, which may cause compilation fail. Therefore, we need to configure buildroot, turn off the compilation of the Linux kernel and uboot, and only use buildroot to build the root file system. First, disable the compilation of the Linux kernel. The configuration is as follows:

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

6. Compile Target packages 

  This option is used to configure the third-party libraries or software to be selected, such as alsa-utils, ffmpeg, iperf and other tools. Here we only select the kernel module to load related software. The configuration is as follows: 

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

  Compile the most basic root file system first, step by step.

7. Save configuration items

  Like uboot and kernel, it is best to save the configuration items after configuring buildroot through the graphical interface to prevent the configuration items from being deleted after clearing the project. The default configuration items of buildroot are saved in the configs directory. After the configuration is completed, select <Save>, and then enter the name of the configuration item to be set:

  If you reconfigure builroot later, you can directly enter:

make stm32mp1_atk_defconfig

  After saving, you can see the stm32mp1_atk_defconfig file.

② Compile buildboot

  Enter the following command:

make -j8 //多线程编译

# "-j"参数可以指定同时执行的并发任务数。"-j8"表示同时进行8个并发编译任务。

  The compilation time is really long, so I will directly circumvent the firewall and then compile it faster.

  Copy rootfs.tar to the rootfs folder in the nfs directory and unzip it. The command is as follows: 

cp rootfs.tar /home/alientek/linux/nfs/rootfs/ -f
cd ~
cd linux/nfs/rootfs/
tar -vxf rootfs.tar
rm rootfs.tar

  This is the root file system compiled using buildroot. We can mount it to the development board through nfs and then test it.

③ buildboot tests the root file system 

  The test method is to start uboot through nfs mounting, modify the bootargs environment variable, and set the nfsroot directory to the rootfs directory in Ubuntu. The command is as follows: 

setenv bootargs console=ttySTM0,115200 root=/dev/nfs nfsroot=192.168.1.105:/home/alientek/linux/nfs/rootfs,proto=tcp rw ip=192.168.1.106:192.168.1.105:192.168.1.1:255.255.255.0::eth0:off''
saveenv

  There is a password to log in and you need to cancel. Enter the following command:

cd ~
vim linux/nfs/rootfs/etc/inittab

  After the modification is successful, RESET the development board and repeat the following operations:

setenv bootargs console=ttySTM0,115200 root=/dev/nfs nfsroot=192.168.1.105:/home/alientek/linux/nfs/rootfs,proto=tcp rw ip=192.168.1.106:192.168.1.105:192.168.1.1:255.255.255.0::eth0:off''
boot

3. Busybox configuration under buildroot

① busybox configuration 

  buildroot will automatically download the busybox compressed package. The source code compressed packages downloaded by buildroot are stored in the /dl directory. There is a folder called "busybox" in the dl directory. The busybox compressed package is saved in this directory, as shown in the figure below. :

  But buildroot will save all decompressed software in the /output/build directory.

  Enter the busybox graphical configuration interface:

cd ..            # 返回buildroot源码根目录下
make busybox-menuconfig

-> Settings
    -> Build static binary (no shared libs)

# 不要选择这个

  Continue configuration:

-> Settings
    -> vi-style line editing commands
# 选择这个

  Continue configuration:

-> Linux Module Utilities
    -> Simplified modutils
# 不要选择这个

  Continue configuration:

-> Linux System Utilities
    -> mdev (17 kb)     # 确保下面的全部选中,默认都是选中的

  ˜Enable busybox’s unicode encoding to support Chinese:

-> Settings
    -> Support Unicode      # 选中
        -> Check $LC_ALL, $LC_CTYPE and $LANG environment variables     # 选中

  After the configuration is complete, you still need to make busybox support Chinese:

cd /linux/tools/buildroot-2020.02.6/output/build/busybox-1.31.1
vim libbb/printable_string.c

  Modify lines 31~32 and 45:

  ˜Modify the contents of busybox-1.32.0/libbb/unicode.c and modify lines 1022 and 1031:

② Compile busybox 

cd /linux/tools/buildroot-2020.02.6    # 进入 buildroot 源码目录下
make show-targets    # 当前 buildroot 所有 packages

  If we want to compile and install busybox separately, just execute the following command:

make busybox    # 编译 busybox

  After the compilation is completed, recompile buildroot, mainly to package it. Enter the following command: 

make -j8

  After the compilation is completed, check whether the creation time of rootfs.tar in the output/images directory was just compiled. If not, delete rootfs.tar, and then re-execute "sudo make" to recompile.​ 

4. Configuration of buildroot third-party software and libraries 

① Enable VSFTPD service

   Set up an FTP server on the development board, so that you can use the FileZilla software to copy files directly to the development board or copy the development board files to the computer.

cd /linux/tools/buildroot-2020.02.6
make menuconfig
-> Target packages
    -> Networking applications
        -> [*] vsftpd

② Enable SSH

  Sometimes you need to log in to the development board remotely. In this case, you can log in through the network and use the SSH service.

  Save in configs/stm32mp1_atk_defconfig.

  After recompiling buildroot, use make -j8. Copy ouput/images/rootfs.tar to the rootfs directory under the nfs directory, and then unzip it again. The command is as follows:

tar -vxf rootfs.tar

  After decompression is completed, you can use related software such as FTP and SSH. Since FTP and SSH both transmit data through the network, you need to configure the network first. If it is a root file system mounted through nfs, the network has been initialized. , so it can be used directly. If it is programmed into EMMC, then you need to configure network-related functions first.​ 

4. buildroot root file system test

① Software operation test

  Compiled application software generally uses dynamic libraries. If dynamic libraries are used, the size of the application software will be very small, but library files must be provided. We have added the library files to the root file system. We write a small test software to test whether the library files are working properly. Create a folder named "drivers" under the root file system. When we learn Linux drivers in the future, we will put all experimental files into this file. Clip inside.​ 

#include <stdio.h>
#include <unistd.h>

int main(void)
{
    while(1)
    {
        printf("hello world!\r\n");
        sleep(2);
    }
    return 0;
}

  sleep is equivalent to the Linux delay function, the unit is seconds, so sleep(2) is a delay of 2 seconds. Because we want to run on an ARM chip, we need to compile it with a cross-compiler:

arm-none-linux-gnueabihf-gcc hello.c -o hello

  You can use the file command to view the file type and encoding format:

file hello

  -hello is a 32-bit LSB executable file, based on ARM architecture and dynamically linked. Will be copied to the rootfs/dervers directory.

  To terminate hello operation, press CTRL+C, "./hello &" will let hello run in the background. Software running in the background can be shut down using the "kill -9 pid (process ID)" command. First, use the "ps" command to check the PID of the software to be shut down. The ps command is used to view all currently running processes, and The PID of the process will be given.

  First let hello run in the background, then enter ps to see what the PID is, and then use the kill -9 command to shut it down.

./hello &
ps
kill -9 205

  Because hello is constantly outputting "hello world", our input seems to be interrupted, but in fact it is not, because we are the input and hello is the output. There is no interruption in the data flow, it just appears as if it is interrupted on SecureCRT.

②Chinese character test

  In ubuntu, create a new folder named "Chinese Test" in the rootfs directory, and then check whether the Chinese name can be displayed correctly under MobaXterm. Enter the "ls" command:

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

③ Auto-start test after power-on

  The shell script /etc/init.d/rcS will be run when entering the root file system, so we can add self-starting related content to this script. The content of the /etc/init.d/rcS file after the addition is completed is as follows: 

#!/bin/sh

PATH=/sbin:/bin:/usr/sbin:/usr/bin
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib:/usr/lib
runlevel=S
umask 022
export PATH LD_LIBRARY_PATH runlevel

mount -a
mkdir /dev/pts
mount -t devpts devpts /dev/pts

echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s

# 开机自启动
cd /drivers        # 进入 drivers 目录,因为要启动的软件存放在 drivers 目录下
./hello &          # 以后台方式执行 hello 这个软件
cd /               # 退出 drivers 目录,进入到根目录下

④ External network connection test

  Test to see if the development board can access the Internet. Create a new file /etc/resolv.conf in rootfs, and then enter the following content in it: 

nameserver 114.114.114.114
nameserver 192.168.1.1

  -nameserver indicates that this is a domain name server, and two domain name server addresses are set: 114.114.114.114 and 192.168.1.1. Then restart the development board.

⑤ depmod test

  When using Linux driver, you need to use this command to analyze module dependencies. This command needs to be enabled in busybox. The path is as follows: 

-> Linux Module Utilities
    -> [*] depmod

  Then recompile, generally put the driver module in the lib/modules/5.4.31 directory. Since this directory does not exist in the current root file system, create this directory manually. The command is as follows: 

mkdir /lib/modules/5.4.31 -p

  The system will automatically use these three files.

⑥ vsftpd test

  First you need to configure vsftpd, open the /etc/vsftpd.conf file, and remove the "#" in front of the following two lines: 

  Next, change the user who owns the file to root and enter the following command:

chown root:root /etc/vsftpd.conf

  We create a new user to complete FTP login.

  Open FileZilla and set up a new site.

  Connect to complete the connection with the development version of vsftpd.

⑦ sshd test

  SSHD does not require configuration, you only need to create a login user. We need to modify the user and user group to which the /var/empty directory belongs. Enter the following command: 

chown root:root /var/empty/

  Similarly, you can also log in to the development board through the ssh command under ubuntu and enter the following command: 

ssh [email protected]

# 其中 luoxuesong 是登录账号名字,192.168.1.106 是我们自己给开发板设的 IP 地址。用户名和 IP 地址用 @ 连接。
# 输入 exit 退出 SSH 会话

⑧Create self-starting files

  By default, the contents of the rcS file in the root file system built by buildroot are as follows:

  By default, rcS will search for all scripts starting with ‘S’ in the /etc/init.d directory, and then execute these scripts in sequence. So we can create a self-starting script file starting with ‘S’. For example, I created a self-starting file named Sautorun. The command is as follows: 

cd /etc/init.d/ 
touch Sautorun 
chmod 777 Sautorun 

  After setting up, restart the development board. At this time, the Sautorun script will be called by rcS to run the test software.​ 

⑨Show path

  After starting the root file system built with buildroot, you will find that when entering commands, there is always "#" in front of the command line. If we enter a certain directory, the current directory path will not be displayed in front.

This is related to the PS1 environment variable, which is used to set the command prompt format. The format is as follows: 

PS1 = ‘命令列表’

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

  We open the /etc/profile file. The content of the file is as follows: 

export PATH="/bin:/sbin:/usr/bin:/usr/sbin"

if [ "$PS1" ]; then
	if [ "`id -u`" -eq 0 ]; then
		export PS1='# '
	else
		export PS1='$ '
	fi
fi

export EDITOR='/bin/vi'

# Source configuration files from /etc/profile.d
for i in /etc/profile.d/*.sh ; do
	if [ -r "$i" ]; then
		. $i
	fi
done
unset i

# 3~9 行是设置 P1 环境变量,但是不建议修改,因为当我们重新编译了 buildroot 并解压后这个文件内容就会被替换。
# 14~17 行是 etc/profile 文件会遍历 etc/profile.d 目录下的 .sh 脚本文件,然后执行。所以我们可以自定义 .sh 脚本文件。

  Create a new shell script file named "myprofile.sh" in the /etc/profile.d directory, and give the file executable permissions. The command is as follows: 

cd /etc/profile.d/ 
touch myprofile.sh 
chmod 777 myprofile.sh 

  Finally add the following code in myprofile.sh:

#!/bin/sh

PS1='[\u@\h]:\w$ '
export PS1

  After restarting the development board, we can see the current path and user.

⑩ Enable sysfs debug directory

  We may need to use the /sys/kernel/debug directory when debugging the driver later. By default, we do not mount the debugfs file system, so there are no files in the /sys/kernel/debug directory. The mounting method is very simple. Enter the following code:

mount -t debugfs none /sys/kernel/debug

# 修改完重启

5. Burn the root file system to EMMC 

① Root file system packaging

1. Create a new ext4 format disk

  Enter the following command to create an ext4 disk: 

cd ~
mkdir /home/alientek/linux/rootfs
cd /home/alientek/linux/rootfs   
dd if=/dev/zero of=rootfs.ext4 bs=1M count=1024 # dd 命令创建一个名为 rootfs.ext4 的磁盘,由于根文件系统比较大,因此 count设置为 1024,也就是根文件系统总空间为 1GB
mkfs.ext4 -L rootfs rootfs.ext4 

# "mkfs.ext4":这是用于创建Ext4文件系统的命令。
# "-L rootfs":这个选项用于设置文件系统的标签,将文件系统的标签设置为"rootfs"。
# "rootfs.ext4":指定要格式化的文件系统所在的设备或文件。在这个例子中,我们使用"rootfs.ext4"作为文件系统。

2. Copy the system image to the ext4 disk

  First create a directory to mount the rootfs.ext4 created earlier:

sudo mkdir /mnt/rootfs

  Then use the mount command to mount rootfs.ext4 to the /mnt/rootfs directory:

cd /home/alientek/linux/rootfs
mount rootfs.ext4 /mnt/rootfs/

  After successful mounting, copy all root file system files in the /home/alientek/linux/nfs/rootfs directory to the /mnt/bootfs directory. The command is as follows: 

cd /home/alientek/linux/nfs/rootfs/
sudo cp * /mnt/rootfs/ -drf

  umount Unmount /mnt/rootfs:

sudo umount /mnt/rootfs

② Burn to EMMC

  Root file system rootfs.ext4 is programmed into the EMMC of the development board. Use the STM32CubeProgrammer software to complete this operation and modify the Flashlayout.

③ EMMC startup test

  After the programming is completed, use the uboot command line to set the two environment variables bootcmd and bootargs:

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

  After completion, the system started the lo network card, but eh0 was not started. Enter the following command:

ifconfig eth0 up     # 打开 eth0 网卡

  However, the development board network cannot be used at this time because we have not configured the eth0 network card address information. Enter the following command. If the development board is connected to a switch or computer, you need to enter the following command: w

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

  If the development version is directly connected to the router, directly enter the "udhcpc" command to obtain the dynamic IP address directly from the router.

Guess you like

Origin blog.csdn.net/qq_45475497/article/details/134940646