RK3568开发板TFTP网络烧写Linux镜像实战指南
2026/6/5 16:04:12 网站建设 项目流程

1. 项目概述与核心价值

如果你手头有一块飞凌嵌入式的RK3568开发板,正琢磨着怎么把一个新的Linux系统镜像给“灌”进去,那么这篇基于真实项目踩坑记录的TFTP烧写指南,就是为你准备的。我最近在做一个工业边缘计算网关的预研,核心硬件选型就是这块OK3568-C开发板,它的国产化、工业级可靠性以及内置的NPU算力是吸引我的关键。在开发初期,频繁地更新内核和文件系统是家常便饭,如果每次都依赖读卡器或者USB烧录,效率太低,而且对于已经集成到机箱里的设备来说也不现实。这时候,通过网络进行烧写就成了刚需。

TFTP(Trivial File Transfer Protocol)协议虽然简单古老,但在嵌入式开发领域,尤其是在U-Boot环境下,它依然是进行网络镜像更新的黄金标准。它不依赖复杂的认证,协议开销小,特别适合在引导加载器这种资源有限的环境下进行大文件的可靠传输。整个过程的核心思路很清晰:开发板启动到U-Boot阶段,配置好网络,从同一局域网内的一台TFTP服务器上下载镜像文件,然后直接写入到eMMC的指定分区。听起来简单,但魔鬼藏在细节里,从网络环境搭建、U-Boot命令参数到分区表解读,每一步都有需要注意的地方。

本文将基于瑞芯微RK3568处理器、Linux 4.19.206内核的标准环境,手把手带你走通整个TFTP烧写流程。无论你是刚接触这块板子的新手,还是想寻找一种更高效的固件更新方法的老手,这篇融合了实操步骤、原理解析和避坑经验的指南,都能让你在半小时内建立起可靠的网络烧写能力,显著提升后续的开发调试效率。

2. 环境准备与核心原理拆解

在动手敲命令之前,把环境理清楚、把原理搞明白,能避免至少80%的“玄学”问题。TFTP烧写不是魔法,它是一套标准操作在特定硬件平台上的具体实现。

2.1 硬件与网络拓扑设计

我使用的硬件是飞凌嵌入式OK3568-C开发板,它采用了“核心板+底板”的设计。核心板集成了RK3568 SoC、LPDDR4内存和eMMC存储,底板则提供了丰富的接口。这次烧写主要用到两个关键接口:Type-C Debug口千兆以太网口

  • Type-C Debug口:这个口子集成了USB转串口芯片(通常是CP2102或FTDI方案),你直接用一根USB-C数据线连接开发板和电脑,电脑上就会识别出一个串口设备。它的作用是提供U-Boot和内核的控制台(Console),所有命令的输入和信息的输出都通过它。默认参数是115200波特率,8位数据位,1位停止位,无校验位。
  • 千兆以太网口:开发板通常有1-2个网口。我们用一个网口来连接TFTP服务器所在的网络。为了获得最简单、最稳定的传输环境,我强烈推荐使用桥接(Bridged)模式

网络拓扑详解: 在我的测试环境中,TFTP服务器运行在一台Ubuntu 20.04的虚拟机上(使用VMware Workstation)。我让这个Ubuntu虚拟机的网络适配器设置为“桥接模式”,这样虚拟机就会像一台真实的物理机一样,直接连接到你的物理局域网中,获取一个和开发板同网段的IP地址。然后,用一根网线,直接将开发板的以太网口(例如ETH0)连接到你的路由器或交换机上。这样,开发板、Ubuntu虚拟机、以及你的宿主机(Windows/Mac)都处于同一个局域网内,三者可以互相ping通。这种拓扑延迟最低,也最不容易出现防火墙或路由问题。

注意:很多朋友喜欢用“NAT模式”让虚拟机上网,但这会导致虚拟机和开发板不在同一个网段,需要额外配置路由,非常麻烦。在嵌入式网络烧写场景下,请务必使用“桥接模式”。

2.2 软件与镜像准备

服务器端和镜像文件也需要提前备好。

  1. TFTP服务器安装与配置(Ubuntu)

    # 1. 安装tftp-hpa(服务器)和tftpd-hpa(守护进程) sudo apt update sudo apt install tftp-hpa tftpd-hpa -y # 2. 创建TFTP服务器目录并赋予权限 sudo mkdir -p /tftpboot sudo chmod -R 777 /tftpboot sudo chown -R nobody:nogroup /tftpboot # 3. 配置TFTP服务 sudo vim /etc/default/tftpd-hpa

    将文件内容修改为:

    TFTP_USERNAME="tftp" TFTP_DIRECTORY="/tftpboot" TFTP_ADDRESS=":69" TFTP_OPTIONS="--secure --create"

    --secure表示限制在指定目录内,--create允许客户端上传文件。

    # 4. 重启服务并设置开机自启 sudo systemctl restart tftpd-hpa sudo systemctl enable tftpd-hpa # 5. 检查服务状态和防火墙 sudo systemctl status tftpd-hpa sudo ufw status # 如果防火墙开启,需要放行69端口: sudo ufw allow 69/udp
  2. 系统镜像准备: 你需要从飞凌嵌入式的官方资料包中获取或自己编译生成两个核心镜像文件:

    • boot.img:引导镜像,包含了Linux内核(zImage或Image)、设备树二进制文件(dtb)以及可能的RAM磁盘(initramfs)。它负责最基础的硬件初始化和加载根文件系统。
    • rootfs.img:根文件系统镜像,包含了完整的Linux目录结构(/bin, /etc, /lib, /usr等)以及你的应用程序。它被挂载为系统的根目录“/”。 将这两个.img文件复制到Ubuntu的/tftpboot目录下。

2.3 U-Boot与TFTP协议协同工作原理

理解这个过程,能让你在出问题时快速定位。

  1. 开发板上电:CPU从eMMC的固定位置(通常是0地址)加载U-Boot。
  2. U-Boot初始化:U-Boot初始化CPU、DDR、基础时钟、以及以太网控制器(RK3568的fe2a0000)。
  3. 网络配置:我们在U-Boot命令行中,通过setenv设置ipaddr(开发板IP)、serverip(TFTP服务器IP)、netmaskgatewayip等环境变量。这些变量告诉U-Boot:“我是谁,我要找谁”。
  4. TFTP下载:当执行tftptftpflash命令时,U-Boot的TFTP客户端会向serverip的69端口发送一个读请求(RRQ),请求下载指定的文件名(如boot.img)。
  5. 数据传输:服务器将文件分割成一个个数据块(默认512字节),依次发送。U-Boot每收到一个块,会回复一个ACK确认包,并写入指定的内存地址(如0x09400000)。这是一个非常简单的“发送-确认”机制。
  6. 写入存储:对于tftpflash命令,U-Boot在内存中接收完整个镜像后,会调用MMC/SD驱动,将内存中的数据按块(block)写入到eMMC的指定分区。这个写入过程会进行ECC校验,确保数据完整性。
  7. 重启验证:烧写完成后重启,U-Boot会从更新后的boot分区加载新内核,并尝试挂载新的rootfs分区。

关键点tftpflash是飞凌嵌入式在标准U-Boot上集成的自定义命令,它把tftp下载和mmc write写入两个步骤合并了,并且自动识别分区名,非常方便。其内部逻辑是:tftp [loadaddr] [filename]->mmc write [loadaddr] [partition_name]

3. 详细实操步骤与命令解析

现在,我们进入实战环节。请确保你的开发板、串口终端、网络都已按上一节描述连接就绪。

3.1 连接串口与进入U-Boot

  1. 使用USB-C线连接开发板的Debug口和电脑。
  2. 打开串口终端软件(如MobaXterm、SecureCRT、PuTTY或简单的screen/minicom)。
  3. 选择正确的串口端口(Windows在设备管理器中查看,Linux通常是/dev/ttyUSB0),设置波特率为115200,数据位8,停止位1,无校验,无流控。
  4. 给开发板上电,同时在终端里快速敲击键盘的空格键回车键。这会打断U-Boot的自动启动流程,进入U-Boot的命令行界面。成功后会看到提示符:=>

3.2 配置U-Boot网络环境变量

这是确保网络通信的基石。请根据你的实际网络规划修改IP地址。

# 1. 设置开发板的MAC地址。每个设备必须唯一,否则网络会冲突。 # 通常板子会有默认值,但最好显式设置。格式为XX:XX:XX:XX:XX:XX => setenv ethaddr aa:bb:cc:dd:ee:ff # 2. 设置开发板的静态IP地址。必须与TFTP服务器在同一网段。 # 本例中服务器是172.16.0.177,开发板设为172.16.0.176 => setenv ipaddr 172.16.0.176 # 3. 设置子网掩码。根据你的局域网情况设置,C类常用255.255.255.0,B类常用255.255.0.0 => setenv netmask 255.255.0.0 # 4. 设置网关。如果TFTP服务器在同一网段,可以不设或设为路由器IP。 => setenv gatewayip 172.16.0.1 # 5. 保存环境变量到eMMC的ENV分区。非常重要!否则重启后配置丢失。 => saveenv Saving Environment to ENV_BLK... Writing to mmc(0)... done

3.3 网络连通性测试

配置完一定要测试,这是排除网络问题的关键。

# 1. 首先ping一下你的宿主机(运行VMware的电脑),确保开发板能出得去。 => ping 172.16.0.77 ethernet@fe2a0000 Waiting for PHY auto negotiation to complete. done Using ethernet@fe2a0000 device host 172.16.0.77 is alive # 看到`is alive`表示成功 # 2. 关键一步:ping TFTP服务器(Ubuntu虚拟机)的IP。 => ping 172.16.0.177 Using ethernet@fe2a0000 device host 172.16.0.177 is alive # 必须成功! # 3. 设置TFTP服务器的IP地址环境变量。 => setenv serverip 172.16.0.177 => saveenv

实操心得:如果ping服务器失败,别慌,按这个顺序排查:

  1. 物理层:网线是否插好?开发板网口指示灯是否亮?尝试换根网线。
  2. 虚拟机网络:确认VMware网络连接模式是否为“桥接模式”,并且是“复制物理网络连接状态”。可以尝试在Ubuntu里ping一下开发板的IP(172.16.0.176),看是否双向可达。
  3. 防火墙:关闭Ubuntu防火墙或放行UDP 69端口:sudo ufw allow 69/udp
  4. IP冲突:检查ipaddrserverip是否确实在同一网段,且没有被其他设备占用。

3.4 查看eMMC分区表

在烧写前,必须知道我们要把镜像写到哪里。RK3568开发板通常使用GPT分区表。

=> mmc part Partition Map for MMC device 0 -- Partition Type: EFI Part Start LBA End LBA Name Attributes Type GUID Partition GUID 1 0x00004000 0x00005fff "uboot" 2 0x00006000 0x00007fff "misc" 3 0x00008000 0x00017fff "boot" # boot.img的目标分区! 4 0x00018000 0x00027fff "recovery" 5 0x00028000 0x00037fff "backup" 6 0x00038000 0x00c37fff "rootfs" # rootfs.img的目标分区! 7 0x00c38000 0x00c77fff "oem" 8 0x00c78000 0x01d59fbf "userdata"

分区表解读

  • uboot:存放U-Boot自身,一般不动。
  • boot:这就是我们要烧写boot.img的分区。它包含了内核和设备树。
  • rootfs:这就是我们要烧写rootfs.img的分区。它包含了完整的操作系统文件。
  • recovery:恢复分区,用于系统恢复场景。
  • userdata:用户数据分区,用于存放应用数据。

记住bootrootfs这两个分区名,后面的命令会用到。飞凌的tftpflash命令支持直接用分区名操作,比记分区号更直观。

3.5 使用TFTP烧写Boot镜像

万事俱备,开始烧写第一个关键镜像。

# 命令格式:tftpflash <内存加载地址> <服务器上的文件名> <目标分区名> => tftpflash 0x09400000 boot.img boot Using ethernet@fe2a0000 device TFTP from server 172.16.0.177; our IP address is 172.16.0.176 Filename 'boot.img'. Load address: 0x9400000 Loading: ################################################################# ################################################################# ... (此处会显示很多#,表示传输进度) ############################################### 3.1 MiB/s done Bytes transferred = 23584256 (167de00 hex) ## TFTP flash boot.img to partition 'boot' size 0x167de00 ... OK

命令解析

  • 0x09400000:这是RK3568平台DDR内存中的一个安全地址,用于临时存放从网络下载的镜像文件。这个地址需要足够大,且不能和U-Boot自身、栈空间冲突。0x09400000是飞凌U-Boot中常用的一个加载地址。
  • boot.img:存放在Ubuntu服务器/tftpboot目录下的文件名,必须完全一致。
  • boot:目标分区名,对应我们刚才在mmc part里看到的分区。

看到最后的OK,并且有正确的字节数显示(23584256字节,约22.5MB),就表示boot.img已经成功烧写到eMMC的boot分区了。

注意事项boot.img的大小不能超过boot分区的容量。你可以通过mmc part输出的Start和End LBA计算分区大小。例如boot分区:(0x17fff - 0x8000 + 1) * 512 bytes ≈ 32MB。通常官方提供的boot.img是适配分区大小的。

3.6 使用TFTP烧写Rootfs镜像

接下来烧写更大的根文件系统镜像,过程类似,但时间会更长。

=> tftpflash 0x09400000 rootfs.img rootfs Using ethernet@fe2a0000 device TFTP from server 172.16.0.177; our IP address is 172.16.0.176 Filename 'rootfs.img'. Load address: 0x9400000 Loading: ################################################################# ################################################################# ... (传输时间较长,文件可能超过1GB) ################################################################# done Bytes transferred = 1404391424 (53b55000 hex) ## TFTP flash rootfs.img to partition 'rootfs' size 0x53b55000 ... OK

这个过程中,你会看到传输速度的显示(例如1.5 MiB/s)。速度取决于你的网络环境(百兆/千兆)、服务器磁盘性能以及开发板CPU的处理能力。RK3568的千兆网口和Cortex-A55核心能很好地支撑高速TFTP传输。

重要提示:烧写rootfs.img时,务必确保电源稳定。因为写入eMMC是耗电操作,且数据量大,时间久。使用开发板配套的12V/2A电源适配器,避免使用功率不足的电源导致烧写过程中断电,损坏eMMC或镜像。

3.7 重启验证与系统启动

两个镜像都烧写成功后,就可以重启进入新系统了。

=> reset # 或者 => boot

重启后,观察串口终端输出。你应该会看到U-Boot的启动日志,然后是Linux内核解压、初始化硬件、加载设备树、最后成功挂载根文件系统的信息。如果一切顺利,你会看到Linux的登录提示符(例如OK3568 login:)。

首次启动可能较慢,因为系统可能会进行一些首次运行的初始化,比如扩展文件系统、创建必要的设备节点等。耐心等待几分钟。

4. 高阶技巧、问题排查与扩展应用

掌握了基础操作后,我们来看看如何优化、排错以及玩出更多花样。

4.1 提升烧写效率与可靠性的技巧

  1. 使用更快的网络:确保开发板、交换机和服务器都连接到千兆网络。TFTP是单线程的,网络带宽是最大瓶颈。
  2. 优化服务器端:将TFTP服务器目录(/tftpboot)放在Ubuntu的SSD硬盘上,甚至放在RAM disk(内存盘)中,可以极大提升读取速度。
  3. 压缩镜像:对于rootfs.img,如果不是必须为原始镜像,可以在服务器上压缩(如.gz),在U-Boot中使用tftp下载后,用unzipgunzip命令解压到内存,再写入eMMC。这能减少网络传输时间,但会增加CPU开销和解压时间,需要权衡。
  4. 脚本化自动化:如果你需要频繁烧写,可以将U-Boot命令写成脚本。在U-Boot中,你可以将命令序列写入环境变量:
    => setenv update_all 'tftpflash 0x09400000 boot.img boot; tftpflash 0x09400000 rootfs.img rootfs; reset' => saveenv
    以后只需要运行run update_all即可自动完成全部烧写和重启。

4.2 常见问题排查速查表

遇到问题不要怕,对照下表快速定位。

问题现象可能原因排查步骤
串口无输出1. 线缆接错(Debug口非USB口)
2. 串口驱动未安装
3. 终端参数错误
4. 板子未上电或损坏
1. 确认连接的是Type-C Debug口。
2. 检查设备管理器是否有未知设备或串口。
3. 确认波特率为115200,数据位8,停止位1,无校验,无流控。
4. 检查电源指示灯。
U-Boot无法中断1. 按键时机不对
2. 串口终端未打开或配置错误
1. 一上电就快速、连续敲击空格或回车。
2. 确认终端软件已正确连接并打开。
ping服务器失败1. 网络未连通(网线、桥接模式)
2. IP地址设置错误
3. 防火墙阻止
4. 服务器TFTP服务未运行
1. 检查网线、网口灯。确认虚拟机为桥接模式。
2. 在Ubuntu里ping开发板IP,双向测试。
3. 关闭Ubuntu防火墙sudo ufw disable或放行69/UDP。
4.sudo systemctl status tftpd-hpa查看服务状态。
tftpflash失败,提示TIMEOUT1. 服务器IP (serverip) 未设置或错误
2. 文件名错误或路径不对
3. 文件权限问题
1. 用printenv检查serverip
2. 确认文件名大小写完全一致,且位于/tftpboot根目录。
3. 在Ubuntu检查/tftpboot目录权限是否为777
tftpflash失败,提示Invalid partition1. 分区名拼写错误
2. 分区表不匹配
1. 用mmc part确认分区名,严格按显示的名称输入。
2. 确认你使用的镜像和开发板的分区表布局是匹配的。不同版本固件分区表可能微调。
烧写成功但系统无法启动1.boot.img内核与硬件不匹配
2.rootfs.img文件系统损坏或格式不对
3. 烧写过程中断电
1. 确认镜像来源正确,是为这块RK3568开发板编译的。
2. 尝试重新烧写,或验证镜像文件的MD5/SHA256校验和。
3.务必使用稳定电源。可尝试先烧写boot.img,启动到旧rootfs看内核是否正常,以隔离问题。
传输速度极慢 (< 1MB/s)1. 网络是百兆模式
2. 服务器磁盘IO慢
3. 网络中存在干扰或错误包
1. 检查网线、交换机、路由器是否支持千兆。
2. 将镜像放在Ubuntu的SSD或内存盘测试。
3. 更换网线,或尝试直连开发板与服务器(需配置同网段静态IP)。

4.3 扩展应用:基于TFTP的网络启动与内核调试

TFTP不仅仅用于烧写,它在开发阶段极其有用。

  1. 网络启动(NFS Root):这是更高效的开发方式。你可以让内核通过TFTP下载(boot.img中的zImagedtb),而根文件系统则通过网络文件系统(NFS)从服务器挂载。这样,你在Ubuntu上修改了根文件系统里的代码,开发板上立即生效,无需反复烧写rootfs.img
    • 在U-Boot中设置启动参数:
      => setenv bootargs 'console=ttyFIQ0 root=/dev/nfs rw nfsroot=172.16.0.177:/path/to/nfs/rootfs ip=172.16.0.176:172.16.0.177:172.16.0.1:255.255.255.0::eth0:off' => setenv bootcmd 'tftp 0x08080000 zImage; tftp 0x0a000000 dtb; bootz 0x08080000 - 0x0a000000' => saveenv => boot
  2. 单独更新内核或设备树:如果你只修改了内核代码或设备树,不需要动整个根文件系统。
    • 将编译好的zImagerk3568-ok3568-c.dtb放入/tftpboot
    • 在U-Boot中:
      # 下载新内核到内存 => tftp 0x08080000 zImage # 下载新设备树到内存 => tftp 0x0a000000 rk3568-ok3568-c.dtb # 将内存中的内核和设备树写入eMMC的boot分区(需要知道分区偏移,稍复杂) # 或者更简单:直接从内存启动测试! => bootz 0x08080000 - 0x0a000000
      如果测试成功,再用mmc write命令将内存中的数据固化到eMMC的对应位置。

4.4 RK3568平台特性与烧写相关的优化

了解你的硬件平台,能更好地理解整个过程。

  • eMMC可靠性:工业级的eMMC芯片带有坏块管理(BBM)磨损均衡(WL)功能。在烧写时,控制器会自动避开物理坏块,并将数据写入到不同的存储单元以延长寿命。这也是为什么直接写分区比写原始扇区更安全。
  • DDR与加载地址0x09400000这个地址位于DDR内存中。RK3568启动时,U-Boot会初始化DDR,并将自己重定位(relocate)到内存高端地址运行,因此低端地址区域(如0x08080000,0x09400000)可以用来安全地加载外部镜像。
  • 电源管理:在烧写大镜像时,CPU和eMMC都会处于高负载状态。底板上的电源电路(DC-DC和LDO)提供了稳定的5V和3.3V等电压。使用劣质电源可能导致电压跌落,引起eMMC写入错误或系统重启。务必使用原装或规格匹配的电源

我个人在多次烧写中最大的体会是:稳定大于一切。一次成功的烧写,依赖于稳定的电源、可靠的网络连接、匹配的镜像文件和正确的命令。在开始批量操作或进行关键升级前,务必在一个“干净”的环境下(直连网络、关闭无关软件)完整测试一遍整个流程。养成在关键操作(如saveenv,tftpflash)后检查命令回显是否有OKdone的习惯。对于RK3568这样功能强大的平台,TFTP烧写只是其基础能力之一,熟练掌握它,能为后续更复杂的应用开发、系统定制和产品部署打下坚实的基础。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询