资讯详情

EasyARM i.mx287学习笔记——rootfs 修改与烧写:从 uboot 到 tftp 的完整链路

📅 2026/9/30 18:12:41 | 华诺云谱 👁 阅读
EasyARM i.mx287学习笔记——rootfs 修改与烧写:从 uboot 到 tftp 的完整链路
1. 从一次 rootfs 改崩说起EasyARM i.mx287 根文件系统替换到底难在哪EasyARM i.mx287 这块板子用的是 NXP i.MX287 处理器Nand Flash 存储跑的是 Linux UBIFS 根文件系统。很多刚上手的朋友会卡在同一个地方内核能起来串口也有输出但 rootfs 里想加个自己的程序、改个开机 IP就不知道怎么把改动“塞”回板子里。直接改板子上的文件重启就没了。重新做整个系统镜像又太重。rootfs 修改与烧写的本质是把 PC 上准备好的一个目录rootfs 文件夹打包成 Nand Flash 能识别的 UBIFS 镜像再通过 uboot 的 tftp 通道传到板子内存最后写进 Nand 的对应分区。整条链路是PC 端 rootfs 目录 → mkfs.ubifs 打包 → ubinize 生成 ubi.img → tftp 服务端就绪 → uboot 设置 ipaddr/serverip → run upsystem 烧写 → 重启挂载验证。适合谁看手里有 EasyARM i.mx287 开发板、已经能用 minicom 进串口、能进 uboot 命令行但还没独立完成过一次 rootfs 替换的嵌入式初学者。我试过第一次烧写时因为 serverip 写错一位uboot ping 不通卡了半小时才反应过来。这篇就把这条链路拆成可复制的步骤包括 uboot 命令序列、tftp 服务端配置骨架、烧写后的挂载验证动作。核心检索词先摆出来EasyARM i.mx287 rootfs 修改与烧写走 uboot tftp 方式涉及 uImage、rootfs.ubifs、build_rootfs.sh、ubinize.cfg 这几个关键文件。下面按“准备 → 改 rootfs → 制作镜像 → uboot 烧写 → 验证 → 排障”的顺序走每一步都给可复制的命令。2. 前置准备tftp 服务端、uImage 与 rootfs.ubifs 三件套怎么摆在动 uboot 之前PC 端通常是 Ubuntu 虚拟机必须先把 tftp 服务端跑起来并且 tftp 根目录里要放好两个文件uImageLinux 内核镜像和rootfs.ubifs根文件系统镜像。这两个文件是 uboot 烧写时直接拉取的源。先确认 tftp 服务端。EasyARM 配套的 Ubuntu ISO 里一般已经装了 tftpd-hpa检查一下dpkg -l | grep tftpd如果没有装一下sudo apt-get install tftpd-hpa tftp-hpa配置文件在/etc/default/tftpd-hpa典型内容如下重点是TFTP_DIRECTORY指向你的 tftp 根目录TFTP_OPTIONS带上-c允许创建文件# /etc/default/tftpd-hpa TFTP_USERNAMEtftp TFTP_DIRECTORY/home/yourname/tftpboot TFTP_ADDRESS0.0.0.0:69 TFTP_OPTIONS--secure --create改完重启服务sudo service tftpd-hpa restart然后确认 tftp 根目录存在并且权限放开tftp 用户要能读mkdir -p ~/tftpboot chmod 777 ~/tftpboot接下来摆文件。uImage 是内核镜像如果你没改内核直接从配套资料里复制到 tftp 根目录即可cp /path/to/your/uImage ~/tftpboot/rootfs.ubifs 不是现成的它由 rootfs 文件夹制作而来。所以先在 PC 上建一个工作目录比如EasyARM-rootfs把三样东西放进去rootfs文件夹、build_rootfs.sh脚本、ubinize.cfg配置文件。目录结构大概是这样EasyARM-rootfs/ ├── rootfs/ # 根文件系统目录树 ├── build_rootfs.sh # 打包脚本 └── ubinize.cfg # ubinize 配置给脚本加可执行权限chmod ax build_rootfs.sh这里有个容易忽略的点build_rootfs.sh里通常会写死输出路径和 tftp 根目录路径。打开脚本确认一下cp -av rootfs.ubifs ~/tftpboot这一行的目标路径和你实际的 tftp 根目录一致。如果 tftp 根目录不是~/tftpboot要么改脚本要么建个软链接。我踩过的坑就是脚本里写的是/home/zlg/tftpboot而我的用户名不是 zlg结果 cp 报“No such file or directory”排查了半天。ubinize.cfg是 ubinize 工具的配置文件它描述 UBI 镜像里各个 volume 的布局。典型内容如下注意vol_type、vol_name和vol_size要和你的 Nand 分区规划对上[ubifs] modeubi imageubifs.img vol_id0 vol_typedynamic vol_namerootfs vol_flagsautoresizevol_flagsautoresize让 rootfs 卷在首次挂载时自动占满剩余空间这对 Nand 上只有一个 rootfs 卷的场景很实用。如果你的分区表里 rootfs 是固定大小就去掉这行改成vol_sizexxxMiB。准备阶段做完PC 端应该满足tftp 服务在跑、~/tftpboot里有uImage、EasyARM-rootfs目录里有rootfsbuild_rootfs.shubinize.cfg。下一步才是改 rootfs 内容。3. 改 rootfs 与打包build_rootfs.sh、ubinize.cfg 可复制配置rootfs 文件夹就是板子启动后看到的根目录树。你要改开机 IP、加自己的可执行文件都是在这个文件夹里操作改完再打包。先说改配置。EasyARM 的 rootfs 里开机启动脚本一般在/etc/rc.d/init.d/下。比如start_userapp这个文件负责启动用户应用。想给板子设固定 IP就在里面加一行 ifconfig。原始内容大概长这样#!/bin/sh ifconfig eth0 hw ether 02:00:92:B3:C4:A8 #ifconfig eth0 down #you can add your app start_command here改成#!/bin/sh ifconfig eth0 hw ether 02:00:92:B3:C4:A8 #ifconfig eth0 down #you can add your app start_command here # 设置固定 IP ifconfig eth0 192.168.1.211注意 MAC 地址那行hw ether是设置硬件地址别和 IP 搞混。IP 用ifconfig eth0 192.168.1.211这种写法掩码默认按类走需要的话补netmask 255.255.255.0。再说加可执行文件。假设你有一个编译好的test-gpio来自文件 IO 操作 GPIO 的例程想放到板子的/root目录下。直接复制进 rootfscp test-gpio EasyARM-rootfs/rootfs/root/ chmod ax EasyARM-rootfs/rootfs/root/test-gpiochmod ax这一步不能省否则板子上跑不起来会报 Permission denied。改完 rootfs回到EasyARM-rootfs目录执行打包脚本cd EasyARM-rootfs ./build_rootfs.shbuild_rootfs.sh的内容是关键逐行看#!/bin/bash mkfs.ubifs -r rootfs -m 2048 -e 126976 -c 1900 -o ubifs.img ubinize -o ubi.img -m 2048 -p 128KiB -s 512 ubinize.cfg mv ubifs.img rootfs.ubifs cp -av rootfs.ubifs ~/tftpboot参数逐个解释这些数字必须和你的 Nand 芯片匹配写错会导致挂载失败参数含义本例取值说明-m最小 I/O 单元2048Nand page size2KB-e逻辑擦除块大小126976通常 擦除块大小 - 2×page-c最大逻辑块数1900决定 UBIFS 卷最大容量-p物理擦除块大小128KiBNand block size-s子页大小512sub-page sizemkfs.ubifs把 rootfs 目录打成ubifs.imgubinize再按ubinize.cfg把它封装成 UBI 格式的ubi.img最后重命名为rootfs.ubifs并复制到 tftp 根目录。mkfs.ubifs和ubinize这两个工具在周立功提供的 Ubuntu ISO 里已经包含不用另外装。执行完确认 tftp 根目录里两个文件都在ls -lh ~/tftpboot/ # 应看到 uImage 和 rootfs.ubifs如果build_rootfs.sh报mkfs.ubifs: command not found说明工具没装或 PATH 不对用which mkfs.ubifs查一下通常在/usr/sbin下需要 sudo 或补 PATH。4. uboot 命令序列与 tftp 烧写run upsystem 完整链路PC 端准备好转到板子。用 minicom 连串口给板子上电或按复位。控制台会打印启动信息看到Hit any key to stop autoboot时按空格或任意键进入 uboot 命令行。第一步设置 uboot 自己的 IP 和 tftp 服务器也就是 PC的 IPsetenv ipaddr 192.168.1.212 setenv serverip 192.168.1.106 saveenv这里ipaddr是板子的地址serverip是 PC 的地址两者必须在同一网段。注意别和 rootfs 里设的固定 IP 冲突——rootfs 里设的是 192.168.1.211uboot 用 192.168.1.212PC 用 192.168.1.106三个地址互不重复。saveenv把环境变量写进 Nand下次上电还在。第二步验证网络通不通在 uboot 里 ping PCping 192.168.1.106正常返回Using FEC0 device host 192.168.1.106 is alive如果返回ping failed或host not alive先查网线、PC 防火墙、tftp 服务是否在跑别急着往下烧。第三步烧写。EasyARM 的 uboot 环境里通常预置了upsystem这个宏它封装了 tftp 拉取 uImage 和 rootfs.ubifs 并写入 Nand 的动作。直接运行run upsystem如果你想看清楚它到底做了什么可以用printenv upsystem查看宏定义典型内容类似upsystemtftp ${loadaddr} uImage; nand erase ${kernel_off} ${kernel_size}; nand write ${loadaddr} ${kernel_off} ${kernel_size}; tftp ${loadaddr} rootfs.ubifs; nand erase ${rootfs_off} ${rootfs_size}; nand write ${loadaddr} ${rootfs_off} ${rootfs_size}它先 tftp 拉 uImage 到内存 loadaddr擦除内核分区写入再 tftp 拉 rootfs.ubifs擦除 rootfs 分区写入。整个过程串口会打印传输进度和写入结果看到OK和字节数就说明成功。烧写完成后复位板子reset板子重新启动这次会从新烧写的 rootfs 挂载。串口会打印 UBIFS 挂载信息看到类似UBIFS: mounted UBI device 0, volume 0, name rootfs就说明根文件系统挂上了。5. 烧写后验证与常见报错排查401、local proxy failed、reading choices 对照烧完不验证等于没烧。板子起来后登录进系统先看 IP 有没有按你改的配置生效ifconfig期望输出里eth0的inet addr应该是 192.168.1.211eth0 Link encap:Ethernet HWaddr 02:00:92:B3:C4:A8 inet addr:192.168.1.211 Bcast:192.168.1.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1如果还是旧 IP 或没有 IP说明 rootfs 没真正替换成功或者启动脚本没执行到那行。检查/etc/rc.d/init.d/start_userapp是否真的在启动流程里被调用。再验证加进去的可执行文件cd /root ./test-gpio正常会看到 GPIO 翻转输出比如 LED Blink 反复打印。如果报not found多半是动态库缺失或架构不对报Permission denied就是打包前忘了chmod ax。下面把这条链路上最常见的几类报错对照一下方便你快速定位现象/报错可能原因排查动作ubootping failedserverip 写错、网线不通、tftp 没起核对 IP 网段service tftpd-hpa statustftp401或Access deniedtftp 根目录权限不足chmod 777 ~/tftpboot检查TFTP_OPTIONSlocal proxy failed网络层不通或 tftp 地址被拦确认 PC 防火墙放行 69/udp直连网线reading choices相关报错启动参数或环境变量异常printenv检查 bootargs、bootcmdUBIFSmount failedmkfs.ubifs 参数与 Nand 不匹配核对-m/-e/-c/-p/-s与芯片手册板子起不来、反复重启内核或 rootfs 分区写错位置用printenv核对分区偏移关于401和local proxy failed这两个在 tftp 场景里通常不是 HTTP 语义而是 tftp 服务端拒绝或网络路径不通的表现。401多见于 tftp 服务端权限配置local proxy failed多见于客户端到服务端之间被中间层拦截。排查思路一致先确认服务端在跑、目录可读、地址可达。如果你在 PC 端用命令行 tftp 客户端自测可以这样验证服务端是否正常tftp 192.168.1.106 tftp get uImage tftp quit能拉下来就说明服务端没问题问题在 uboot 侧的网络配置。6. 把 rootfs 替换流程固化成自己的开发习惯整条链路走通一次之后建议把它固化成脚本和检查清单下次改 rootfs 就不用重新摸索。我的做法是在EasyARM-rootfs目录里放一个rebuild.sh把打包和复制合成一步再在 PC 上留一个check_tftp.sh烧写前自动确认 tftp 根目录里两个文件的时间戳是不是最新的。#!/bin/bash # rebuild.sh set -e ./build_rootfs.sh ls -lh ~/tftpboot/uImage ~/tftpboot/rootfs.ubifs echo 打包完成确认时间戳为最新后再进 uboot 烧写set -e让脚本在任一步失败时立即退出避免打包失败还继续复制旧文件。烧写前跑一下看到两个文件时间戳都是刚刚再进 ubootrun upsystem能省掉很多“烧了但没生效”的困惑。另外uboot 环境变量ipaddr、serverip用saveenv存过之后下次上电不用重设但如果你换了 PC 或换了网段记得重新设。rootfs 里的固定 IP 和 uboot 的 ipaddr 建议错开避免同一网段地址冲突。最后留一个实用技巧改 rootfs 时先在 PC 上用chroot进 rootfs 目录跑一下你的程序确认依赖和权限没问题再打包烧写。这样能把大部分“烧进去跑不起来”的问题挡在 PC 端板子上只做最终验证。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑