920 words
5 minutes
根文件系统的搭建
基于 BusyBox 构建根文件系统
本文基于正点原子 I.MX6U-ALPHA 开发板、Linux 4.1.15、busybox-1.29.0,手把手教你从零制作可 NFS 启动、可中文显示、无报错的最小根文件系统。
一、整体思路
- 在 Ubuntu NFS 目录下创建
rootfs,作为根文件系统目录 - 编译 BusyBox,生成基本命令(ls、cd、mkdir、ifconfig 等)
- 从交叉编译器拷贝动态库到 rootfs
- 创建必要目录:dev、proc、sys、tmp、mnt、root
- 完善启动配置:
rcS、fstab、inittab - U-Boot 配置 NFS 启动,测试根文件系统
二、环境准备
- 已安装 NFS 服务(驱动开发必备)
- 已安装交叉编译器:
arm-linux-gnueabihf-gcc - 已获取:
busybox-1.29.0.tar.bz2
创建根文件系统存放目录(示例路径,按你自己的改):
cd /home/zuozhongkai/linux/nfsmkdir rootfs三、解压并配置 BusyBox
1. 解压
tar -vxjf busybox-1.29.0.tar.bz2cd busybox-1.29.02. 修改顶层 Makefile(指定架构与编译器)
打开 Makefile,找到并修改:
ARCH ?= armCROSS_COMPILE ?= /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-ARCH=armCROSS_COMPILE写绝对路径,避免编译失败
四、修改 BusyBox 支持中文显示(关键)
默认会把中文显示成 ?,必须改两处源码。
1. 修改 libbb/printable_string.c
找到函数 printable_string:
- 注释掉:
if (c >= 0x7f) break; - 将判断改为:
if (c < ' ')
// 修改前if (c >= 0x7f) break;
// 修改后// if (c >= 0x7f)// break;// 修改前if (c < ' ' || c >= 0x7f) *d = '?';
// 修改后if (c < ' ') *d = '?';2. 修改 libbb/unicode.c
找到 unicode_conv_to_printable2:
// 修改前*d++ = (c >= ' ' && c < 0x7f) ? c : '?';
// 修改后*d++ = (c >= ' ') ? c : '?';// 修改前if (c < ' ' || c >= 0x7f) *d = '?';
// 修改后if (c < ' ') *d = '?';五、menuconfig 配置 BusyBox
make defconfigmake menuconfig按下面路径逐项配置:
1. Settings
- 不勾选:
Build static binary (no shared libs)(动态编译,否则 DNS 异常) - 勾选:
vi-style line editing commands - 勾选:
Support Unicode - 勾选:
Check $LC_ALL $LC_CTYPE $LANG
2. Linux Module Utilities
- 取消勾选:
Simplified modutils
3. Linux System Utilities
- 确保
mdev全部勾选(默认已选)
六、编译并安装到 rootfs
makemake install CONFIG_PREFIX=/home/zuozhongkai/linux/nfs/rootfs执行后,rootfs 会出现:
- bin sbin usr linuxrc
七、添加动态库(非常重要)
应用程序运行必须依赖库文件,从交叉编译器里拷贝。
1. 创建 lib 目录
cd /home/zuozhongkai/linux/nfs/rootfsmkdir libmkdir -p usr/lib2. 拷贝第一组库(libc/lib)
cd /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/libcp *so* *.a /home/zuozhongkai/linux/nfs/rootfs/lib/ -d特殊处理 ld-linux-armhf.so.3
这个文件必须是实体文件,不能是软链接,否则程序无法运行:
rm /home/zuozhongkai/linux/nfs/rootfs/lib/ld-linux-armhf.so.3cp ld-linux-armhf.so.3 /home/zuozhongkai/linux/nfs/rootfs/lib/3. 拷贝第二组库(arm-linux-gnueabihf/lib)
cd ../..cp *so* *.a /home/zuozhongkai/linux/nfs/rootfs/lib/ -d4. 拷贝 usr/lib
cd /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/usr/libcp *so* *.a /home/zuozhongkai/linux/nfs/rootfs/usr/lib/ -d八、创建根文件系统空目录
cd /home/zuozhongkai/linux/nfs/rootfsmkdir dev proc sys tmp mnt root etc九、完善启动配置(解决开机报错)
1. 创建 /etc/init.d/rcS
mkdir -p etc/init.dvim etc/init.d/rcS内容:
#!/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin:$PATHLD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib:/usr/lib
export PATH LD_LIBRARY_PATH
mount -a
mkdir /dev/ptsmount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplugmdev -s添加可执行权限:
chmod 777 etc/init.d/rcS2. 创建 /etc/fstab
vim etc/fstab内容:
#<file system> <mount point> <type> <options> <dump> <pass>proc /proc proc defaults 0 0tmpfs /tmp tmpfs defaults 0 0sysfs /sys sysfs defaults 0 03. 创建 /etc/inittab
vim etc/inittab内容:
::sysinit:/etc/init.d/rcSconsole::askfirst:-/bin/sh::restart:/sbin/init::ctrlaltdel:/sbin/reboot::shutdown:/bin/umount -a -r::shutdown:/sbin/swapoff -a十、U-Boot 配置 NFS 启动根文件系统
1. 设置 bootargs(NFS 挂载)
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'
saveenv2. 内核启动命令(TFTP + NFS)
tftp 80800000 zImagetftp 83000000 imx6ull-alientek-emmc.dtbbootz 80800000 - 83000000十一、成功标志
- 开机无报错
- 不提示:
can't run /etc/init.d/rcS - 出现:
Please press Enter to activate this console. - 按回车进入命令行,
lspwdifconfig正常 - 中文文件名/目录可正常显示(不再是?)
十二、最简记忆口诀
- 解压 busybox
- 改 Makefile 指定编译器
- 改两处源码支持中文
- menuconfig 关闭静态编译、打开 unicode
- make && make install 到 rootfs
- 从交叉编译器拷贝所有 .so 库
- 修 ld-linux-armhf.so.3 为实体文件
- 创建 rcS fstab inittab
- U-Boot 配置 NFS 启动
- TFTP 下载内核 + dtb,开机成功
系统烧写(暂略)
Some information may be outdated