Linux必学知识点:文件系统的构建


  

一、相关知识点

  1. Linux嵌入式操作系统的组成
    一个完整的嵌入式Linux系统确实包括三个主要部分:U-Boot、Linux内核和根文件系统。
    启动顺序如下:
    ① U-Boot:系统上电后,首先执行U-Boot,它负责初始化硬件,并加载Linux内核。
    ② Linux内核:U-Boot成功加载后,执行Linux内核,内核负责管理系统资源、调度进程等。
    ③ 根文件系统:内核启动后,挂载根文件系统,提供系统运行所需的文件和目录结构。
    在这里插入图片描述

  2. 什么是文件系统?
      文件系统是用于组织、存储和管理计算机文件的结构和方法。它定义了文件如何在存储设备上布局,以及如何访问和操作这些文件。常见的文件系统类型包括NTFS、FAT32、ext4等,每种文件系统都有其特点和用途。

  3. 什么是根文件系统?
      在 Linux 中并没有磁盘盘符这个概念,而只有一个根目录/,所有文件都在该目录下,这类目录结构也是从UNIX 系统引用过来的。下面就以 Ubuntu 为例进行简要分析并了解。
    在这里插入图片描述

目录名称描述
/根目录,所有文件和目录的起始点。
/bin存放可执行的二进制文件,如常用命令。
/boot存放系统启动所需的文件,如内核和引导程序。
/dev设备文件的目录,通过这些文件访问设备。
/etc系统配置文件存放的地方,不适合存放可执行文件。
/home用户的家目录,新增用户的目录均在此。
/lib、/usr/lib、/usr/local/lib存放系统使用的函数库。
/media、/mnt光盘和其他外部设备的挂载点。
/opt用于额外安装软件的目录。
/proc虚拟文件系统,存放内存中的数据,如系统信息。
/root系统管理员(root用户)的家目录。
/tmp存放临时文件的目录,任何用户可访问。
/srv服务需要访问的数据存放地。
/usr应用程序及其相关文件的存放目录。
/var存放经常变化的文件,如日志文件和邮件。
/sbin、/usr/sbin、/usr/local/sbin系统管理员使用的可执行命令。
  1. 根文件系统制作工具
      最简单的根文件系统一般使用 busybox工具制作。 除此之外,还可以使用 buildroot工具和yocto工具构建的文件系统。当然也可以直接使用发行版Linux系统,如Ubuntu系统,Debian 系统。
工具优缺点
busybox优点:体积小,支持常用命令,常用于定制精简的小系统。缺点:功能不全,无包管理工具。
buildroot优点:构建简单,容易理解,能构建完整镜像。缺点:无包管理工具。
yocto优点:支持的构建较多,能构建完整镜像。缺点:配置复杂,不易于新手操作。
Ubuntu优点:构建方便,支持包管理工具,支持ROS 1.x等机器人大操作系统。缺点:构建的文件系统较大。
Debian优点:构建方便,支持包管理工具,支持可视化界面。缺点:构建的文件系统较大。

二、使用busybox构建文件系统

1. 下载源码编译

  1. 下载busybox工具源码。传入Ubuntu虚拟机上并解压。下载地址点击此处!

  2. 使用命令make menuconfig,打开图形化界面进行配置选择,对命令进行裁剪,选择需要的命令。这里根据需求来选择,下面我们配置一些必要的选项。
    (1)选择:Settings -> Cross compiler prefix(NEW) ,来配置交叉编译器(根据自身开发板来选择)。填写交叉编译器的绝对路径。
    在这里插入图片描述
    (2)选择:Settings -> Build static binary(no shared libs),取消该选项,不然编译出的文件系统会很大。
    (3)选择:Settings -> vi-style line editing commands,选中,以便支持vi命令。
    (4)选择:Linux system utilities ->medv ,选中。支持热插拔。
    (5)选择:Settings -> support Unicode,选中。支持编码格式。其下面的一个选项也同样选中。
    在这里插入图片描述

  3. 修改源码,支持中文。
    使用 :set nu,显示行号。
    (1)打开libbb/printable_string.c,修改为下面的内容。
    在这里插入图片描述
    在这里插入图片描述
    (2)打开libbb/unicode.c,修改为以下内容。
    在这里插入图片描述

  4. 编译源码。
    使用命令:make来编译源码。然后使用make install CONFIG_PREFIX=../sys来安装到指定路径…/sys目录下,若路径不存在则自动生成。

  5. 查看生成的文件系统。
    在sys安装目录下生成了我们需要的命令。如下所示。
    在这里插入图片描述

2、完善busybox文件系统

  1. 使用命令:mkdir dev etc lib mnt proc sys tmp var opt,创建缺少的文件夹(自己需要哪个就创建哪个即可)。
  2. 进入lib文件夹,将交叉编译器(与编译busybox文件系统的交叉编译器一致)的库文件拷贝到此处(通常交叉编译器路径下的libc/lib文件夹的内容)。原因:在第二章节中我们取消勾选了构建静态库,防止占用内存过大,所以我们需要手动添加需要的库文件。
  3. 进入etc目录下。
    (1)使用 vim eth0-setting 创建并编辑文件,编辑以下内容,并修改权限为0777。
IP=192.168.1.230  //开发板启动后默认设置的 IP 地址
Mask=255.255.255.0 //开发板启动后默认设置的掩码
Gateway=192.168.1.1 //开发板启动手默认配置的网关
DNS=192.168.1.1 //开发板启动后默认设置的 DNS
MAC=08:90:90:90:90:90 //开发板启动后默认设置的MAC地址

(2)使用命令:mkdir /etc/init.d创建目录。进入 init.d 目录,使用命令:vim ifconfig-eth0创建文件添加以下内容,并修改权限为0777。

#!/bin/sh
# 输出提示信息到串口,表示尝试启动 eth0 接口
echo -n "尝试启动 eth0 接口..." > /dev/ttyS0

# 检查 /etc/etho-setting 文件是否存在
if [ -f /etc/etho-setting ]; then
    # 如果存在,加载该文件中的环境变量
    source /etc/etho-setting

    # 检查当前根文件系统是否挂载为 NFS
    if grep -q "^/dev/root /nfs " /etc/mtab ; then
        # 如果是 NFS 根,输出提示信息
        echo -n "NFS 根..." > /dev/ttyS0
    else
        # 否则,先将 eth0 接口关闭
        ifconfig eth0 down
        
        # 设置 eth0 接口的 MAC 地址
        ifconfig eth0 hw ether $MAC
        
        # 设置 eth0 接口的 IP 地址和子网掩码,并启动接口
        ifconfig eth0 $IP netmask $MASK up
        
        # 添加默认网关
        route add default gw $GATEWAY
    fi

    # 将 DNS 服务器地址写入 /etc/resolv.conf
    echo "nameserver $DNS" > /etc/resolv.conf
else
    # 如果 /etc/etho-setting 文件不存在,检查当前根文件系统是否挂载为 NFS
    if grep -q "^/dev/root /nfs " /etc/mtab ; then
        # 如果是 NFS 根,输出提示信息
        echo -n "NFS 根..." > /dev/ttyS0
    else
        # 否则,手动设置 eth0 接口的 IP 地址和子网掩码,并启动接口
        /sbin/ifconfig eth0 192.168.253.12 netmask 255.255.255.0 up
    fi
fi

# 输出完成信息到串口
echo "完成" > /dev/ttyS0

(3)进入/etc/init.d 文件夹, vi rcs 创建并编辑文件,输入以下内容,并修改权限为0777。

#!/bin/sh

# 设置 PATH 环境变量,包含系统常用的二进制路径
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

# 设置运行级别和上一个运行级别
runlevel=S    #只有一个控制台。
prevlevel=N

# 设置文件创建权限掩码
umask 022

# 导出环境变量,使子进程也能访问
export PATH runlevel prevlevel

# 捕获 Ctrl-C、QUIT 和 TSTP 信号,以便在当前 shell 中中断子进程
trap ":" INT QUIT TSTP

# 设置系统主机名
/bin/hostname iTOP-LS2K1000

# 挂载所有在 /etc/fstab 中定义的文件系统
mount -a

# 设置热插拔管理程序
echo /sbin/mdev > /proc/sys/kernel/hotplug
/sbin/mdev -s  # 立即触发设备事件

# 创建伪终端设备目录
mkdir -p /dev/pts
/bin/mount -n -t devpts none /dev/pts -o mode=0622  # 挂载 devpts

# 创建一些必要的空目录
mkdir -p /var/empty
mkdir -p /var/log
mkdir -p /var/lock
mkdir -p /var/run
mkdir -p /var/tmp

# 启动系统日志服务
syslogd

# 启动网络服务
/etc/rc.d/init.d/netd start

# 配置本地回环接口
mkdir -p /mnt/disk  # 确保目录存在
/sbin/ifconfig lo 127.0.0.1  # 配置 lo 接口

# 启动 eth0 接口的配置脚本
/etc/init.d/ifconfig-eth0

# 等待 1 秒
sleep 1

# 将信息输出到串口设备
echo "http://topeetboard.com" > /dev/ttyS0  # 输出网址
echo "启动完成" > /dev/ttyS0  # 输出启动完成提示

(4)在etc目录下,创建passwd文件输入以下内容,并修改权限为0777。 作用:用于保存用户信息。

root:x:0:0:root:/:/bin/sh
bin:*:1:1:bin:/bin:
daemon:*:2:2:daemon:/sbin:
nobody:*:99:99:Nobody:/: 

(5)在etc目录下,创建profile文件输入以下内容,并修改权限为0777。

# Ash profile
# vim:syntax=sh

# 默认不生成核心文件
ulimit -s -c 0 >/dev/null 2>&1

# 获取当前用户名并赋值给 USER 变量
USER="`id -un`"

# 设置 LOGNAME 变量
LOGNAME=$USER

# 设置提示符样式,显示用户名和主机名
PS1='[$USER@$HOSTNAME]# '

# 设置 PATH 环境变量
PATH=$PATH

# 获取主机名并赋值给 HOSTNAME 变量
HOSTNAME='/bin/hostname'

# 导出变量,使其在子进程中可用
export USER LOGNAME PS1 PATH

(6)在etc目录下,创建rc.d文件夹。进入rc.d,创建netd文件输入以下内容,并修改权限为0777。

#!/bin/sh

# 设置基础服务名称
base=inetd

# 根据输入参数执行相应操作
case "$1" in
start)
    # 启动服务
    /usr/sbin/$base
    ;;
stop)
    # 获取服务的进程 ID
    pid=$(pidof $base)

    # 如果找到进程 ID,则杀死进程
    if [ -n "$pid" ]; then
        kill -9 $pid
    fi
    ;;
*)
    # 如果输入参数不匹配,输出用法信息
    echo "Usage: $0 {start|stop}"
    exit 1
    ;;
esac

exit 0

(7)在etc目录下,创建inittab文件,输入以下内容,并修改权限为0777。

::sysinit:/etc/init.d/rcS                # 系统初始化时运行的命令,启动系统服务
console::askfirst:-/bin/sh                # 在控制台上询问用户,启动 shell
::restart:/sbin/init                      # 重启系统的命令
::ctrlaltdel:/sbin/reboot                 # 按下 Ctrl+Alt+Del 时重启系统
::shutdown:/bin/umount -a -r              # 关闭系统时卸载所有文件系统并重启
::shutdown:/sbin/swapoff -a               # 关闭系统时关闭所有交换空间

(8)在etc目录下,创建fstab文件,输入以下内容,并修改权限为0777。

proc   /proc   proc    defaults 0 0   # 挂载 proc 文件系统
tmpfs  /tmp    tmpfs   defaults 0 0   # 挂载 tmpfs 文件系统到 /tmp
sysfs  /sys    sysfs   defaults 0 0   # 挂载 sysfs 文件系统

(9)在etc目录下,创建mdev.conf文件,输入以下内容,并修改权限为0777。

sd[a-z][0-9]0:0 666 @ /etc/hotplug/udisk inserting   # 当插入 USB 磁盘时执行的动作
sd[a-z]0:0 666 $ /etc/hotplug/udisk removing         # 当移除 USB 磁盘时执行的动作

  在etc目录下,创建hotplug文件夹,然后在 hotplug文件夹下创建 udisk_insertingudisk_removing文件,并把权限修改成 777,,在里面输入以下内容:
udisk_inserting:

#!/bin/sh
echo "usbdisk insert!" > /dev/console  # 输出 USB 磁盘插入的消息到控制台

if [ -e "/dev/$MDEV" ]; then              # 检查设备是否存在
    mkdir -p /mnt/usbdisk/$MDEV          # 创建挂载点(如果不存在)
    mount /dev/$MDEV /mnt/usbdisk/$MDEV  # 挂载设备到指定目录
    echo "/dev/$MDEV mounted in /mnt/usbdisk/$MDEV" > /dev/console  # 输出挂载成功的消息到控制台
fi

udisk_removing:

#!/bin/sh
echo "usbdisk remove!" > /dev/console             # 输出 USB 磁盘移除的消息到控制台
umount -l /mnt/usbdisk/sd*                         # 强制卸载挂载点,使用懒惰卸载(lazy unmount)
rm -rf /mnt/usbdisk/sd*                            # 删除挂载点下的所有内容

(10)在etc目录下,创建mtab文件夹,输入命令:ln -s /proc/mounts mtab链接即可。

3. 打包busybox文件系统

不同的开发板文件系统镜像的格式不同,如下所示:

处理器型号文件系统格式
三星处理器4412,4418,6818rootfs.img
NXP处理器rootfs.tgz、rootfs.tar.bz2
RK处理器rootfs.img
龙芯处理器rootfs.cpio.gz
ST处理器rootfs.ext4
  1. 在解压的文件系统源码同级目录下创建rootfs文件夹,作为挂载点。
  2. 使用命令 du sys -h来查看文件系统的大小。 并使用下述命令,制作一个能够装下文件系统大小的容器。
dd if=/dev/zero of=rootfs.img bs=1M count=300
/*
	dd:一个用于转换和复制文件的工具,常用于创建磁盘或镜像文件。
	if=/dev/zero:输入文件为 /dev/zero,这是一个特殊文件,它会持续输出值为零的字节,相当于填充空白数据。
	of=rootfs.img:输出文件为 rootfs.img,即生成的镜像文件的名称。
	bs=1M:设置每次读取或写入的块大小为 1MB。
	count=300:表示写入 300 个 1MB 大小的块,总共创建一个大小为 300MB 的空白镜像文件。
*/

在这里插入图片描述

  1. 使用命令:mkfs.ext4 rootfs.img,格式化rootfs.img 为 ext4 格式。
  2. 使用命令:sudo mount rootfs.img rootfs,将容器挂载到 rootfs 文件上。使用df命令查看是否成功。
  3. 将文件系统源码复制到 rootfs 文件夹里。命令:sudo cp -rfpd sys/* ./rootfs
  4. 文件复制完成后,使用以下命令取消挂载。使用命令:sudo umount rootfs
  5. rootfs.img烧录至开发板。

4. 验证自制文件系统功能

前提:将rootfs.img烧录至开发板。

  1. 用户名。
    在这里插入图片描述

  2. 网络IP。
    在这里插入图片描述

  3. 热插拔
    在这里插入图片描述

5. 添加新功能

在这里插入图片描述
  对于需要添加的新功能,我们可以下载其源码进行编译,然后将编译出来的文件打包成文件夹,放入文件系统的/opt目录下。然后再vi /etc/profile编辑该文件,在末尾添加库文件路径等环境变量。添加完成最后将该文件系统打包成img下载至开发板即可。

三、使用buildroot构建文件系统(最常用)

  通过前面的学习,我们已经了解了如何使用 BusyBox 来构建文件系统,虽然 BusyBox 提供了一个精简的 Linux 工具集,但使用它构建的文件系统往往需要手动添加很多额外的软件或库。这意味着需要进行大量的交叉编译和手动移植工作,这个过程不仅复杂,而且非常耗时。那么,有没有一种更加便捷的方式来构建嵌入式 Linux 文件系统呢?
  从这节课开始,我们将学习另一种构建根文件系统的方法——使用 Buildroot 来构建文件系统。相比于 BusyBox,Buildroot 不仅集成了 BusyBox 的功能,还包含了大量常用的第三方库和软件。用户只需根据需求选择相应的功能,Buildroot 会自动完成编译、打包,并生成适用于嵌入式设备的文件系统。buildroot源码下载地址。
  Buildroot 能够生成多个固件镜像文件,包括内核镜像、Bootloader 镜像、根文件系统等,方便烧录到嵌入式设备。在此我们只是用Buildroot来构建文件系统镜像!

交叉编译器下载地址。

1. 下载源码解压

在这里插入图片描述

2. 打开图形化界面进行配置。

使用命令:make menuconfig

  1. 基础配置
    在这里插入图片描述
    在这里插入图片描述

  2. 配置交叉编译器路径
    在这里插入图片描述
    在这里插入图片描述
    1:选择External toolchain,即外部工具链。
    2:选择Custom toolchain:即我们自己下载的工具链。
    3:选择Pre-installed toolchain:即我们自己的工具链。
    4:输入我们自己工具链的路径,这里就是我们前面编译uboot和kernel的工具链的路径。
    5:输入我们自己交叉编译工具链的前缀:这里为:arm-linux-gnueabi
    6:选择我们工具链的版本:我们是7.5版本,因此在这里选择7.x。可以使用:aarch64-none-linux-gnu-gcc -v来查看版本。
    7:选择工具链kernel head:我们工具链的版本为:·4.10·,这里选择4.10.x。
    8:选择使用glibc。
    9:选中我们gcc支持的一些特性。如果报错则取消某些选项的勾选即可。
    10:选中我们gcc支持的一些特性。如果报错则取消某些选项的勾选即可。

  3. 构建选择配置
      通常不需要修改,默认即可。可以自定义路径。
    在这里插入图片描述
    在这里插入图片描述

  4. 配置系统选项
    在这里插入图片描述
    在这里插入图片描述
    其中使用串口控制台交互中,波特率的选择如下:
    在这里插入图片描述
    在这里插入图片描述

  5. 对于内核源码,不勾选。
    在这里插入图片描述
    在这里插入图片描述

  6. 对于Bootloaders,不勾选。
    在这里插入图片描述
    在这里插入图片描述

3. 修改busybox源码以及配置

(1)裁剪命令
  使用命令:make busybox-menuconfig,打开busybox的图形化界面来进行选择命令的裁剪,最后保存退出。

(2)支持中文
  裁剪完成后,使用make命令先进行编译Buildroot源码,用于生成一些文件夹。编译完成后,在dl目录下生成busybox文件夹,进入该文件夹。

在这里插入图片描述

  将压缩包进行解压,解压完成后进入目录。与目录二中busybox中修改中文操作一致,修改源码文件。
在这里插入图片描述

  修改完成源码后,删除之前的压缩包,然后将修改完的源码压缩为与之前压缩包一样的名称的压缩包文件。使用命令:tar -cjf busybox-1.36.1.tar.bz2 busybox-1.36.1。其他文件如果需要修改的话同理。原因:使用make进行编译时,会自动解压这些目录下的压缩包来配置,所以我们需要修改完源码后重新进行打包成压缩包格式。

4. 添加新功能 - QT

  使用make menuconfig打开配置界面,使用补充目录的小技巧搜索qt,然后找到自己想要的qt位置(此处为序号7),按下对应的序号。

在这里插入图片描述
我们发现是缺少C++支持,我们先进行配置C++支持。
在这里插入图片描述

在这里插入图片描述

添加完成后,我们继续搜索qt,发现qt变成了可选项。如下所示:
在这里插入图片描述

选择以下配置(可根据自身来选):
在这里插入图片描述

5. 编译buildroot,并打包。

使用命令:make进行编译,编译完成后,会在output/images下生成文件系统压缩包,解压后内容如下。
在这里插入图片描述
然后使用目录二的第3小节的方法来进行打包即可!

补充:使用make menuconfig快速搜索配置小技巧

当我们使用命令打开图形化配置界面时,我们可以按下 /进入搜索界面。
在这里插入图片描述

搜索后,出现下面的内容,包含序号。我们可以根据自己的实际选择来按下相应的序号,则会自动跳转到相应的配置位置。
在这里插入图片描述

如我们按下序号5,则自动跳转到该处来进行配置选择。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值