根文件系统制作和NFS挂载
本文详细介绍了基于BusyBox构建嵌入式Linux根文件系统的完整流程。主要内容包括:1) BusyBox源码获取与配置,重点说明中文支持、共享库编译、交叉编译器设置等关键配置项;2) BusyBox编译安装过程,包括权限设置和动态库处理;3) 根文件系统目录结构创建,包括设备节点、配置文件(fstab/inittab/rcS等)的编写;4) 生成rootfs.img镜像文件的自动化脚本实现;5
Linux系统组成:bootloader(uboot)+内核+根文件系统。
根文件系统为Linux系统提供其运行所必需的用户空间环境,包括核心命令、应用程序、系统与软件配置信息以及程序运行时依赖的库文件。在嵌入式领域,通常使用BusyBox这一开源工具来构建轻量级的根文件系统,它通过集成大量精简的Linux命令,成为制作嵌入式根文件系统的核心组件。
1.利用BusyBox制作根文件系统
1.1 BusyBox源码获得
官方网站:https://busybox.net/
BusyBox 1.25.0直接下载地址https://busybox.net/downloads/busybox-1.25.0.tar.bz2
1.2 BusyBox配置
- 复制busybox-1.25.0.tar.bz2到ubuntu系统中解压
tar -xf busybox-1.25.0.tar.bz2 busybox-1.25.0/
- 配置BusyBox
进入BusyBox源码顶层目录,使用menuconfig方式配置BusyBox
cd busybox-1.25.0/
make menuconfig
1.2.1 配置中文支持


说明:
启用Unicode支持:此为显示中文的基础,因中文通过Unicode编码实现。
检查环境变量:系统通过检查 LANG 等环境变量来设定 unicode_status=UNICODE_ON,以激活Unicode模式。
调整字符范围:默认支持的Unicode字符范围(767)不足。为涵盖全部汉字(上限为U+2FA1D),需将范围修改为十进制 195101。
启用宽字符输出:中文显示需要开启宽字符(Wide Character)支持功能。
1.2.2 配置编译为共享库
编译为共享库,可以让生成的命令程序占用空间更小。


1.2.3 配置交叉编译器
这一项是必须配置,根据自己使用的编译器名称配置,填写编译器前缀。


1.2.4 配置安装目录
此选项用于设置编译结果的安装路径。为避免因权限不足导致的安装失败,建议将其指向当前用户家目录下的一个子目录,以确保拥有写入权限。


1.2.5 配置模块安装命令
因为在驱动开的过程中经常需要动态安装驱动,卸载驱动,但是busybox默认是使用精简模式的模块命令,需要开启完整的模块命令支持。
- 取消Simplified modutils


- 分别选择新出现的

1.2.6 配置rfkil命令支持
rfkill 是一个内核级工具,用于启用或禁用无线设备(如 Wi-Fi 和蓝牙)。若系统中需使用此类功能,建议配置此工具。


1.3 BusyBox编译、安装
- 退出时保存配置

- 编译并安装BusyBox
make -j$(nproc)
make install -j$(nproc)
--------------------------------------------------
You will probably need to make your busybox binary
setuid root to ensure all configured applets will
work properly.
--------------------------------------------------
- 查看BusyBox安装后生成的文件
cd /home/liu/linux/rk3399/rootfs/
ls -F
bin/ lib/ linuxrc* sbin/ usr/
ls lib/ -lh
总用量 932K
-rw-r--r-- 1 liu liu 930K 4月 23 10:44 libbusybox.so.1.25.0
可以看到安装后生成了以5个文件:bin/ linuxrc sbin / usr/ lib/
其中lib目录中有一个libbusybox.so.1.25.0动态库文件。
- 使用file命令查看生成的busybox程序运行平台
file bin/busybox
bin/busybox: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 3.7.0, BuildID[sha1]=f029f7fbc0b61f3912b34cfb6b5a46a652547152, stripped
或者
file lib/libbusybox.so.1.25.0
lib/libbusybox.so.1.25.0: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=8ff5bc988174f75f9dc4f4888807317fce5d5e0b, stripped
- 查看BusyBox依赖的动态库
readelf bin/busybox -d
Dynamic section at offset 0xdccf8 contains 25 entries:
标记 类型 名称/值
0x0000000000000001 (NEEDED) 共享库:[libm.so.6]
0x0000000000000001 (NEEDED) 共享库:[libc.so.6]
0x000000000000000c (INIT) 0x406428
0x000000000000000d (FINI) 0x4b7a08
0x0000000000000019 (INIT_ARRAY) 0x4e9f10
0x000000000000001b (INIT_ARRAYSZ) 8 (bytes)
0x000000000000001a (FINI_ARRAY) 0x4e9f18
0x000000000000001c (FINI_ARRAYSZ) 8 (bytes)
0x0000000000000004 (HASH) 0x400260
0x0000000000000005 (STRTAB) 0x403030
0x0000000000000006 (SYMTAB) 0x400c78
0x000000000000000a (STRSZ) 3159 (bytes)
0x000000000000000b (SYMENT) 24 (bytes)
0x0000000000000015 (DEBUG) 0x0
0x0000000000000003 (PLTGOT) 0x4ecfe8
0x0000000000000002 (PLTRELSZ) 8736 (bytes)
0x0000000000000014 (PLTREL) RELA
0x0000000000000017 (JMPREL) 0x404208
0x0000000000000007 (RELA) 0x403fc8
0x0000000000000008 (RELASZ) 576 (bytes)
0x0000000000000009 (RELAENT) 24 (bytes)
0x000000006ffffffe (VERNEED) 0x403f88
0x000000006fffffff (VERNEEDNUM) 2
0x000000006ffffff0 (VERSYM) 0x403c88
0x0000000000000000 (NULL) 0x0
- 查看整体文件系统大小:(仅作为查看信息,非必须)
du -hs ../rootfs/
4.7M ../rootfs/
- 修改installbin/busybox的属性为4755
ls bin/busybox -l
-rwxr-xr-x 1 liu liu 910656 4月 23 10:45 bin/busybox
chmod 4755 ./bin/busybox
ls bin/busybox -l
-rwsr-xr-x 1 liu liu 910656 4月 23 10:45 bin/busybox
如果不修改权限属性,否则在busybox中很多命令会受限制,比如su有可能会引发以下错误:
su
su:mustbe suid to work properly
1.3.1 复制命令的动态库
- 搜索依赖的libc.so.6所在目录
which aarch64-linux-gnu-gcc
/usr/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc
find /usr/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/ -name "libc.so.6*"
/usr/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/aarch64-linux-gnu/libc/lib/libc.so.6
- 复制依赖库到开发板根文件系统lib目录
把编译器中所有的动态库文件都复制到lib目录中
cp /usr/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/aarch64-linux-gnu/libc/lib/* ./lib/ -rf
- 删除不必须的静态库
rm -rf lib/*.a
- 查看整体文件系统大小
du -hs ../rootfs/
117M ../rootfs/
1.3.2 创建其他文件夹
在开发板根文件系统目录/ home/liu/linux/rk3399/rootfs下创建其他文件:
mkdir etc/init.d dev proc sys home mnt root var opt tmp -p
ls
bin dev etc home lib linuxrc mnt opt proc root sbin sys tmp usr var
1.3.3 创建控制台设备文件
- 查看x86 ubuntu系统的控制台设备文件信息
ls /dev/console -l
crw--w---- 1 root tty 5, 1 4月 23 09:11 /dev/console
- 在根文件系统中创建控制台设备文件
sudo mknod dev/console c 5 1
ls
bin dev etc home lib linuxrc mnt opt proc root sbin sys tmp usr var
ls dev/console -l
crw-r--r-- 1 root root 5, 1 4月 23 11:51 dev/console
1.3.4 创建etc目录下文件
- 创建etc/fstab文件
使用vim创建etc/fstab文件:
vi etc/fstab
添加下内容:
# <file system> <mount point> <type> <options> <dump> <pass>
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
none /sys/kernel/debug debugfs defaults 0 0
- 创建etc/inittab文件:
从busybox-1.25.0/examples目录中复制这个文件到开发板根文件系统etc日录中进行修改。
cp ~liu/linux/rk3399/busybox-1.25.0/examples/inittab etc/
vi etc/init
修改里面的内容,只保留4行:
::sysinit:/etc/init.d/rcS
console::askfirst:-/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
- 使用vi创建rcS文件
vi etc/init.d/rcS
- 添加以下内容
#!/bin/sh
#创建devpts和tmpfs设备挂载点,如果在fstab没有指定要挂载devpts和tmpfs则不需要写
mkdir -p /dev/shm/dev/pts
#挂载fstab文件中指定的所有文件系统
mount -a
#以下是热拔插支持
#类型源挂载点
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
#以下是设置Linux系统的主机名
/bin/hostname liu
#用户可以根据需要写任意开机时需要执行的程序。
- 编辑完成后给etc/init.d/rcS文件执行权限
sudo chmod +x etc/init.d/rcS
这个文件中的命令,在系统启动后,挂接上文件系统会全部执行。也就是说需要开机自动执行的程序都可以写在这里,以上的内容除最后一行,其他是必须的。
- 创建etc/profile文件
vi etc/profile
并且添加以下内容:
USER="`id -un`"
LOGNAME=$USER
PS1='[\u@\h \W]# '
PATH=$PATH
HOSTNAME=`/bin/hostname`
export USER LOGNAME PS1
这个文件就是添加环境变量,以上的内容是实现控制台终端命令提示符号模板功能。以上命令提示模板中含有用户名\u,用户名配置需要使用etc/passwd两个文件。
从虚拟机的ubuntu系统/etc目录中复制到开发板根文件系统etc目录。
cp /etc/passwd etc/
因为busybox制作的根文件系统没有bash shell,只有shshell命令,需要要修改passwd中的bash为sh。
可以使用vim或gedit打开修改,
vi etc/passwd
root:x:0:0:root:/root:/bin/sh
liu:x:1000:1000:LIU,,,:/home/liu:/bin/sh
或直接使用sed命令修改,如下:
sed -i 's/bash/sh/g' etc/passwd
说明:如果没有做密码登录功能,不修改也可以。
1.3.5 增加登陆功能(非必须,可选功能)
- 复制ubuntu文件系统的/etc/group /etc/shadow到开发板根文件系统的etc目录中。
sudo cp /etc/group /etc/shadow etc/
- 打开etc/passwd目录,把其中的bash全部替换成sh,保存。
sed -i 's/bash/sh/g' etc/passwd
- 修改etc/inittab文件:
注释以下行
# console::askfirst:-/bin/sh
替换为:
console::respawn:-/bin/login
在开发板根文件系统中增加一个与虚拟机中ubuntu系统普通帐户同名文件夹用于在登陆时候可以自动切换到自己的家目录。
我的ubuntu系统普通用户是liu,因此,下面在开发板根文件系统home目录中创建liu文件夹。
mkdir home/liu
ls home/
liu
这样开发板挂载上文件系统后,会请求用户输入用户名和密码,帐号和密码就是虚拟机中ubuntu和帐号密码,输入帐号和密码正确才可以进入。
1.4 生成rootfs.img文件
- 下载工具
sudo apt-get update
sudo apt install genext2fs
- 创建脚本make_rootfs_img.sh
pwd
/home/liu/linux/rk3399
vi make_rootfs_img.sh
#!/bin/bash
# 设置颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 配置变量
ROOTFS_DIR="rootfs"
OUTPUT_IMG="rootfs.img"
MOUNT_POINT="/mnt/rootfs_test"
# 函数:打印信息
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 函数:检查命令是否存在
check_command() {
if ! command -v $1 &> /dev/null; then
log_error "命令 $1 未找到,请安装: sudo apt install $2"
exit 1
fi
}
# 函数:清理操作
cleanup() {
if mountpoint -q $MOUNT_POINT; then
log_info "卸载挂载点 $MOUNT_POINT"
sudo umount $MOUNT_POINT
fi
if [ -d $MOUNT_POINT ]; then
sudo rmdir $MOUNT_POINT
fi
}
# 设置退出时清理
trap cleanup EXIT
# 使用 dd+mkfs 方法创建镜像
create_img_with_dd() {
log_info "使用 dd+mkfs 方法创建镜像..."
# 计算大小(增加20%余量)
DD_SIZE_MB=$((SIZE_MB * 12 / 10))
log_info "创建 ${DD_SIZE_MB}MB 的镜像文件"
# 创建空白镜像
dd if=/dev/zero of=$OUTPUT_IMG bs=1M count=$DD_SIZE_MB status=progress
# 格式化为 ext4
mkfs.ext4 -F $OUTPUT_IMG
# 挂载并复制文件
sudo mount -o loop $OUTPUT_IMG $MOUNT_POINT
sudo cp -a $ROOTFS_DIR/* $MOUNT_POINT/
sudo umount $MOUNT_POINT
}
# 验证镜像 - 增强版
verify_image() {
log_info "开始验证镜像..."
# 挂载镜像
sudo mount -o loop $OUTPUT_IMG $MOUNT_POINT
# 1. 显示根目录内容
log_info "=== 镜像根目录内容 ==="
sudo ls -la $MOUNT_POINT
# 2. 显示磁盘使用情况
log_info "=== 磁盘使用情况 ==="
df -h $MOUNT_POINT
# 3. 检查关键目录
log_info "=== 关键目录检查 ==="
for dir in bin etc lib usr sbin dev proc sys tmp var home root; do
if [ -d "$MOUNT_POINT/$dir" ]; then
log_info "✓ 目录 $dir 存在"
else
log_warn "⚠ 目录 $dir 不存在"
fi
done
# 卸载镜像
sudo umount $MOUNT_POINT
log_info "镜像验证完成!"
# 最终文件系统检查
log_info "执行文件系统完整性检查..."
sudo e2fsck -f -y $OUTPUT_IMG
}
# 显示最终结果
show_final_result() {
log_info "=== 镜像创建完成 ==="
echo "镜像文件: $OUTPUT_IMG"
echo "文件大小: $(du -h $OUTPUT_IMG | cut -f1)"
echo "实际使用: $(sudo dumpe2fs $OUTPUT_IMG 2>/dev/null | grep 'Block count' | head -1 | awk '{print $3}') 个块"
echo "可用空间: $(sudo dumpe2fs $OUTPUT_IMG 2>/dev/null | grep 'Free blocks' | head -1 | awk '{print $3}') 个块"
log_info "镜像可以用于 RK3399 开发板了!"
}
# 主函数
main() {
log_info "开始创建根文件系统镜像..."
# 检查必要命令
check_command genext2fs genext2fs
check_command e2fsck e2fsprogs
check_command resize2fs e2fsprogs
# 检查根文件系统目录是否存在
if [ ! -d "$ROOTFS_DIR" ]; then
log_error "根文件系统目录 $ROOTFS_DIR 不存在"
exit 1
fi
# 检查并创建挂载点
if [ ! -d "$MOUNT_POINT" ]; then
log_info "创建挂载点 $MOUNT_POINT"
sudo mkdir -p $MOUNT_POINT
fi
# 步骤1:计算根文件系统大小
log_info "计算根文件系统大小..."
SIZE_KB=$(sudo du -sk $ROOTFS_DIR | cut -f1)
SIZE_MB=$((SIZE_KB / 1024))
log_info "检测到根文件系统大小: ${SIZE_KB}KB (约 ${SIZE_MB}MB)"
# 步骤2:计算需要的块数(增加30%余量)
BLOCKS=$((SIZE_KB * 130 / 100))
BLOCKS_MB=$((BLOCKS / 1024))
log_info "使用 ${BLOCKS} 个块创建镜像 (约 ${BLOCKS_MB}MB)"
# 步骤3:创建镜像
log_info "使用 genext2fs 创建镜像..."
sudo genext2fs -b $BLOCKS -d $ROOTFS_DIR $OUTPUT_IMG
# 检查是否创建成功
if [ $? -ne 0 ]; then
log_warn "指定块数创建失败,尝试自动计算大小..."
sudo genext2fs -d $ROOTFS_DIR $OUTPUT_IMG
if [ $? -ne 0 ]; then
log_error "自动计算大小也失败,尝试使用 dd+mkfs 方法..."
create_img_with_dd
fi
fi
# 步骤4:检查文件系统
log_info "检查文件系统..."
sudo e2fsck -f -y $OUTPUT_IMG
# 步骤5:优化镜像大小
log_info "优化镜像大小..."
sudo resize2fs -M $OUTPUT_IMG
# 步骤6:验证镜像(包含完整检查)
verify_image
# 步骤7:显示最终结果
show_final_result
}
# 运行主函数
main "$@"
- 执行脚本
chmod +x make_rootfs_img.sh
./make_rootfs_img.sh
[INFO] 开始创建根文件系统镜像...
[INFO] 创建挂载点 /mnt/rootfs_test
[INFO] 计算根文件系统大小...
[INFO] 检测到根文件系统大小: 1343128KB (约 1311MB)
[INFO] 使用 1746066 个块创建镜像 (约 1705MB)
[INFO] 使用 genext2fs 创建镜像...
[INFO] 检查文件系统...
e2fsck 1.45.5 (07-Jan-2020)
文件系统没有 UUID;正在创建新的 UUID。
第 1 遍:检查 inode、块,和大小
第 2 遍:检查目录结构
第 3 遍:检查目录连接性
第 4 遍:检查引用计数
第 5 遍:检查组概要信息
rootfs.img:11030/11984 文件(0.6% 为非连续的),1421166/1746066 块
[INFO] 优化镜像大小...
resize2fs 1.45.5 (07-Jan-2020)
将 rootfs.img 上的文件系统调整为 1599428 个块(每块 1k)。
rootfs.img 上的文件系统大小已经调整为 1599428 个块(每块 1k)。
[INFO] 开始验证镜像...
[INFO] === 镜像根目录内容 ===
总用量 87693
drwxr-xr-x 17 root root 1024 10月 22 17:58 .
drwxr-xr-x 6 root root 4096 10月 22 17:55 ..
-rw------- 1 root root 16316 10月 21 20:49 .ash_history
drwxrwxr-x 2 liu liu 2048 10月 22 17:58 bin
drwxrwxr-x 2 liu liu 1024 5月 23 20:51 dev
drwxrwxr-x 3 liu liu 1024 10月 22 17:58 etc
drwxrwxr-x 2 liu liu 1024 10月 21 20:47 home
drwxrwxr-x 10 liu liu 3072 10月 22 17:58 lib
-rwxrwxr-x 1 liu liu 5888 10月 20 11:58 linuxrc
drwx------ 2 root root 89398272 10月 22 17:55 lost+found
drwxrwxr-x 2 liu liu 1024 5月 23 20:50 mnt
drwxrwxr-x 4 liu liu 1024 10月 21 19:30 opt
drwxrwxr-x 2 liu liu 1024 5月 23 20:50 proc
drwxrwxr-x 2 liu liu 1024 5月 23 20:50 root
drwxrwxr-x 2 liu liu 2048 5月 23 18:01 sbin
drwxrwxr-x 2 liu liu 1024 5月 23 20:50 sys
drwxrwxr-x 3 liu liu 1024 10月 21 20:47 tmp
drwxrwxr-x 4 liu liu 1024 5月 23 18:01 usr
drwxrwxr-x 2 liu liu 1024 5月 23 20:50 var
[INFO] === 磁盘使用情况 ===
文件系统 容量 已用 可用 已用% 挂载点
/dev/loop14 1.6G 1.4G 97M 94% /mnt/rootfs_test
[INFO] === 关键目录检查 ===
[INFO] ✓ 目录 bin 存在
[INFO] ✓ 目录 etc 存在
[INFO] ✓ 目录 lib 存在
[INFO] ✓ 目录 usr 存在
[INFO] ✓ 目录 sbin 存在
[INFO] ✓ 目录 dev 存在
[INFO] ✓ 目录 proc 存在
[INFO] ✓ 目录 sys 存在
[INFO] ✓ 目录 tmp 存在
[INFO] ✓ 目录 var 存在
[INFO] ✓ 目录 home 存在
[INFO] ✓ 目录 root 存在
[INFO] 镜像验证完成!
[INFO] 执行文件系统完整性检查...
e2fsck 1.45.5 (07-Jan-2020)
第 1 遍:检查 inode、块,和大小
第 2 遍:检查目录结构
第 3 遍:检查目录连接性
第 4 遍:检查引用计数
第 5 遍:检查组概要信息
rootfs.img:11030/11032 文件(0.8% 为非连续的),1420877/1599428 块
[INFO] === 镜像创建完成 ===
镜像文件: rootfs.img
文件大小: 1.6G
实际使用: 1599428 个块
可用空间: 178551 个块
[INFO] 镜像可以用于 RK3399 开发板了!
- 复制到Windows共享文件夹中并烧录进开发板


2.NFS文件系统挂接
2.1 NFS网络文件系统
NFS网络文件系统(Network File System),由Sun公司开发,这个服务是通过网络的方式来共享文件系统。
2.2 Ubuntu安装NFS服务
Ubuntu上默认是没有安装Ubuntu nfs服务器的,因此我们首先安装Ubuntu nfs服务器端:
安装nfs服务器:
sudo apt-get install nfs-common nfs-kernel-server
创建nfs共享目录:(如果已经存放就不用创建)
mkdir /home/liu/linux/rk3399/rootfs -p
2.3 配置Linux系统NFS服务
- 添加nfs共享目录:编辑/etc/exports
cd /home/liu/linux/rk3399/rootfs/
sudo vi /etc/exports
打开/etc/exports配置文件,添加以下内容:
/home/liu/linux/rk3399/rootfs *(rw,no_root_squash,sync,no_subtree_check)
配置说明:
/home/liu/linux/rk3399/rootfs 自己的根文件系统绝对路径
* 任意IP都可以连接这目录
sync 同步数据
rw 可读可写
no_root_squash 登陆进来的用户具有像root帐对这个目录的操作权限
添加完成后,让目录生效,同查看结果:
sudo exportfs -av
exporting *:/home/liu/linux/rk3399/rootfs
如果输出有警告,错误的,请检查文件内容格式是否正确(*号后面不能有空格)
- 启动nfs服务
sudo service nfs-kernel-server restart
其他相关命令:
sudo service nfs-kernel-server stop //停止nfs服务
sudo service nfs-kernel-server start //开启nfs服务
sudo service nfs-kernel-server status //查看nfs服务
设置nfs服务开启自启动
- 打开/etc/rc.local文件
sudo vi /etc/rc.local
- 在exit0前面添加启动命令
service nfs-kernel-server restart
- 关Limux防火墙
一般情况下防火墙会拦截NFS,需要配置让NFS可以通过,但是最简单方法关闭它Ubuntu系统:
sudo ufw disable
防火墙在系统启动时自动禁用
sudo ufw status
状态:不活动
说明:如果要开启防火墙则使用sudo ufw enable
- 本机nfs挂载测试
可以使用以下命令把它挂载在本机目录,例如将/home/liu/linux/rk3399/rootfs挂载到/mnt/nfstest下
sudo mkdir /mnt/nfstest/ -p
cd /mnt/nfstest/
sudo mount -t nfs localhost:/home/liu/linux/rk3399/rootfs /mnt/nfstest/
查看系统挂载情况:
- 方法一:
showmount -e localhost
Export list for localhost:
/home/liu/linux/rk3399/rootfs *
- 方法二:运行df命令查看是否挂载成功
df
文件系统 1K-块 已用 可用 已用% 挂载点
udev 939116 0 939116 0% /dev
……
localhost:/home/liu/linux/rk3399/rootfs 102107136 57384448 39489536 60% /mnt/nfstest
- 卸载:
sudo umount /mnt/nfstest
如果出现错误:umount.nfs4: /mnt/nfstest: device is busy,使用下面命令:
sudo umount -lf /mnt/nfstest
2.4 配置虚拟机IP地址

如果没有网络可以尝试下面命令重启网络服务:
sudo systemctl restart NetworkManager
查看虚拟机网卡设备名及IP地址:(不同的电脑这里的设备可能会不同,我的ens33)
ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.1.111 netmask 255.255.255.0 broadcast 192.168.1.255
inet6 fe80::7ec6:d7a9:8cb5:3077 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:71:73:85 txqueuelen 1000 (以太网)
RX packets 1460 bytes 486248 (486.2 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 543 bytes 57121 (57.1 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
设置IP:
sudo ifconfig ens33 192.168.1.11 up
ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.1.11 netmask 255.255.255.0 broadcast 192.168.1.255
inet6 fe80::7ec6:d7a9:8cb5:3077 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:71:73:85 txqueuelen 1000 (以太网)
RX packets 1527 bytes 500786 (500.7 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 574 bytes 61950 (61.9 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
上面设置临时有效,重启会变化。如果想固定不变,可以使用静态IP配置方式。
方法一:命令
sudo vi /etc/netplan/01-network-manager-all.yaml
修改后内容如下:
1 # Let NetworkManager manage all devices on this system
2 network:
3 version: 2
4 renderer: NetworkManager
5 ethernets:
6 ens33: # 配置的网卡的名称
7 addresses: [192.168.1.11/24] # 配置的静态ip地址和掩码
8 optional: true
9 gateway4: 192.168.1.1 # 网关地址
10 nameservers:
11 addresses: [223.5.5.5] #DNS服务器
保存退出后应用配置:
sudo netplan apply
方法二:图形



根据自己的IP地址进行修改
2.5 配置开发板IP地址和环境变量
RK3399配套u-boot环境变量参数被获取方式被修改了,bootargs环境变量不再有作用,而是通过parameter.txt文件中的CMDLINE变量配置。
parameter.txt文件配置信息如下:
CMDLINE:console=ttyFIQ0 noinitrd root=/dev/nfs nfsroot=192.168.1.11: /home/liu/linux/rk3399/rootfs ip=192.168.1.123:192.168.1.11:192.168.1.1:255.255.255.0:eth0:off rw mtdparts=rk29xxnand:0x00002000@0x00002000(uboot),0x00002000@0x00004000(trust),0x00002000@0x00006000(misc),0x00006000@0x00008000(resource),0x00010000@0x0000e000(kernel),0x00010000@0x0001e000(boot),0x008a0000@0x00030000(rootfs),-@0x008d0000(userdata)
注意:上面的CMDLINE是一行,太长了自动换行显示,写时候注意不要换行。
2.6 挂接nfs文件系统
修改完成parameter.txt文件中的CMDLINE参数内容为NFS挂载参数后,进入loader模式,下载parameter.txt文件,重启开发板。

直接重启开发板,设置好环境变量。以下是部分启动信息:
U-Boot 2014.10-RK3399-06-03582-g62645e6fef (Aug 17 2022 - 18:53:42)
CPU: rk3399
WARNING: could not set reg FDT_ERR_BADOFFSET.
Starting kernel ...
[ 0.000000] Linux version 4.4.179 (liu@ubuntu) (gcc version 7.3.1 20180425 [linaro-7.3-2018.05 revision d29120a424ecfbc167ef90065c0eeb7f91977701] (Linaro GCC 7.3-2018.05) ) #1 SMP Fri May 23 15:56:02 CST 2025
[liu@liu ]# ls
bin etc lib mnt proc sbin tmp var
dev home linuxrc opt root sys usr
至此,开发板就可挂载Linux虚拟机上Ubuntu系统中自己制作的根文件系统了。
测试:
liu@ubuntu:test$ vi hello.c
liu@ubuntu:test$ aarch64-linux-gnu-gcc hello.c -o hello
liu@ubuntu:test$ cp hello /home/liu/linux/rk3399/rootfs/home/
[liu@liu home]# ./hello
hello linux!
通过NFS文件系统挂接的方式可以很方便地将编译完成的文件发送到开发板中,后期在Makefile文件中加入cp的命令可以make后便能复制到开发板中。
openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。
更多推荐


所有评论(0)