根文件系统(rootfs)

一、根文件系统的内容

/
├── bin/         基本命令
├── sbin/        系统命令
├── etc/         配置
├── dev/         设备文件(devtmpfs)
├── proc/        进程信息(procfs)
├── sys/         内核对象(sysfs)
├── lib/         库
├── usr/         用户程序
├── var/         变化的数据
├── tmp/         临时
├── root/        root 家目录
├── home/        用户家目录
├── boot/        启动文件(独立分区)
├── mnt/, /media 挂载点
├── opt/         第三方
└── run/         运行时数据(tmpfs)

二、根文件系统的挂载

内核
  ↓
挂载第一个文件系统(initramfs 或 rootfs)
  ↓
执行 /sbin/init
  ↓
init 继续挂载 /proc /sys /dev ...
  ↓
启动服务

三、initramfs / initrd

1. 概念

2. 用途

3. 内核配置

CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE="..."   # 可指定 cpio 文件

4. 制作

# 准备目录
mkdir -p initramfs/{bin,sbin,etc,proc,sys,dev}
cd initramfs
# ... 填充内容

# 打包
find . | cpio -o -H newc | gzip > ../initramfs.cpio.gz

# 或
find . | cpio -o -H newc > ../initramfs.cpio

5. 内容示例

initramfs/
├── init                  # 可执行脚本
├── bin/
│   └── busybox -> /bin/busybox
├── dev/
│   └── console
└── lib/

init 脚本:

#!/bin/sh
mount -t proc proc /proc
mount -t sysfs sys /sys
mount -t devtmpfs dev /dev
# 加载驱动
modprobe usb_storage
sleep 2
# 挂载真根
mount -t ext4 /dev/sda1 /mnt
exec switch_root /mnt /sbin/init

四、真实 rootfs 构建(手动)

1. 创建基础目录

ROOTFS=/path/to/rootfs
mkdir -p $ROOTFS/{bin,sbin,etc,dev,proc,sys,run,tmp,usr/{bin,sbin,lib},var,lib,home,root}

2. 编译 / 安装 BusyBox

make CONFIG_PREFIX=$ROOTFS install

3. 创建设备文件(可选,devtmpfs 会自动创建)

sudo mknod $ROOTFS/dev/console c 5 1
sudo mknod $ROOTFS/dev/null c 1 3
sudo mknod $ROOTFS/dev/tty c 5 0
sudo chmod 600 $ROOTFS/dev/console

4. 准备 etc

cat > $ROOTFS/etc/fstab <<EOF
proc       /proc  proc  defaults  0 0
sysfs      /sys   sysfs defaults  0 0
devtmpfs   /dev   devtmpfs mode=0755,nosuid 0 0
tmpfs      /tmp   tmpfs mode=1777 0 0
tmpfs      /run   tmpfs mode=0755,nosuid,nodev 0 0
EOF

cat > $ROOTFS/etc/passwd <<EOF
root:x:0:0:root:/root:/bin/sh
EOF

cat > $ROOTFS/etc/group <<EOF
root:x:0:
EOF

cat > $ROOTFS/etc/hostname <<EOF
myboard
EOF

cat > $ROOTFS/etc/inittab <<EOF
::sysinit:/etc/init.d/rcS
::respawn:/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/etc/init.d/rcK
EOF

mkdir -p $ROOTFS/etc/init.d
cat > $ROOTFS/etc/init.d/rcS <<EOF
#!/bin/sh
mount -a
echo "Welcome to MyBoard!"
EOF
chmod +x $ROOTFS/etc/init.d/rcS

5. 打包成镜像

# ext4 镜像
dd if=/dev/zero of=rootfs.ext4 bs=1M count=64
mkfs.ext4 -F -L rootfs rootfs.ext4
sudo mount rootfs.ext4 /mnt
sudo cp -a $ROOTFS/* /mnt/
sudo umount /mnt

# squashfs(只读、压缩)
mksquashfs $ROOTFS rootfs.squashfs -comp xz -noappend

# initramfs
find $ROOTFS | cpio -o -H newc | gzip > rootfs.cpio.gz

五、devtmpfs

# 内核配置
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y

内核自动挂载 /dev,无需 mknod。

六、OverlayFS(OTA 关键)

mount -t overlay overlay -o lowerdir=/mnt/ro,upperdir=/mnt/rw,workdir=/mnt/work /mnt/merged

应用:
- Docker 镜像分层
- 嵌入式 OTA:A/B 分区
- 只读根文件系统 + 可写 overlay

七、其他文件系统

1. tmpfs(内存)

2. squashfs(压缩只读)

3. ubifs / jffs2(NAND)

4. f2fs(eMMC)

八、嵌入式 rootfs 选择

场景 推荐
开发调试 initramfs + NFS root
NAND 启动 jffs2 / ubifs
eMMC 启动 ext4
量产只读 squashfs + overlay
OTA A/B 分区

九、NFS Root(开发神器)

# U-Boot 环境变量
nfsroot=192.168.1.10:/path/to/rootfs
ip=dhcp
setenv bootargs root=/dev/nfs nfsroot=${nfsroot} ip=${ip}