i.MX6ULL嵌入式Linux系统移植完整学习笔记
平台:正点原子I.MX6ULL开发板,Linux4.1.15内核 目标:搞懂嵌入式Linux系统移植整体概念、三大镜像文件、三种烧录模式,理清开发调试与量产的不同使用场景。
一、什么是Linux系统移植
简单来说,系统移植就是让Linux操作系统能够在我们的开发板硬件上跑起来。
PC机的Linux已经适配好了X86硬件,但是i.MX6ULL是ARM硬件,原厂内核不能直接运行,我们需要准备三套核心组件,把它们烧写到开发板存储介质,才能完整启动Linux。
Linux内核可以给开发板提供这些核心能力:
- 内存管理
- 进程调度
- 虚拟文件系统
- 进程间通信IPC
- 网络接口
移植需要的4个关键文件
| 文件 | 作用 | 对应文件名 |
|---|---|---|
| U‑Boot(BootLoader) | 初始化硬件,引导内核启动 | u‑boot.imx |
| Linux内核镜像 | 操作系统内核本体,管理软硬件资源 | zImage |
| 设备树 | 描述板载硬件资源信息(Linux3.0之后独立出来,旧版本直接编译进内核) | imx6ull‑alientek‑emmc.dtb |
| 根文件系统rootfs | 用户空间程序、库、配置文件,提供人机交互 | rootfs.tar.bz2 |
启动链路:
U‑Boot → dtb设备树 + zImage内核 → rootfs根文件系统
开发板启动方式(拨码开关选择)
- USB启动:芯片下载模式,烧写系统时使用
- SD卡启动:软件开发调试阶段,SD卡存放整套系统
- EMMC启动:产品量产阶段,系统固化到板载EMMC
- Nand Flash:本开发板无此硬件
存储器分布:ROM固件 | uboot | zImage | dtb | rootfs | userdata
二、三种系统烧录模式对比
实际开发中有三种常用烧录方案,不同场景选不同模式,不要全部都用EMMC烧写做开发调试。
| 模式 | 实现方式 | 使用场景 |
|---|---|---|
| 模式一:烧写到SD卡 | 将整套系统烧录进SD卡,板子从SD卡启动 | 快速部署、系统刷机恢复,调试前期 |
| 模式二:烧写到EMMC | 将整套系统固化到板载EMMC芯片 | 开发完成,产品量产出厂 |
| 模式三:uboot存SD卡,TFTP下载内核,NFS挂载根文件系统 | SD只放uboot;内核、dtb网络下载;rootfs网络挂载 | 开发阶段首选,不用反复烧写存储,修改内核/文件系统直接生效,效率最高 |
模式一:烧写到SD卡
两种操作途径:Windows下MfgTool工具;Ubuntu下shell脚本。
Windows MfgTool烧写SD卡
- 解压mfgtool工具,路径不能有中文,推荐7z/winrar解压,不要Windows自带解压,长文件名会解压失败。
Profiles/Linux/OS Firmware/files目录:- boot:存放uboot、zImage、dtb
- filesystem:存放rootfs.tar.bz2根文件系统压缩包
- 运行脚本:
Mfgtool2‑eMMC‑ddr512‑SDCard.vbs(DDR512版本核心板,烧录目标SD卡) - 硬件操作:
- 开发板12V供电;Type‑C接底板USB_OTG,关闭VMware虚拟机,让OTG设备识别到Windows主机
- 拨码设置为USB启动模式(01000000)
- 先拔掉SD卡,上电等待MfgTool识别开发板;识别成功后插入SD卡,点击
Start开始烧录
- 等待约5分钟烧录完成;烧录完成后,拨码切换为SD卡启动,开发板上电即可运行Linux系统。
⚠️小提示:烧写时不要接LCD屏幕,容易出现白屏液化现象。
Ubuntu脚本烧写SD卡
- SD卡插入读卡器接入虚拟机,执行
sudo fdisk -l确认SD卡设备名,一般为/dev/sdb - 将mfgtool中
files整个文件夹拷贝到Ubuntu。 - 执行烧录脚本:
sudo ./imx6mksdboot.sh -device /dev/sdb -flash emmc -ddrsize 512
- 脚本执行完毕,SD卡就已经写好系统;拨码切SD卡启动即可。
SD卡分区布局
- 0扇区:MBR分区表(512字节)
- 1KB开始存放U‑Boot镜像,最大占用至1MB
- 分区1 FAT32(64MB)挂载/boot,存放
zImage、dtb - 分区2 EXT3,占用剩余全部SD卡空间,挂载
/根目录,存放整个rootfs
模式二:烧写到EMMC(量产模式)
同样支持Windows MfgTool、Ubuntu脚本两种方式。
Windows MfgTool烧写EMMC
- 使用脚本
Mfgtool2‑eMMC‑ddr512‑eMMC.vbs,其余硬件接线、USB启动拨码操作与SD卡烧录基本一致。 - 不要插入SD卡,上电识别OTG设备,点击Start烧录,等待完成。
- 烧写结束,拨码切换为EMMC启动,板子直接从板载存储启动系统。
Ubuntu脚本烧写EMMC
前提:SD卡已经烧录好系统,开发板SD卡启动先跑起Linux。
- 串口工具minicom连接开发板,开发板与Ubuntu虚拟机处于同一局域网,网络ping通。
- Ubuntu开启NFS服务,开发板通过NFS挂载Ubuntu共享目录:
mount -o nolock,rw,nfsvers=3 192.168.1.100:/home/linux/nfs/rootfs /mnt
- 将烧录脚本和固件放到共享目录,开发板进入共享目录,执行
imx6mkemmcboot.sh脚本,完成EMMC烧写。 - 烧写完毕拨码切换EMMC启动。
模式三:TFTP+NFS网络启动(开发调试神器)
✅开发阶段强烈推荐!不需要反复烧写SD/EMMC,每次编译出新内核、新设备树直接放在Ubuntu服务器,开发板网络加载,极大节约调试时间。
工作原理
- SD卡只烧录U‑Boot,板子SD卡启动,上电运行uboot。
- uboot通过TFTP协议从Ubuntu服务器下载
zImage内核、.dtb设备树到DDR内存。 - 内核启动之后,不使用本地存储的rootfs,通过NFS网络直接挂载Ubuntu主机上的根文件系统。
- 整套系统运行,修改内核、驱动、应用只需要更新Ubuntu服务器的文件,重启板子就生效。
操作步骤
- 使用模式一把uboot烧录进SD卡,板子设置SD卡启动。
- Ubuntu配置TFTP、NFS服务:
- tftpboot目录存放
zImage、imx6ull‑alientek‑emmc.dtb - nfs共享目录解压好完整
rootfs.tar.bz2根文件系统。
- tftpboot目录存放
- 串口进入U‑Boot交互终端,配置环境变量:
env default -a
saveenv
#网络参数
setenv ipaddr 192.168.1.50 #开发板IP
setenv ethaddr 00:04:9f:04:d2:35 #MAC地址
setenv gatewayip 192.168.1.1
setenv netmask 255.255.255.0
setenv serverip 192.168.1.100 #Ubuntu虚拟机桥接网卡IP
saveenv
#bootcmd:tftp下载内核和dtb,启动内核
setenv bootcmd 'tftp 80800000 zImage;tftp 83000000 imx6ull‑alientek‑emmc.dtb;bootz 80800000 - 83000000'
saveenv
#bootargs:内核启动参数,指定nfs根文件系统
setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.1.100:/home/linux/nfs/rootfs,proto=tcp,nfsvers=3 rw ip=192.168.1.50:192.168.1.100:192.168.1.1:255.255.255.0::eth0:off'
saveenv
reset
- 板子重启,uboot自动执行bootcmd,通过网络加载内核和挂载NFS根文件系统,成功进入Linux。
注意:uboot中的ping命令只能开发板ping虚拟机,不能虚拟机ping开发板。
三、i.MX6ULL完整启动流程梳理
- Boot ROM阶段(芯片内置固化代码,不属于U‑Boot) 上电复位,芯片内部ROM固件运行。读取拨码的启动模式;把uboot.imx头部IVT/DCD/bootdata加载到片内OCRAM(片上SRAM);初始化基础时钟,DDR控制器。
- U‑Boot第一阶段(SPL,运行在片内OCRAM) 完成DDR完整初始化;把完整U‑Boot镜像拷贝到DDR内存(0x87800000);跳转到DDR执行U‑Boot主程序。
- U‑Boot第二阶段(DDR内存运行) 初始化外设,读取环境变量,执行bootcmd;把zImage内核、dtb设备树加载到DDR指定地址;通过bootargs向内核传递启动参数;调用
bootz启动Linux内核。 - Linux内核启动 内核解压运行,执行
start_kernel,完成内核各个子系统初始化,创建pid=1的init进程。 - 根文件系统阶段 内核按照bootargs找到rootfs,执行
/etc/inittab、/etc/init.d/rcS脚本,挂载各类文件系统,启动shell,提供控制台交互,系统完全就绪。
四、烧录自己编译的镜像
当自己编译完uboot、内核、设备树、构建完rootfs之后,替换对应目录文件即可:
- boot目录:替换自己编译生成的
u‑boot.imx、zImage、dtb设备树文件。 - filesystem目录:把自制根文件系统打包为
rootfs.tar.bz2放入。 - 执行烧录脚本:
sudo ./imx6mksdboot.sh -device /dev/sdb -flash emmc -ddrsize 512
烧录完成后,可在uboot设置启动参数:
- EMMC本地启动示例bootcmd
setenv bootcmd 'mmc dev 1; fatload mmc 1:1 80800000 zImage; fatload mmc 1:1 83000000 imx6ull‑alientek‑emmc.dtb; bootz 80800000 - 83000000;'
setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw'
saveenv
五、学习心得总结
- 分清开发和量产模式:开发调试优先TFTP+NFS网络启动,减少SD/EMMC反复擦写;产品定稿后,再烧写到EMMC。
- 四大件缺一不可:uboot负责引导,zImage是内核本体,dtb描述硬件资源,rootfs提供用户态环境。
- 设备树是Linux3.0之后重大改进,把硬件资源描述从内核剥离,实现驱动代码和硬件资源描述分离,提升代码可移植性。
- 启动链路要记牢:ROM → U‑Boot → 内核(zImage+dtb) → rootfs。任何一个环节出错,开发板都无法正常进入控制台。
- 做系统移植,不仅仅是会烧写镜像,更要理解每个组件在整个启动流程中承担的工作,出现启动失败(黑屏、卡死、panic)才能够快速定位问题。
后续学习:U‑Boot编译、Linux内核裁剪编译、设备树语法、busybox构建根文件系统。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐


所有评论(0)