news 2026/7/31 3:09:36

嵌入式Linux开发:虚拟机与开发板高效文件传输方案全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
嵌入式Linux开发:虚拟机与开发板高效文件传输方案全解析

1. 项目缘起:为什么我们需要在虚拟机与开发板间传文件?

搞嵌入式开发的朋友,尤其是从单片机转向Linux应用或驱动开发的,几乎都绕不开一个场景:你的代码在虚拟机里的Linux系统上编写和编译,但最终要在一块真实的开发板上运行和调试。这个过程中,最频繁、最基础的操作就是文件传输。你可能需要把编译好的可执行文件、动态库、配置文件或者测试脚本,从虚拟机的Linux环境拷贝到开发板上。反过来,开发板上生成的日志、抓取的数据,也需要传回虚拟机进行分析。

这看似简单的一来一回,在实际操作中却可能成为效率的瓶颈,甚至是新手入门的“拦路虎”。直接用U盘倒腾?开发板往往没有USB Host接口,或者接口紧张。用串口一点点传?几兆的文件就能让你等到怀疑人生。所以,掌握几种高效、可靠的文件传输方法,是嵌入式Linux开发者的必备技能。今天,我们就来深入聊聊虚拟机与开发板间文件传输的几种主流方案,我会结合自己多年的踩坑经验,告诉你每种方法怎么用、什么时候用、以及有哪些必须注意的细节。

2. 网络基础:打通虚拟机和开发板的通信链路

在讨论具体传输方法之前,我们必须先解决一个前提问题:如何让虚拟机和开发板在网络上“看见”彼此。这是所有网络传输方式(NFS, TFTP, SCP等)的基础。通常有三种连接方式,每种方式下的网络配置逻辑完全不同。

2.1 方式一:开发板、虚拟机、宿主机三者同处一个局域网

这是最推荐,也是最常见的配置。你需要一个路由器(或交换机),并用网线将开发板、以及运行虚拟机的宿主机(你的物理电脑)都连接到这个路由器上。

  • 虚拟机网络设置:在VMware或VirtualBox中,将虚拟机的网络适配器设置为“桥接模式”(Bridged)。这个模式会让虚拟机从你的路由器那里直接获取一个IP地址,就像一台真实的、新接入局域网的电脑一样。
  • 查看IP地址:配置好后,启动虚拟机的Linux系统,在终端输入ifconfigip addr命令,查看网卡(通常是eth0或ens33)获取到的IP地址,例如192.168.1.105
  • 开发板IP设置:同样,通过串口登录开发板,使用ifconfig命令给开发板的网卡配置一个与虚拟机同网段的静态IP。例如,虚拟机是192.168.1.105,网关是192.168.1.1,那么可以设置开发板IP为192.168.1.200
    # 在开发板终端执行 ifconfig eth0 192.168.1.200 netmask 255.255.255.0 up route add default gw 192.168.1.1
  • 验证连通性:在虚拟机里ping 192.168.1.200,在开发板里ping 192.168.1.105。双向都能ping通,网络链路就打通了。

注意:桥接模式的成功与否,高度依赖宿主机物理网卡的驱动和状态。如果遇到虚拟机无法获取IP的情况,可以尝试在虚拟机设置中,将桥接的“复制物理网络连接状态”选项取消勾选,或者更换桥接到哪个具体的物理网卡(如果你有有线/无线多个网卡)。

2.2 方式二:开发板与虚拟机直连,宿主机作为“中转站”

在没有路由器的情况下,你可以用一根网线直接将开发板连接到宿主机电脑的网口。此时,虚拟机、开发板、宿主机三者将构成一个特殊的网络。

  • 虚拟机网络设置:使用“NAT模式”。这是虚拟机的默认模式,虚拟机会通过宿主机进行地址转换来访问外网,同时宿主机可以访问虚拟机。
  • 宿主机设置:关键步骤来了。你需要开启宿主机(Windows)的“Internet连接共享”功能。以Win10为例,进入“控制面板 -> 网络和 Internet -> 网络连接”,找到你用来连接开发板的那个“以太网”适配器(连接后通常显示“未识别的网络”),右键“属性”,在“共享”选项卡中,勾选“允许其他网络用户通过此计算机的Internet连接来连接”,并选择共享给虚拟机的那个虚拟网卡(VMware Network Adapter VMnet8)。
  • IP配置:开启共享后,宿主机用于直连的网卡IP会被强制设为192.168.137.1。接着,你需要手动将开发板的IP设置为同一网段,例如192.168.137.100,网关设置为192.168.137.1。虚拟机的IP则由NAT服务分配,通常也是192.168.xxx.xxx网段,但和137网段不同。
  • 通信逻辑:经过这样配置,开发板(192.168.137.100)可以ping通宿主机(192.168.137.1),也可以ping通虚拟机(192.168.xxx.xxx。因为宿主机充当了路由器。但虚拟机可能无法直接ping通开发板,不过这通常不影响从虚拟机向开发板发起传输(如SCP、TFTP PUT)。

这种方式配置稍复杂,且共享功能有时不太稳定,但作为临时或移动开发方案是可行的。

2.3 方式三:纯虚拟网络(仅用于特定测试)

还有一种“主机模式”(Host-Only),它创建一个仅包含宿主机和虚拟机的封闭网络,开发板无法接入。这种模式不适合与真实开发板通信,仅用于多虚拟机之间组网测试,这里就不展开了。

核心心得强烈建议使用“桥接模式+路由器”的方案一。它最符合真实网络环境,配置简单,稳定性高,也是后续搭建NFS等服务的基石。在开始任何文件传输前,请务必用ping命令确认双向网络可达。

3. 方案对比与选型:五种传输方法详解

网络打通后,我们就可以根据不同的使用场景,选择合适的传输工具了。下面这个表格概括了五种主流方法的核心特点:

传输方式核心原理适用场景优点缺点是否需要开发板侧服务
SCP/SFTP基于SSH协议的安全文件复制传输单个或少量文件,如部署最终程序安全、加密;无需额外安装服务端(若已有SSH)每次需手动命令;不适合频繁修改的目录同步需要开启SSH服务端
TFTP简单的基于UDP的文件传输协议传输内核镜像、设备树等启动文件;无SSH环境时协议简单,客户端极小,常内置在Bootloader中不安全(无加密)、不可靠(UDP)、功能单一需要搭建TFTP服务器(通常在宿主机/虚拟机)
NFS网络文件系统,挂载远程目录开发阶段,需频繁修改/调试代码时透明访问,如同本地目录;极适合联调配置稍复杂;性能依赖网络;有安全风险需要搭建NFS服务器(通常在宿主机/虚拟机)
FTP传统的文件传输协议作为SCP的备选,或与旧系统交互图形化客户端丰富,操作直观不如SCP安全,配置比SCP复杂需要搭建FTP服务器
串口传输通过串口协议直接发送数据网络未配置好时的应急方案;传输极小文件无需网络,仅需串口线;任何阶段都可用速度极慢(以KB/s计);需要专用工具需要开发板侧有接收工具(如rz

接下来,我们重点深入最常用、也最容易出问题的三种:NFS、TFTP和SCP。

4. NFS实战:将虚拟机目录“映射”到开发板

NFS是我在开发调试阶段的首选。它的魅力在于,你在虚拟机里修改并保存代码后,在开发板上就能直接运行,省去了反复拷贝的繁琐。感觉就像是把开发板的/mnt目录,直接“伸”到了你的虚拟机里。

4.1 在虚拟机(服务端)搭建NFS服务器

假设你的虚拟机是Ubuntu。

  1. 安装NFS服务器软件包

    sudo apt update sudo apt install nfs-kernel-server
  2. 创建共享目录并设置权限:创建一个你打算共享的目录,例如/home/yourname/share

    mkdir ~/share sudo chown nobody:nogroup ~/share # 修改所属,避免权限问题 sudo chmod 777 ~/share # 为测试方便,给足权限

    注意:生产环境绝不能使用777权限,这里仅为简化调试。应根据实际用户和组进行精细的权限控制。

  3. 配置NFS导出目录:编辑NFS的配置文件/etc/exports

    sudo vim /etc/exports

    在文件末尾添加一行(请将192.168.1.0/24替换为你的实际局域网网段):

    /home/yourname/share 192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash)
    • rw: 读写权限。
    • sync: 同步写入,更可靠。
    • no_subtree_check: 提高性能,禁用子树检查。
    • no_root_squash:重要!让客户端的root用户保持root权限。在开发板调试时经常需要root,不开启此项会导致权限不足。但这也带来了安全风险,请仅在可信网络中使用。
  4. 使配置生效并启动服务

    sudo exportfs -a # 重新导出所有配置 sudo systemctl restart nfs-kernel-server sudo systemctl enable nfs-kernel-server # 设置开机自启
  5. 验证服务:可以本地先挂载测试一下。

    sudo mount -t nfs 127.0.0.1:/home/yourname/share /mnt

    如果能在/mnt下看到文件,说明服务端配置基本正确。

4.2 在开发板(客户端)挂载NFS目录

  1. 确保开发板内核支持NFS客户端:通常标准Linux内核都已包含。可以检查/proc/filesystems是否有nfsnfs4

    cat /proc/filesystems | grep nfs
  2. 安装NFS客户端工具(如果必要):有些精简的根文件系统可能没带mount.nfs命令,需要安装nfs-common包(通过包管理器,或编译进根文件系统)。

  3. 创建本地挂载点

    mkdir /mnt/nfs
  4. 执行挂载命令

    mount -t nfs -o nolock,vers=3 192.168.1.105:/home/yourname/share /mnt/nfs
    • -o nolock:极其关键!禁用文件锁。在低版本NFS或某些网络环境下,不加这个参数会导致挂载卡死或极其缓慢。
    • vers=3: 指定使用NFS v3协议。v4协议更强大但配置更复杂,v3在局域网内简单可靠。如果服务端是v4,客户端也需要对应。
    • 192.168.1.105: 你的虚拟机IP。
  5. 验证挂载:使用df -hmount命令查看挂载情况。进入/mnt/nfs,应该能看到虚拟机~/share目录下的所有文件。现在,你在虚拟机里编译一个程序到~/share/hello,在开发板上就可以直接/mnt/nfs/hello运行了。

4.3 NFS常见故障排查

  • 挂载失败:Connection refused:检查虚拟机防火墙是否关闭(sudo ufw disable或配置防火墙放行2049端口),检查NFS服务是否正常运行(sudo systemctl status nfs-kernel-server)。
  • 挂载失败:RPC Error:可能是RPC相关服务(rpcbind)未启动。确保rpcbind服务正在运行。
  • 挂载成功但操作卡顿或权限被拒绝
    • 首先检查nolock选项是否已添加。
    • 检查/etc/exports配置的IP网段是否正确,以及权限选项(尤其是no_root_squash)。
    • 尝试在挂载时增加-o intr选项,允许中断挂载操作。
  • 客户端CPU负载高:这通常与网络丢包、重传或lockd锁管理有关。确保网络稳定,尝试在服务端/etc/exports和客户端挂载选项中都加上async(异步写入,有数据丢失风险,仅调试用)和noac(禁止属性缓存),可以降低客户端负载,但可能影响性能一致性。

个人经验:NFS挂载的稳定性与网络质量强相关。使用质量差的网线或WiFi桥接,可能会遇到偶发的“卡死”(ls命令都无响应),此时只能强制卸载(umount -l /mnt/nfs)后重新挂载。对于关键调试阶段,建议用网线直连路由器。

5. TFTP实战:向Bootloader或最小系统传输文件

TFTP通常用于更“底层”的场景。比如你的开发板Bootloader(如U-Boot)支持网络启动,你可以用TFTP将内核镜像(zImage)和设备树(.dtb)文件快速下载到开发板的内存中运行,而无需烧写Flash,极大加快启动镜像的调试速度。

5.1 在虚拟机(服务端)搭建TFTP服务器

  1. 安装TFTP服务器

    sudo apt update sudo apt install tftpd-hpa

    tftpd-hpa是较常用且维护良好的一个TFTP服务器实现。

  2. 配置TFTP服务器:编辑其配置文件/etc/default/tftpd-hpa

    sudo vim /etc/default/tftpd-hpa

    修改为类似以下内容:

    TFTP_USERNAME="tftp" TFTP_DIRECTORY="/var/lib/tftpboot" TFTP_ADDRESS=":69" TFTP_OPTIONS="--secure --create"
    • TFTP_DIRECTORY: 这是TFTP服务的根目录,客户端只能访问这个目录下的文件。
    • --secure: 将文件访问限制在TFTP_DIRECTORY内。
    • --create: 允许客户端上传文件(创建新文件)。
  3. 创建目录并设置权限

    sudo mkdir -p /var/lib/tftpboot sudo chown -R tftp:tftp /var/lib/tftpboot sudo chmod -R 777 /var/lib/tftpboot # 为方便,开放权限
  4. 重启服务

    sudo systemctl restart tftpd-hpa sudo systemctl enable tftpd-hpa
  5. 放置测试文件:将你需要传输的文件(如uImage)拷贝到/var/lib/tftpboot目录下。

    sudo cp ~/your-kernel/uImage /var/lib/tftpboot/

5.2 在开发板(客户端)使用TFTP

场景一:在完整的Linux系统下使用。如果开发板已经启动了Linux系统,并且有tftp客户端命令(Busybox通常包含):

# 从服务器下载文件到当前目录 tftp -g -r uImage 192.168.1.105 # 上传文件到服务器 tftp -p -l localfile 192.168.1.105

场景二:在U-Boot中使用。这是TFTP最经典的应用。在U-Boot命令行下:

# 首先设置开发板IP和服务器IP setenv ipaddr 192.168.1.200 setenv serverip 192.168.1.105 # 将服务器上的uImage下载到开发板内存的0x82000000地址 tftp 0x82000000 uImage # 然后可以用bootm等命令启动它 bootm 0x82000000

5.3 TFTP常见问题

  • 超时或传输失败:TFTP基于UDP,对网络丢包敏感。确保防火墙放行了UDP 69端口(sudo ufw allow 69/udp)。在U-Boot中,可以尝试setenv tftpblocksize 1460setenv tftpblocksize 512来调整块大小,以适应不同的网络环境。
  • 权限错误:确保TFTP目录及其内部文件对tftp用户或所有人有读取(和写入,如果需要上传)权限。
  • 文件找不到:确认文件名完全正确,并且文件确实存在于TFTP服务器的根目录下。TFTP没有复杂的目录浏览功能。

个人经验:TFTP服务器的配置本身不难,难点往往在于U-Boot下的网络驱动是否正常。在U-Boot中,先用ping命令测试与服务器的连通性。如果ping不通,后面的tftp肯定失败。此时需要检查U-Boot中网络相关环境变量(ipaddr,serverip,netmask,gatewayip,ethaddr)是否正确设置。

6. SCP/RSYNC实战:安全可靠的“搬运工”

当你的开发板已经运行着完整的Linux,并且开启了SSH服务(通常通过安装openssh-server实现),那么SCP(基于SSH)就是最顺手、最安全的文件传输工具。RSYNC则是在SCP基础上的增强,支持增量同步,非常适合传输大目录或定期备份。

6.1 基础SCP传输

假设开发板IP是192.168.1.200,用户是root

  • 从虚拟机传文件到开发板(推)
    scp /path/to/local/file root@192.168.1.200:/path/on/board/
  • 从开发板拉文件到虚拟机(拉)
    scp root@192.168.1.200:/path/on/board/file /local/path/
  • 传输整个目录:使用-r递归选项。
    scp -r /local/dir root@192.168.1.200:/remote/path/

6.2 使用RSYNC进行智能同步

RSYNC的强大在于它只传输发生变化的部分。对于含有大量文件的项目目录,首次传输后,后续修改的同步速度极快。

  • 基本同步(将本地目录同步到开发板,使开发板目录与本地一致)

    rsync -avz --progress /local/project/ root@192.168.1.200:/remote/project/
    • -a: 归档模式,保持文件属性。
    • -v: 详细输出。
    • -z: 传输时压缩。
    • --progress: 显示传输进度。
    • 注意:源路径/local/project/后面的/很重要。有/表示同步目录内的内容,没有/则表示同步目录本身。
  • 删除开发板上多余文件(使开发板目录成为本地目录的精确镜像):增加--delete选项,但要极其小心,误操作会导致数据丢失。

    rsync -avz --delete --progress /local/project/ root@192.168.1.200:/remote/project/
  • 排除某些文件/目录

    rsync -avz --exclude='*.o' --exclude='.git' --progress /local/project/ root@192.168.1.200:/remote/project/

6.3 SSH免密登录提升效率

反复输入密码很麻烦。可以配置SSH密钥对实现免密登录。

  1. 在虚拟机生成密钥对(如果还没有)

    ssh-keygen -t rsa

    一路回车,会在~/.ssh/下生成id_rsa(私钥)和id_rsa.pub(公钥)。

  2. 将公钥上传到开发板

    ssh-copy-id root@192.168.1.200

    输入一次密码后,以后使用SCP或RSYNC就不再需要密码了。

个人经验:对于日常开发,我通常会结合使用NFS和RSYNC。在代码剧烈变化、需要频繁编译调试的阶段,使用NFS挂载。当代码趋于稳定,需要部署到测试环境或进行备份时,使用RSYNC进行一次性的、精确的目录同步。SCP则用于零散的、一次性的文件传输。把SSH免密配置好,能节省大量时间。

7. 串口传输:最后的备用方案

当网络完全无法配置通,或者开发板处于最原始的引导状态时,串口传输是唯一的希望。常用的工具有minicom(配合sz/rz命令)或picocom

  1. 开发板侧:需要确保文件系统包含了lrzsz工具包,这样才有rz(接收)和sz(发送)命令。
  2. 虚拟机侧:使用minicompicocom连接开发板串口。
  3. 传输文件
    • 在开发板执行rz -y,然后 minicom 中按Ctrl+A,再按S,选择zmodem协议,并指定要发送的文件。
    • 从开发板发送文件到虚拟机,在开发板执行sz filename,然后在 minicom 中选择接收。

串口传输速度通常只有115200波特率甚至更低,实际传输速率约每秒10KB左右,传输一个几兆的内核镜像需要数分钟,因此仅作为应急手段

8. 总结与个人建议

回顾这几种方法,没有绝对的“最佳”,只有最适合当前场景的“最优”。

  • 早期Bootloader调试、烧录:首选TFTP。它集成在U-Boot中,是启动内核、设备树最快捷的方式。
  • 应用程序开发与联调阶段:强烈推荐NFS。代码即改即生效,调试效率提升不止一个数量级。务必记牢nolockno_root_squash这两个关键选项。
  • 部署、备份或一次性传输:使用SCP/RSYNC。安全、可靠,配合SSH免密和RSYNC增量同步,体验非常好。
  • 网络未通或最小系统:只能依靠串口。慢,但能救命。

在我自己的项目流程里,通常是这样的:先用TFTP将新编译的内核、设备树下载到开发板内存启动,快速验证启动是否正常。进入系统后,通过NFS挂载我的项目代码目录,进行深入的应用程序调试和驱动测试。当所有功能稳定,需要制作最终的系统镜像时,我会用RSYNC将完整的文件列表同步到开发板的Flash存储中,进行固化测试。

最后一个小技巧:给你的虚拟机和开发板设置静态IP,或者在你的路由器上为它们的MAC地址分配固定的DHCP地址。这样可以避免IP变化导致每次都要修改挂载命令或配置文件的麻烦。文件传输是嵌入式开发的基础设施,花点时间把它们搭建和调试顺畅,后续的整个开发流程都会变得行云流水。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/31 3:09:27

单片机心形流水灯:27种模式实现与状态机编程实战

1. 项目概述与核心价值“心形流水灯——27种流水方式”这个项目,对于任何一个单片机初学者,尤其是从51单片机入门的朋友来说,绝对是一个集趣味性、挑战性和教学性于一体的“黄金练手项目”。它听起来浪漫,做起来过瘾,学…

作者头像 李华
网站建设 2026/7/31 3:09:21

TCP四次挥手详解:从状态机到TIME_WAIT的工程实践

1. 从一次“优雅”的断线说起:为什么挥手需要四次?如果你写过网络程序,或者抓过包,一定见过这个场景:客户端和服务端聊得正欢,突然一方想结束对话了。你可能会想,直接关掉连接不就行了&#xff…

作者头像 李华
网站建设 2026/7/31 3:08:20

OpenClaw 内置全套运行依赖,省去环境搭建繁琐步骤实操分享

🔹 工具基础介绍 OpenClaw 是开源生态中一款实用性极强的本地智能工具。它凭借本地离线运行、可视化图形操作和任务自动化三大核心特性,赢得了广泛用户的青睐。与普通的在线对话 AI 工具不同,OpenClaw 是一款能够直接操控本机软硬件的智能数…

作者头像 李华
网站建设 2026/7/31 3:07:15

AI论文写作工具测评:9款神器提升学术效率

1. 论文写作工具测评背景与价值去年指导表弟写专科毕业论文时,发现市面上突然涌现出大量号称"AI论文神器"的工具。作为经历过学术写作煎熬的人,我花了三周时间深度测试了23款相关软件,最终筛选出9款真正能提升写作效率的工具。这些…

作者头像 李华
网站建设 2026/7/31 3:03:10

React Native Module 注册流程

React Native 的 Native Module 注册流程,指的是 JavaScript 层如何调用 Android/iOS 原生代码(Java/Kotlin/Obj-C/Swift)的过程。整体流程:JavaScript|| NativeModules.xxx↓ React Native Bridge|↓ Module Registry|↓ Native …

作者头像 李华
网站建设 2026/7/31 2:58:42

如何用Bili2Text一键将B站视频转为文字稿:完整免费教程

如何用Bili2Text一键将B站视频转为文字稿:完整免费教程 【免费下载链接】bili2text Bilibili视频转文字,一步到位,输入链接即可使用 项目地址: https://gitcode.com/gh_mirrors/bi/bili2text 还在为整理B站视频内容而烦恼吗&#xff1…

作者头像 李华