04-根文件系统构建.md 25 KB


title: 根文件系统构建 tags: [根文件系统, BusyBox, 嵌入式Linux, I.MX6ULL, 系统移植] created: 2026-09-16 updated: 2026-09-17

pdf_ref: "【正点原子】I.MX6U嵌入式Linux驱动开发指南V2.0.1 - 第三十八章 根文件系统构建"

根文件系统构建

💡 关联知识: [[06-系统移植与启动/03-Linux内核裁剪与配置]] | [[02-嵌入式Linux内核基础/01-内核编译与启动流程]] | [[06-系统移植与启动/01-Uboot移植与配置]]

一、根文件系统概述

1.1 什么是根文件系统

根文件系统(rootfs)是 Linux 内核启动后挂载的第一个文件系统。它包含了系统启动所需的目录结构、基本命令、配置文件和库文件,为用户空间程序提供运行环境。

关键特性

  • Linux 内核初始化时首先挂载的文件系统
  • 包含 /sbin/init 或指定的 init 程序
  • 提供用户空间与内核空间的接口
  • 如果没有根文件系统,内核会报 "Kernel panic" 错误

与普通文件系统的区别

  • 根文件系统在内核启动时自动挂载
  • 包含系统启动必需的初始化脚本(如 rcS、inittab)
  • 通常比普通文件系统更精简

1.2 目录结构

Linux 根文件系统采用标准的目录结构,每个目录有特定用途:

目录 用途 说明
/bin 基本命令 系统启动和运行必需的可执行文件,如 ls、mv、cp
/sbin 系统命令 系统管理命令,如 ifconfig、reboot,通常只有管理员使用
/lib 共享库 系统库文件,供应用程序动态链接使用
/etc 配置文件 系统配置文件,如 fstab、inittab、resolv.conf
/dev 设备文件 设备节点文件,如 /dev/ttyS0、/dev/null
/proc 进程信息 proc 文件系统挂载点,存储系统运行时信息
/sys 内核对象 sysfs 文件系统挂载点,提供内核数据结构信息
/usr 用户程序 Unix Software Resource,用户空间程序和库
/var 可变数据 日志、缓存等可改变的数据
/mnt 挂载点 临时挂载目录,如 /mnt/sdcard、/mnt/usb
/tmp 临时文件 系统重启后清空的临时文件
/root root用户目录 root 用户的家目录

1.3 文件系统类型

嵌入式 Linux 常用的文件系统类型:

磁盘文件系统

  • ext2/ext3/ext4:Linux 原生文件系统,支持日志(ext3/ext4)
  • FAT32/exFAT:Windows 兼容,SD 卡常用
  • NTFS:Windows NT 文件系统

闪存文件系统

  • YAFFS/YAFFS2:专为 NAND Flash 设计
  • UBIFS:Unsorted Block Image,适用于大容量 NAND
  • JFFS2:Journaling Flash File System

内存文件系统

  • proc:进程信息,虚拟文件系统
  • sysfs:内核对象,虚拟文件系统
  • tmpfs:临时文件系统,基于内存

网络文件系统

  • NFS:Network File System,开发调试常用

1.4 根文件系统构建流程

1. 下载并编译 BusyBox(提供基本命令)
2. 创建根文件系统目录结构
3. 拷贝 C 库文件(libc、libm 等)
4. 创建必要的设备节点
5. 编写启动脚本(rcS、inittab 等)
6. 测试与调试

二、BusyBox 构建

2.1 BusyBox 概述

BusyBox 是一个集成了大量 Linux 命令和工具的单个可执行文件。它将 ls、mv、cp、ifconfig 等常用命令集成到一个程序中,大大减小了根文件系统的体积。

名称由来:"Busy"(繁忙)+ "Box"(盒子),意为"繁忙的盒子",因为它提供了文件系统所需的大量工具。

官网https://busybox.net/

优势

  • 体积小:一个可执行文件包含上百个命令
  • 配置灵活:可通过 menuconfig 选择需要的功能
  • 开源免费:遵循 GPL 协议
  • 广泛使用:几乎所有嵌入式 Linux 系统都使用 BusyBox

2.2 下载与解压

# 下载 BusyBox 源码(推荐使用 1.29.0 版本,稳定无 bug)
wget https://busybox.net/downloads/busybox-1.29.0.tar.bz2

# 解压源码
tar -vxjf busybox-1.29.0.tar.bz2

# 进入源码目录
cd busybox-1.29.0

⚠️ 注意:建议使用 1.29.0 版本,该版本经过充分测试,稳定性好。

2.3 修改 Makefile

与 Uboot 和 Linux 内核类似,BusyBox 的编译需要指定交叉编译器。修改 Makefile

# 第 164 行左右
CROSS_COMPILE ?= /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-

# 第 190 行左右
ARCH ?= arm

说明

  • CROSS_COMPILE:交叉编译器前缀路径(使用绝对路径防止出错)
  • ARCH:目标架构,ARM 芯片设置为 arm

2.4 中文字符支持修改

默认编译的 BusyBox 在终端中无法正确显示中文字符(显示为 ?)。需要修改源码:

修改文件 1busybox-1.29.0/libbb/printable_string.c

找到 printable_string 函数,注释掉第 31-32 行和第 45-46 行:

// 修改前(第 31-32 行)
if (c >= 0x7f)
    break;

// 修改后
/* if (c >= 0x7f)
    break; */

// 修改前(第 45-46 行)
if (c < ' ' || c >= 0x7f)
    *d = '?';

// 修改后
if( c < ' ')
    *d = '?';

修改文件 2busybox-1.29.0/libbb/unicode.c

找到 unicode_conv_to_printable2 函数,修改第 1022 行和第 1030-1031 行:

// 修改前(第 1022 行)
*d++ = (c >= ' ' && c < 0x7f) ? c : '?';

// 修改后
*d++ = (c >= ' ') ? c : '?';

// 修改前(第 1030-1031 行)
if (c < ' ' || c >= 0x7f)
    *d = '?';

// 修改后
if(c < ' ')
    *d = '?';

修改原理:BusyBox 默认会过滤掉 ASCII 码大于 0x7f 的字符(即中文字符),通过注释掉这些判断,可以使 BusyBox 正确显示中文。

2.5 配置 BusyBox

BusyBox 支持三种配置方式:

# 1. 默认配置(推荐初学者)
make defconfig

# 2. 全选配置(包含所有功能)
make allyesconfig

# 3. 最小配置(只包含最基本功能)
make allnoconfig

图形化配置(推荐):

make menuconfig

关键配置选项

1. 静态编译 vs 动态编译

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

⚠️ 重要:不要选择静态编译!静态编译会导致 DNS 解析失败,无法正常联网。必须使用动态编译。

2. vi 风格行编辑

Location:
    -> Settings
        -> vi-style line editing commands

3. 简化 modutils(取消选择):

Location:
    -> Linux Module Utilities
        -> Simplified modutils

4. 启用 mdev(确保选中):

Location:
    -> Linux System Utilities
        -> mdev (16 kb)

5. 启用 Unicode 支持(可选):

Location:
    -> Settings
        -> Support Unicode  [Y]
        -> Check $LC_ALL, $LC_CTYPE and $LANG environment variables  [Y]

2.6 编译与安装

# 编译 BusyBox
make

# 安装到指定目录
make install CONFIG_PREFIX=/home/zuozhongkai/linux/nfs/rootfs

CONFIG_PREFIX 指定安装目录,即根文件系统所在路径。

安装完成后,rootfs 目录结构如下:

rootfs/
├── bin/        # BusyBox 命令链接
├── sbin/       # 系统命令链接
├── usr/        # 用户程序
│   ├── bin/
│   └── sbin/
└── linuxrc    # init 程序(由 BusyBox 生成)

2.7 BusyBox 命令说明

BusyBox 支持的命令可以分为几类:

类别 命令示例 说明
文件操作 ls, cp, mv, rm, mkdir 基本文件管理
文本处理 cat, grep, sed, awk 文本查看和处理
网络工具 ifconfig, ping, wget 网络配置和测试
系统管理 ps, kill, top, free 进程和系统管理
存储工具 mount, fdisk, df 存储设备管理

三、根文件系统目录创建

3.1 创建基本目录结构

在 rootfs 目录下创建必要的目录:

cd rootfs

# 创建基本目录
mkdir -p bin sbin lib etc usr dev proc sys tmp mnt root

# 创建 usr 子目录
mkdir -p usr/bin usr/sbin usr/lib

# 创建 dev 子目录(用于 mdev)
mkdir -p dev/pts

3.2 创建设备节点

Linux 系统需要基本的设备节点才能正常运行:

cd dev

# 控制台设备
sudo mknod console c 5 1

# 空设备
sudo mknod null c 1 3

# 终端设备
sudo mknod ttyS0 c 4 64

# 随机数设备
sudo mknod random c 1 8

# _urandom 设备
sudo mknod urandom c 1 9

cd ..

设备号说明

  • 第一个数字:设备类型(c=字符设备,b=块设备)
  • 第二个数字:主设备号
  • 第三个数字:次设备号

3.3 /etc 目录配置

/etc 目录包含系统配置文件,是根文件系统中最关键的目录之一。

创建 /etc/passwd 文件

# 用户信息文件
cat > etc/passwd << 'EOF'
root::0:0:root:/root:/bin/sh
EOF

创建 /etc/group 文件

# 用户组信息文件
cat > etc/group << 'EOF'
root:x:0:
EOF

创建 /etc/profile 文件

cat > etc/profile << 'EOF'
export PATH=/sbin:/bin:/usr/sbin:/usr/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib:/usr/lib
export runlevel=S
export umask=022
EOF

3.4 /etc/init.d/rcS 文件

rcS 是系统启动后执行的第一个脚本,用于初始化系统:

cat > etc/init.d/rcS << 'EOF'
#!/bin/sh

PATH=/sbin:/bin:/usr/sbin:/usr/bin
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib:/usr/lib
export PATH LD_LIBRARY_PATH

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

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

chmod 777 etc/init.d/rcS

脚本说明

  • 第 1 行:指定 shell 解释器
  • 第 3-5 行:设置环境变量(PATH 和库路径)
  • 第 7 行:挂载 /etc/fstab 中定义的所有文件系统
  • 第 8-9 行:创建并挂载 devpts 文件系统(用于伪终端)
  • 第 11-12 行:启用 mdev 热插拔支持

3.5 /etc/fstab 文件

fstab 文件定义了需要自动挂载的文件系统:

cat > etc/fstab << 'EOF'
#<file system> <mount point>  <type>  <options>   <dump>  <pass>
proc              /proc            proc        defaults    0        0
tmpfs             /tmp             tmpfs       defaults    0        0
sysfs             /sys             sysfs       defaults    0        0
EOF

字段说明

  • <file system>:要挂载的设备或文件系统
  • <mount point>:挂载点
  • <type>:文件系统类型
  • <options>:挂载选项(defaults 表示使用默认选项)
  • <dump>:是否备份(0=不备份)
  • <pass>:开机时是否检查(0=不检查)

3.6 /etc/inittab 文件

inittab 文件定义了 init 进程的行为:

cat > etc/inittab << 'EOF'
#etc/inittab
::sysinit:/etc/init.d/rcS
console::askfirst:-/bin/sh
::restart:/sbin/init
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
::shutdown:/sbin/swapoff -a
EOF

字段格式<id>:<runlevels>:<action>:<process>

action 类型说明

action 说明
sysinit 系统初始化,执行一次
respawn 进程终止后重新启动
askfirst 显示 "Please press Enter to activate this console",等待用户按回车
wait 等待进程执行完毕
once 执行一次,不等待
restart init 重启时执行
ctrlaltdel 按 Ctrl+Alt+Del 时执行
shutdown 关机时执行

四、库文件拷贝

4.1 C 库选择

嵌入式 Linux 系统需要 C 库来支持动态链接的程序。常用的 C 库有:

  • glibc:GNU C Library,功能完整,体积较大
  • uClibc:专为嵌入式设计,体积小
  • musl:轻量级 C 库,兼容性好

I.MX6ULL 开发板使用 Linaro 工具链,对应的 C 库位于:

/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/lib

4.2 拷贝 /lib 库文件

# 进入库文件目录
cd /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/lib

# 拷贝所有动态库和静态库到 rootfs/lib
cp *so* *.a /home/zuozhongkai/linux/nfs/rootfs/lib/ -d

重要:修复 ld-linux-armhf.so.3 链接

ld-linux-armhf.so.3 是动态链接器,必须是实际文件而非符号链接:

# 删除 rootfs/lib 中的符号链接
rm ld-linux-armhf.so.3

# 从工具链目录拷贝实际文件
cp /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/lib/ld-linux-armhf.so.3 /home/zuozhongkai/linux/nfs/rootfs/lib/

4.3 拷贝 /usr/lib 库文件

# 进入 usr/lib 库文件目录
cd /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/usr/lib

# 拷贝所有库文件到 rootfs/usr/lib
cp *so* *.a /home/zuozhongkai/linux/nfs/rootfs/usr/lib/ -d

4.4 验证库文件

# 查看库文件大小
cd rootfs
du ./lib ./usr/lib/ -sh

# 示例输出:
# 57M    ./lib
# 67M    ./usr/lib

💡 提示:库文件总大小约 124MB,对于 256MB/512MB NAND Flash 的开发板可能空间不足,建议使用 EMMC 版本。

五、完整构建脚本

5.1 一键构建脚本

#!/bin/bash
# rootfs_build.sh - 一键构建根文件系统

# 配置参数
TOOLCHAIN_DIR=/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf
ROOTFS_DIR=/home/zuozhongkai/linux/nfs/rootfs
BUSYBOX_VERSION=1.29.0

# 1. 创建 rootfs 目录
echo "1. 创建 rootfs 目录..."
mkdir -p $ROOTFS_DIR

# 2. 解压并编译 BusyBox
echo "2. 编译 BusyBox..."
tar -vxjf busybox-${BUSYBOX_VERSION}.tar.bz2
cd busybox-${BUSYBOX_VERSION}

# 修改 Makefile
sed -i "s|^CROSS_COMPILE ?=.*|CROSS_COMPILE ?= ${TOOLCHAIN_DIR}/bin/arm-linux-gnueabihf-|" Makefile
sed -i "s|^ARCH ?=.*|ARCH ?= arm|" Makefile

# 配置并编译
make defconfig
make -j$(nproc)
make install CONFIG_PREFIX=$ROOTFS_DIR
cd ..

# 3. 创建目录结构
echo "3. 创建目录结构..."
cd $ROOTFS_DIR
mkdir -p bin sbin lib etc usr dev proc sys tmp mnt root
mkdir -p usr/bin usr/sbin usr/lib dev/pts

# 4. 创建设备节点
echo "4. 创建设备节点..."
cd dev
sudo mknod console c 5 1
sudo mknod null c 1 3
sudo mknod ttyS0 c 4 64
sudo mknod random c 1 8
sudo mknod urandom c 1 9
cd ..

# 5. 拷贝库文件
echo "5. 拷贝库文件..."
cp ${TOOLCHAIN_DIR}/arm-linux-gnueabihf/libc/lib/*so* ${TOOLCHAIN_DIR}/arm-linux-gnueabihf/libc/lib/*.a $ROOTFS_DIR/lib/ -d
cp ${TOOLCHAIN_DIR}/arm-linux-gnueabihf/libc/usr/lib/*so* ${TOOLCHAIN_DIR}/arm-linux-gnueabihf/libc/usr/lib/*.a $ROOTFS_DIR/usr/lib/ -d

# 修复 ld-linux-armhf.so.3
rm -f $ROOTFS_DIR/lib/ld-linux-armhf.so.3
cp ${TOOLCHAIN_DIR}/arm-linux-gnueabihf/libc/lib/ld-linux-armhf.so.3 $ROOTFS_DIR/lib/

# 6. 创建配置文件
echo "6. 创建配置文件..."

# /etc/passwd
cat > etc/passwd << 'EOF'
root::0:0:root:/root:/bin/sh
EOF

# /etc/group
cat > etc/group << 'EOF'
root:x:0:
EOF

# /etc/profile
cat > etc/profile << 'EOF'
export PATH=/sbin:/bin:/usr/sbin:/usr/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib:/usr/lib
export runlevel=S
export umask=022
EOF

# /etc/init.d/rcS
mkdir -p etc/init.d
cat > etc/init.d/rcS << 'EOF'
#!/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib:/usr/lib
export PATH LD_LIBRARY_PATH
mount -a
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
EOF
chmod 777 etc/init.d/rcS

# /etc/fstab
cat > etc/fstab << 'EOF'
#<file system> <mount point>  <type>  <options>   <dump>  <pass>
proc              /proc            proc        defaults    0        0
tmpfs             /tmp             tmpfs       defaults    0        0
sysfs             /sys             sysfs       defaults    0        0
EOF

# /etc/inittab
cat > etc/inittab << 'EOF'
#etc/inittab
::sysinit:/etc/init.d/rcS
console::askfirst:-/bin/sh
::restart:/sbin/init
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
::shutdown:/sbin/swapoff -a
EOF

# /etc/resolv.conf(DNS 配置)
cat > etc/resolv.conf << 'EOF'
nameserver 114.114.114.114
nameserver 192.168.1.1
EOF

echo "7. 根文件系统构建完成!"
echo "   目录:$ROOTFS_DIR"

5.2 脚本使用说明

# 1. 赋予执行权限
chmod +x rootfs_build.sh

# 2. 执行脚本
./rootfs_build.sh

# 3. 验证构建结果
ls -la $ROOTFS_DIR

5.3 目录大小检查

# 查看 rootfs 总大小
du -sh $ROOTFS_DIR

# 查看各目录大小
du -sh $ROOTFS_DIR/*

六、根文件系统测试

6.1 NFS 测试

NFS(Network File System)是开发阶段最常用的测试方式,无需烧写到 Flash。

配置 Uboot 环境变量

# 在 Uboot 命令行执行
setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.1.250:/home/zuozhongkai/linux/nfs/rootfs,proto=tcp rw ip=192.168.1.251:192.168.1.250:192.168.1.1:255.255.255.0::eth0:off'

saveenv
boot

NFS 挂载参数说明

参数 说明 示例值
root=/dev/nfs 指定 NFS 根文件系统 -
nfsroot=<server-ip>:<path> NFS 服务器 IP 和路径 192.168.1.250:/home/.../rootfs
proto=tcp 使用 TCP 协议 -
rw 读写权限 -
ip=<client-ip>:<server-ip>:<gw>:<mask>::<dev>:off 网络配置 192.168.1.251:...

6.2 启动测试

系统启动后,应该能够进入 shell 环境:

Please press Enter to activate this console.

# ls
bin      dev      etc      lib      linuxrc  mnt      proc     root     sbin     sys      tmp      usr

#

6.3 功能测试

1. 测试动态链接程序

# 在 Ubuntu 上编译测试程序
arm-linux-gnueabihf-gcc hello.c -o hello

# 拷贝到 rootfs/drivers 目录
cp hello $ROOTFS_DIR/drivers/

# 在开发板上运行
cd /drivers
./hello

2. 测试中文字符显示

# 创建中文测试文件
mkdir 测试目录
touch 测试文档.txt
echo "你好世界" > 测试文档.txt

# 验证显示
ls
cat 测试文档.txt

3. 测试网络功能

# 配置 IP 地址
ifconfig eth0 192.168.1.251

# 测试 ping
ping www.baidu.com

6.4 常见问题排查

问题 1:can't run '/etc/init.d/rcS': No such file or directory

  • 原因:rcS 文件不存在或没有执行权限
  • 解决:创建 rcS 文件并执行 chmod 777 /etc/init.d/rcS

问题 2:中文字符显示为 '?'

  • 原因:BusyBox 未修改中文支持
  • 解决:重新编译 BusyBox,修改 printable_string.cunicode.c

问题 3:ping 显示 "bad address"

  • 原因:DNS 配置缺失
  • 解决:创建 /etc/resolv.conf 文件,配置 DNS 服务器

问题 4:动态链接程序无法运行

  • 原因:缺少动态链接器 ld-linux-armhf.so.3
  • 解决:确保拷贝的是实际文件而非符号链接

七、跨平台对比

7.1 IMX6ULL vs STM32 vs RK3568 根文件系统差异

特性 I.MX6ULL STM32MP1 RK3568
架构 ARM Cortex-A7 ARM Cortex-A7 ARM Cortex-A55
位宽 32-bit 32-bit 64-bit
交叉编译器 arm-linux-gnueabihf- arm-openstlinux-linux-gnueabi- aarch64-linux-gnu-
C 库 glibc glibc glibc
文件系统类型 ext4/squashfs ext4 ext4/squashfs
推荐构建工具 BusyBox/Buildroot Yocto/Buildroot Buildroot/Debian
根 FS 大小 50-200MB 100-500MB 200MB-2GB

7.2 构建工具对比

工具 特点 适用场景
BusyBox 手动构建,完全控制 学习、小型系统
Buildroot 自动化构建,配置简单 中小型项目
Yocto 功能强大,学习曲线陡峭 大型商业项目
Debian 完整 Linux 发行版 需要丰富软件包

7.3 文件系统大小优化

优化方法 效果 说明
使用 BusyBox 替代完整工具 减小 50-70% BusyBox 集成多命令
使用 squashfs 压缩 减小 50-60% 只读压缩文件系统
去除未使用的库 减小 20-40% 精简 C 库
使用 uClibc 替代 glibc 减小 30-50% 更小的 C 库

八、面试精选

题目 1:什么是根文件系统?它与普通文件系统有什么区别?

考察点:基础概念理解

参考答案: 根文件系统(rootfs)是 Linux 内核启动时挂载的第一个文件系统,包含系统启动必需的目录结构、命令、库文件和配置文件。

与普通文件系统的区别

  1. 挂载时机:rootfs 在内核初始化时自动挂载,普通文件系统需要手动或自动挂载
  2. 内容要求:rootfs 必须包含 init 程序和基本命令,普通文件系统无此要求
  3. 完整性:rootfs 是系统运行的基础,缺失会导致 kernel panic
  4. 特殊目录:rootfs 包含 /proc、/sys、/dev 等特殊目录

题目 2:BusyBox 的作用是什么?为什么嵌入式系统常用 BusyBox?

考察点:工具理解

参考答案: BusyBox 是一个集成了大量 Linux 命令和工具的单个可执行文件,被称为"嵌入式 Linux 的瑞士军刀"。

常用原因

  1. 体积小:一个可执行文件包含上百个命令,大大减小根文件系统体积
  2. 配置灵活:通过 menuconfig 可以选择需要的功能,按需定制
  3. 性能优化:针对嵌入式系统优化,启动速度快
  4. 开源免费:遵循 GPL 协议,无授权费用
  5. 广泛支持:几乎所有嵌入式 Linux 发行版都支持 BusyBox

题目 3:根文件系统构建过程中,为什么需要修改 BusyBox 源码来支持中文?

考察点:实际问题解决

参考答案: BusyBox 默认会过滤 ASCII 码大于 0x7f 的字符(即非 ASCII 字符),导致中文字符显示为 ?

修改原理

  1. printable_string.c 中的 printable_string 函数会将 >= 0x7f 的字符替换为 ?
  2. unicode.c 中的 unicode_conv_to_printable2 函数也有类似逻辑
  3. 通过注释掉这些判断,可以保留中文字符的原始编码

修改后的效果

  • 终端可以正确显示中文文件名和目录名
  • 支持中文文本编辑和查看
  • 提升用户体验

题目 4:在构建根文件系统时,为什么不能选择 BusyBox 的静态编译?

考察点:配置选项理解

参考答案: 静态编译会将所有库函数直接链接到可执行文件中,虽然简化了依赖,但会导致严重问题:

DNS 解析失败

  • 静态链接的程序无法使用系统的动态 DNS 解析器
  • 导致 ping www.baidu.com 等网络命令失败

体积增大

  • 静态链接的程序体积比动态链接大 5-10 倍
  • 浪费宝贵的存储空间

内存占用

  • 每个静态程序都包含完整的库代码
  • 多个程序运行时内存占用成倍增加

最佳实践:使用动态编译,确保 /lib 目录包含必要的动态库。

题目 5:如何让根文件系统支持自动挂载 USB 设备和 SD 卡?

考察点:系统配置能力

参考答案: 需要配置 mdev 和相应的挂载点:

1. 确保 mdev 配置正确

# /etc/init.d/rcS
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s

2. 创建挂载点

mkdir -p /mnt/usb /mnt/sdcard

3. 配置 mdev 规则(可选):

# /etc/mdev.conf
sd[a-z][0-9]*  0:0 0660  */bin/mount /dev/$MDEV /mnt/sdcard
sd[a-z]        0:0 0660  */bin/umount /mnt/sdcard

4. 配置 fstab(可选):

# /etc/fstab
/dev/sda1      /mnt/usb     vfat    defaults    0    0
/dev/mmcblk0p1 /mnt/sdcard  vfat    defaults    0    0

验证方法

  1. 插入 USB 设备或 SD 卡
  2. 执行 ls /mnt/usbls /mnt/sdcard
  3. 检查设备是否自动挂载

最后更新: 2026-09-17