前言
近期完成 i.MX6ULL 平台嵌入式 Linux 系统移植系列课程学习,完整走完 U-Boot、内核、设备树、根文件系统移植全流程。开发阶段采用TFTP+NFS 网络启动模式,无需反复烧录 SD 卡,极大提升内核、驱动调试效率,下面对整套移植知识体系做一次完整梳理。
一、Linux 系统移植基础
1.1 移植的目的与四大核心镜像
Linux 系统可以为硬件提供内存管理、进程多任务、设备驱动、文件系统、网络协议栈等基础能力。要让 Linux 在 i.MX6ULL 开发板上运行,必须准备 4 个核心文件:
- U-Boot:Bootloader,负责 DDR、串口、网口等硬件初始化,加载内核到内存,向内核传递启动参数;
- zImage:压缩后的 Linux 内核镜像;
- DTB 设备树文件:用树形描述硬件资源,实现内核与硬件信息解耦;
- Rootfs 根文件系统:Linux 应用程序、命令、库文件、启动脚本的集合。
1.2 i.MX6ULL 启动流程
上电之后,芯片内部 ROM 代码(BootROM)优先运行,从 SD 卡/EMMC 等存储介质读取 U-Boot 到 DDR 内存并执行。U-Boot 完成硬件初始化后,有两种方案加载系统:
- 离线模式:从 SD 卡/EMMC 读取 zImage、dtb、根文件系统;
- 开发推荐模式:TFTP 下载内核与设备树,NFS 挂载 Ubuntu 虚拟机上的根文件系统。
开发阶段优先使用网络启动,修改内核、应用程序后,只需要在虚拟机替换文件,不用重新烧录 SD 卡。
二、开发环境搭建(TFTP + NFS + Minicom)
2.1 虚拟机网卡配置
虚拟机配置双网卡:
- 网卡 1:桥接模式,对应 USB 转网口,用来和开发板通信(TFTP/NFS 网络传输);
- 网卡 2:NAT 模式,虚拟机访问外网,用于 apt 安装软件。
开发板 IP:192.168.1.50
Ubuntu 虚拟机(TFTP/NFS 服务器)IP:192.168.1.100
2.2 TFTP 服务器
TFTP 负责把虚拟机里的zImage、imx6ull-alientek-emmc.dtb传输到开发板 DDR。
- 安装 tftpd-hpa,修改配置文件指定共享目录;
- 将编译好的内核镜像、设备树放入 TFTP 共享文件夹;
- U-Boot 命令:
tftp 0x80800000 zImage tftp 0x83000000 imx6ull-alientek-emmc.dtb2.3 NFS 服务器
NFS 用来让开发板通过网络,直接挂载虚拟机上的 rootfs 作为根文件系统。
- 安装 NFS 服务,修改
/etc/exports配置共享目录; - 重启 NFS 服务生效;
- 在 U-Boot 的
bootargs启动参数中指定根文件系统类型为 nfs,填写服务器 IP 与共享路径。
2.4 Minicom 串口工具
USB 转串口连接开发板,Minicom 用来查看 U-Boot、内核打印,进入 U-Boot 交互命令行。
- 退出快捷键:
Ctrl+A松开,按下X,输入y确认退出。
三、U-Boot 编译、环境变量与常用命令
3.1 U-Boot 编译流程
源码一般使用 NXP 原厂或正点原子适配好的版本,原生官方 U-Boot 对开发板外设适配较差。
makedistcleanmakeimx6ull_alient_emmc_defconfigmake编译产物:u-boot.bin、u-boot.imx。u-boot.imx额外包含 IVT、DCD 头部信息,支持 SD 卡烧录,BootROM 可以识别并完成 DDR 初始化。
3.2 U-Boot 关键环境变量
bootcmd:上电自动执行的命令,可配置自动 TFTP 下载内核、设备树;bootargs:传递给 Linux 内核的启动参数,包含串口控制台、波特率、根文件系统位置。
3.3 U-Boot 常用调试命令
ping:测试开发板与虚拟机网络连通性;md/mm/nm:内存查看、修改;mmc:SD 卡/EMMC 读写,用于系统固化烧录;tftp:网络下载文件到 DDR;bootz:启动 zImage 内核。
网络调试排坑:PHY 自动协商超时、ARP 重试失败,大多是网线、桥接网卡、IP 网段不匹配导致。网络不通时执行 bootz 会报
Bad Linux ARM zImage magic!,属于内存垃圾数据假象,不是内核编译错误。
四、Linux 内核编译与设备树
4.1 内核编译
内核编译依赖交叉编译工具链,提前把工具链加入环境变量,安装 lzop 压缩工具。
makexxx_defconfigmakemenuconfigmake-jN编译产物:
vmlinux:未压缩内核,带完整调试信息;zImage:压缩后的内核镜像,嵌入式常用;dtb:设备树二进制文件。
make menuconfig图形化配置界面,可以增删内核驱动,例如 USB 转串口 CH340 驱动。编译完成后,把 zImage 和 dtb 放到 TFTP 共享目录。
五、根文件系统制作
根文件系统是 Linux 应用运行的基础,有两种主流制作方案:
- BusyBox:轻量经典方案。需要手动配置交叉编译工具链,手动拷贝动态库、静态库,编写
/etc/init.d/rcS启动脚本,挂载 proc、sysfs 文件系统; - Buildroot:更加现代化,图形化勾选软件包,自动处理库依赖,开箱即用;
- Yocto:大型项目、原厂 SDK 常用,复杂度更高。
rcS 启动脚本负责系统初始化,设置环境变量 PATH、LD_LIBRARY_PATH,是根文件系统启动的关键。
六、网络启动完整流程(模式三)
- 开发板上电,BootROM 从 SD 卡加载 U-Boot 到 DDR;
- U-Boot 启动,通过串口进入交互界面;
- U-Boot 配置 ipaddr、serverip,ping 确认网络连通;
- TFTP 从虚拟机下载 zImage 到
0x80800000,dtb 到0x83000000; - U-Boot 传递 bootargs,告知内核采用 NFS 挂载远程根文件系统;
bootz 0x80800000 - 0x83000000启动内核;- 内核启动,通过 NFS 挂载虚拟机 rootfs,进入 Linux shell;
- 在虚拟机交叉编译应用程序(如 hello world),直接在开发板运行调试。
内核启动报错 Kernel Panic,大概率是 bootargs 参数错误,找不到根文件系统。
七、固化与后续开发
网络启动仅用于开发调试。驱动、应用开发完成后,需要把 U-Boot、zImage、dtb、rootfs 烧录进 EMMC,脱离 TFTP/NFS,实现板子独立上电运行。
移植完成之后,下一步就进入Linux 字符设备驱动开发,编写硬件驱动代码,控制 LED、按键等外设。
八、常见踩坑总结
- PHY 协商超时、ARP 重试失败:优先检查网线、网口灯、虚拟机桥接网卡;
- Bad Linux ARM zImage magic:TFTP 下载失败,内存数据无效,不是内核损坏;
- Kernel Panic:bootargs 参数写错,NFS 共享目录权限或者路径错误;
- TFTP/NFS 无法传输:检查虚拟机防火墙是否关闭、服务是否正常运行;
- Minicom 串口乱码:波特率、数据位、停止位配置不匹配。