告别MFGTool!手把手教你用U-Boot命令给NAND版IMX6ULL烧写内核和设备树
告别MFGTool!手把手教你用U-Boot命令给NAND版IMX6ULL烧写内核和设备树
在嵌入式Linux开发中,IMX6ULL处理器的NAND版本开发板是许多开发者的首选。传统上,我们依赖NXP官方的MFGTool工具来完成系统镜像的烧写,但这种"黑盒"操作方式往往让开发者感到束手束脚。今天,我将分享一种更透明、更可控的方法——完全在U-Boot命令行环境下完成Linux内核和设备树的更新。
这种方法特别适合那些系统已初步运行,但需要进行内核调试或升级的开发者。通过直接操作U-Boot命令,你不仅能更深入地理解系统启动流程,还能在开发过程中获得更大的灵活性和控制权。更重要的是,当MFGTool无法使用时(比如在远程调试场景下),这种方法将成为你的救命稻草。
1. 准备工作与环境搭建
在开始烧写之前,我们需要确保开发环境已经正确配置。首先确认你的开发板是NAND版本,并且已经能够正常启动到U-Boot命令行界面。如果你是从头开始配置,需要特别注意以下几点:
- 开发板连接:通过串口连接开发板与主机,确保能够接收U-Boot输出并输入命令
- 网络配置:开发板与主机需要在同一局域网,并配置好TFTP服务
- 文件准备:准备好要烧写的内核镜像(zImage)和设备树文件(.dtb)
提示:建议在操作前备份当前系统中的重要数据,避免意外擦除导致数据丢失
1.1 确认NAND信息
在U-Boot命令行中,我们可以使用以下命令查看NAND Flash的基本信息:
nand info这个命令会输出NAND的页大小、OOB区域大小和擦除块大小等关键参数。对于IMX6ULL开发板,典型的输出可能如下:
| 参数名称 | 典型值 | 说明 |
|---|---|---|
| Page Size | 2048 bytes | 单页大小 |
| OOB Size | 64 bytes | 每页的OOB区域大小 |
| Erase Size | 128 KB | 最小擦除块大小 |
1.2 网络配置与文件传输
为了将内核和设备树文件传输到开发板,我们需要配置TFTP服务。在U-Boot中,首先设置开发板的IP地址和服务器IP:
setenv ipaddr 192.168.1.100 # 开发板IP setenv serverip 192.168.1.10 # TFTP服务器IP saveenv # 保存环境变量然后使用ping命令测试网络连接:
ping 192.168.1.10如果网络连接正常,就可以使用tftp命令下载文件到开发板的DRAM中。例如下载内核镜像:
tftp 0x87800000 zImage2. 理解NAND分区布局
在IMX6ULL开发板上,NAND Flash通常被划分为几个固定的分区,每个分区有明确的用途和地址范围。典型的NAND分区表如下:
| 分区名称 | 起始地址 | 结束地址 | 大小 | 用途 |
|---|---|---|---|---|
| boot | 0x00000000 | 0x00400000 | 4MB | U-Boot |
| kernel | 0x00400000 | 0x00600000 | 2MB | Linux内核 |
| dtb | 0x00600000 | 0x00700000 | 1MB | 设备树 |
| rootfs | 0x00700000 | 0x02000000 | 25MB | 根文件系统 |
理解这个分区表至关重要,因为它决定了我们应该将内核和设备树文件烧写到哪个地址范围。错误的地址可能导致系统无法启动或数据损坏。
2.1 查看当前分区
在U-Boot中,可以使用以下命令查看NAND的分区信息:
mtdparts这个命令会显示当前配置的MTD分区表,包括每个分区的名称、地址范围和大小。如果输出为空或不符合预期,可能需要先设置正确的分区表。
2.2 地址对齐的重要性
NAND操作有一个关键特性:所有操作都必须对齐到擦除块边界。对于IMX6ULL,典型的擦除块大小是128KB。这意味着:
- 擦除操作必须从擦除块边界开始
- 擦除大小必须是擦除块大小的整数倍
- 写入操作也应当遵循这些对齐规则
不遵守这些规则可能导致操作失败或数据损坏。例如,如果你尝试从0x400010地址开始擦除,很可能会收到错误提示。
3. 内核镜像的烧写流程
现在,我们进入实际操作阶段。首先从内核镜像开始,这是系统启动的核心组件。
3.1 下载内核镜像
使用TFTP将内核镜像下载到DRAM中。我们通常选择0x87800000作为加载地址,这是IMX6ULL的内存映射中一个安全的位置:
tftp 0x87800000 zImage下载完成后,可以检查文件大小:
iminfo 0x87800000这个命令会显示镜像的头部信息,包括大小和校验和。记录下实际的镜像大小,后续擦除和写入操作需要参考这个值。
3.2 擦除目标区域
根据分区表,内核分区从0x00400000开始。我们需要先擦除这个区域:
nand erase 0x00400000 0x00200000这里我们擦除了整个2MB的内核分区。虽然实际内核镜像可能只有600-700KB,但擦除整个分区可以确保足够的空间,也避免了复杂的尺寸计算。
注意:擦除操作是不可逆的,执行前请确认地址和大小正确
3.3 写入内核镜像
现在可以将DRAM中的内核镜像写入NAND:
nand write 0x87800000 0x00400000 0x00200000这个命令将把从0x87800000开始的2MB数据写入NAND的0x00400000地址处。虽然我们可能只下载了600KB的内核,但写入整个2MB是安全的,多余的空白区域不会影响系统运行。
4. 设备树文件的烧写方法
设备树文件虽然小,但对系统启动同样关键。它的烧写流程与内核类似,但有一些特殊注意事项。
4.1 下载设备树文件
使用TFTP下载设备树文件到DRAM:
tftp 0x87800000 imx6ull-alientek-nand.dtb设备树文件通常很小(几十KB),但我们需要确保下载的版本与内核兼容。下载后可以检查文件头:
fdt addr 0x87800000 fdt header4.2 擦除设备树分区
设备树分区从0x00600000开始,大小通常为1MB:
nand erase 0x00600000 0x001000004.3 写入设备树文件
将设备树文件写入NAND:
nand write 0x87800000 0x00600000 0x00100000由于设备树文件很小,我们实际上可以只写入实际大小而不是整个分区。但为了简单起见,写入整个分区也是可行的。
5. 验证与调试技巧
烧写完成后,我们需要验证操作是否成功。以下是一些实用的验证方法和调试技巧。
5.1 读取验证
最简单的验证方法是读取刚写入的内容:
nand read 0x83000000 0x00400000 0x00200000 # 读取内核 nand read 0x83000000 0x00600000 0x00100000 # 读取设备树然后可以使用iminfo和fdt命令检查读取到的内容:
iminfo 0x83000000 # 检查内核镜像 fdt addr 0x83000000 # 设置设备树地址 fdt print # 打印设备树内容5.2 常见问题排查
在实际操作中,可能会遇到各种问题。以下是一些常见错误及解决方法:
TFTP下载失败:
- 检查网络连接和IP设置
- 确认TFTP服务器已启动且文件路径正确
- 尝试使用不同的DRAM地址(如0x82000000)
NAND操作错误:
- 确认地址对齐到擦除块边界
- 检查分区大小是否足够
- 确保NAND没有写保护
启动失败:
- 确认烧写的镜像与硬件兼容
- 检查启动参数是否正确设置
- 验证设备树是否匹配当前硬件
5.3 高级技巧
对于需要频繁调试的开发者,可以设置U-Boot环境变量来简化操作:
setenv update_kernel 'tftp 0x87800000 zImage; nand erase 0x00400000 0x00200000; nand write 0x87800000 0x00400000 0x00200000' setenv update_dtb 'tftp 0x87800000 imx6ull-alientek-nand.dtb; nand erase 0x00600000 0x00100000; nand write 0x87800000 0x00600000 0x00100000' saveenv之后,更新内核和设备树只需要分别执行:
run update_kernel run update_dtb6. 安全注意事项与最佳实践
NAND操作具有一定的风险性,不当的操作可能导致系统无法启动或数据丢失。以下是一些重要的安全注意事项。
6.1 避免全片擦除
最重要的规则是:永远不要执行nand erase.chip命令。这个命令会擦除整个NAND Flash,包括U-Boot本身,导致系统完全无法启动,只能通过专业的编程器恢复。
6.2 备份关键数据
在进行任何修改前,建议备份当前的关键数据:
nand read 0x83000000 0x00400000 0x00200000 # 备份内核 tftpput 0x83000000 0x00200000 kernel_backup.bin nand read 0x83000000 0x00600000 0x00100000 # 备份设备树 tftpput 0x83000000 0x00100000 dtb_backup.dtb6.3 操作确认流程
建议建立一套标准的操作确认流程:
- 确认当前分区布局(mtdparts)
- 确认要写入的文件大小(iminfo/fdt header)
- 计算并确认擦除区域
- 执行擦除操作
- 执行写入操作
- 验证写入结果
6.4 性能优化建议
对于需要频繁烧写的情况,可以考虑以下优化:
- 使用RAM文件系统减少NAND写入次数
- 合理设置擦除块大小,避免过度擦除
- 考虑使用UBI文件系统提高NAND管理效率
在实际项目中,我发现最常遇到的问题是不匹配的内核和设备树版本。一个实用的技巧是在文件名中加入版本号或日期,如zImage_v1.2和imx6ull_v1.2.dtb,这样可以避免混淆。另外,在远程更新时,建议先在本地测试确认镜像的兼容性,再部署到现场设备。
