1,当系统起不来,出现flash ECC error怎么定位是哪里的问题呢
思路:读出单板上的flash数据和烧写到单板上的bin文件进行对比。
(1)系统可以正常系统,可以进uboot
sf read/sf write:用于操作SPI Flash。
U-Boot大小为512KB(0x80000),存储在Flash的起始位置。
U-Boot读取命令:
# sf read <内存地址> <Flash偏移> <读取大小>
sf read 0x81000000 0x0 0x80000
```
* `0x81000000`:数据加载到内存的地址。
* `0x0`:从Flash的0地址开始读。
* `0x80000`:读取512KB。
-
导出到Windows:
tftp 0x81000000 u-boot.bin 0x80000 ```- 执行后,Windows上会得到一个
u-boot.bin文件。
- 执行后,Windows上会得到一个
nand read/nand write:用于操作NAND Flash。
读取整个NAND Flash数据
NAND Flash的一个关键特性是坏块 。U-Boot的nand read命令非常智能,它会自动跳过坏块,只读取有效数据。
-
场景:假设单板有一个256MB的NAND Flash。
-
计算:
- 总字节数:256MB =
0x10000000字节。
- 总字节数:256MB =
-
注意 :虽然物理容量是256MB,但由于坏块的存在,实际读出的有效数据量可能会略小。
nand read会处理这一切。 -
U-Boot读取命令(读取整个芯片):
# nand read <内存地址> <Flash偏移> <读取大小> nand read 0x81000000 0x0 0x10000000 ```0x81000000:数据加载到内存的地址。0x0:从NAND Flash的0地址开始读。0x10000000:尝试读取256MB的数据(命令会自动跳过坏块)。
-
导出到Windows:
# ${filesize} 是U-Boot变量,在上次read后自动设置为实际读取的字节数 tftp 0x81000000 full_nand_dump.bin ${filesize} ```使用
${filesize}变量可以确保只传输实际读取到的数据长度。
四、具体举例:读取并导出不同组件
假设我们使用的内存加载地址统一为 0x81000000,并且分区布局如下:
- U-Boot: 存储在NAND Flash最前端,大小1MB。
- Kernel: 紧随U-Boot,从1MB偏移开始,大小5MB。
- Device Tree: 紧随Kernel,从6MB偏移开始,大小64KB。
1. 读取并导出 U-Boot (u-boot.bin)
-
U-Boot读取命令:
nand read 0x81000000 0x0 0x100000 ```0x0:从NAND的0地址开始读。0x100000:读取1MB。
-
导出到Windows:
tftp 0x81000000 u-boot.bin 0x100000 ``` -
分析 :对比这个
u-boot.bin和你电脑上原始的、正确的u-boot.bin文件。如果文件开头是0xFF或与原始文件不一致,说明U-Boot损坏或其所在的块变成了坏块,这是单板无法启动的最常见原因。
2. 读取并导出 Linux内核 (kernel.bin)
-
U-Boot读取命令:
nand read 0x81000000 0x100000 0x500000 ```0x100000:跳过前1MB(留给U-Boot)。0x500000:读取5MB的内核数据。
-
导出到Windows:
tftp 0x81000000 kernel.bin 0x500000 ``` -
分析 :对比
kernel.bin。如果损坏,U-Boot可能能启动并打印信息,但在加载内核时会失败、卡死或报错 "Kernel panic - not syncing"。
3. 读取并导出 设备树 (dts.bin)
-
U-Boot读取命令:
nand read 0x81000000 0x600000 0x10000 ```0x600000:从6MB偏移开始读。0x10000:读取64KB的设备树数据。
-
导出到Windows:
tftp 0x81000000 dts.bin 0x10000 ```
mmc read/mmc write:用于操作eMMC或SD卡
通用导出方法(以TFTP为例)
这是最常用、速度最快的方法。
-
Windows端准备:
- 下载并运行一个TFTP服务器软件,如
tftpd64。 - 将其工作目录设置为你想保存文件的目录(例如
D:\Backup)。 - 记住你Windows电脑的IP地址,例如
192.168.1.100。
- 下载并运行一个TFTP服务器软件,如
-
U-Boot端设置网络:
# 设置单板的IP地址 setenv ipaddr 192.168.1.10 # 设置TFTP服务器(你的Windows电脑)的IP地址 setenv serverip 192.168.1.100 # 保存环境变量(可选,但推荐) saveenv ``` -
U-Boot端导出命令:
# tftp <内存地址> <要保存的文件名> <文件大小> tftp 0x81000000 backup.bin 0x80000 ```执行后,你会在
tftpd64的窗口看到传输进度,完成后D:\Backup目录下就会出现backup.bin。
三、读取整个eMMC数据
要读取整个eMMC,你需要知道它的总容量,并将其转换为块数。eMMC的默认块大小是512字节(0x200)。
-
场景:假设单板有一个8GB的eMMC。
-
计算:
- 总字节数:8GB = 8 1024 1024 * 1024 =
0x200000000字节。 - 总块数:
0x200000000/0x200=0x10000000块。
- 总字节数:8GB = 8 1024 1024 * 1024 =
-
注意:8GB的数据量巨大,你的单板RAM可能没有这么大空间来一次性存储。更实际的做法是读取启动相关的关键部分(例如前几百MB)。这里我们以读取前512MB为例。
-
U-Boot读取命令(读取前512MB):
# mmc read <内存地址> <起始块号> <块数> # 起始块号: 0 # 块数: 512MB / 512字节 = 0x100000 mmc read 0x81000000 0x0 0x100000 ```0x81000000:数据加载到内存的地址。0x0:从eMMC的第0块开始读。0x100000:读取0x100000个块(即512MB)。
-
导出到Windows:
tftp 0x81000000 full_emmc_512MB.bin 0x20000000 ```0x20000000是512MB的字节数。
四、具体举例:读取并导出不同组件
假设我们使用的内存加载地址统一为 0x81000000,并且分区布局如下:
- U-Boot: 存储在eMMC最前端,大小1MB。
- Kernel: 紧随U-Boot,从1MB偏移开始,大小5MB。
- Device Tree: 紧随Kernel,从6MB偏移开始,大小64KB。
1. 读取并导出 U-Boot (u-boot.bin)
-
计算 :
- 起始块号:
0x0/0x200=0x0。 - 块数:
1MB/0x200=0x100000/0x200=0x800。
- 起始块号:
-
U-Boot读取命令:
mmc read 0x81000000 0x0 0x800 ``` -
导出到Windows:
tftp 0x81000000 u-boot.bin 0x100000 ``` -
分析 :对比这个
u-boot.bin和你电脑上原始的、正确的u-boot.bin文件。如果文件开头是0xFF或与原始文件不一致,说明U-Boot损坏,这是单板无法启动的最常见原因。
2. 读取并导出 Linux内核 (kernel.bin)
-
计算 :
- 起始块号:
1MB/0x200=0x100000/0x200=0x800。 - 块数:
5MB/0x200=0x500000/0x200=0x2800。
- 起始块号:
-
U-Boot读取命令:
mmc read 0x81000000 0x800 0x2800 ``` -
导出到Windows:
tftp 0x81000000 kernel.bin 0x500000 ``` -
分析 :对比
kernel.bin。如果损坏,U-Boot可能能启动并打印信息,但在加载内核时会失败、卡死或报错 "Kernel panic - not syncing"。
3. 读取并导出 设备树 (dts.bin)
-
计算 :
- 起始块号:
6MB/0x200=0x600000/0x200=0x3000。 - 块数:
64KB/0x200=0x10000/0x200=0x80。
- 起始块号:
-
U-Boot读取命令:
mmc read 0x81000000 0x3000 0x80 ``` -
导出到Windows:
tftp 0x81000000 dts.bin 0x10000 ``` -
分析 :对比
dts.bin。如果设备树损坏,内核可能在启动初期(通常在 "Starting kernel ..." 之后)无法识别硬件(如内存、串口),导致没有任何输出或直接卡
(2) linux系统启动正常后
- Linux系统工具 (如果Flash能被Linux识别):
dd:可以直接从块设备(如/dev/mmcblk0)读取原始数据。nanddump:用于读取MTD分区(NAND Flash)的原始数据。
(2)系统异常不能启动
- J-Link / J-Flash:功能强大,支持芯片种类最多,商业软件,但非常稳定可靠。
- OpenOCD:开源免费,完全通过命令行操作,非常灵活,适合集成到自动化脚本中。配合GDB可以进行调试。是J-Link的绝佳替代品。
nor flash分析
连接与配置
- 连接硬件 :将J-Link的SWD引脚(
VTREF,GND,SWDIO,SWCLK)连接到单板。 - 打开J-Flash:创建新项目,选择对应的CPU内核(如Cortex-A7)。
读取NOR Flash数据
NOR Flash的读取非常直接,因为它就像一块只读内存。
- 连接目标 :点击
Target->Connect。 - 执行读取 :点击
Target->Read back->Range...。- 为什么选"Range"? 因为NOR Flash是内存映射的,我们直接从它的映射地址读取即可。
- 设置地址范围 :
- Start address :
0x60000000(SPI NOR Flash的起始地址) - End address :
0x60000000 + 0x1000000 - 1(即0x60FFFFFF,读取全部16MB)
- Start address :
- 保存数据 :读取完成后,将数据保存为
readback_from_nor.bin。
nand flash分析
- 连接目标 :点击
Target->Connect。 - 执行读取 :点击
Target->Read back->Entire Chip。- 为什么选"Entire Chip"? 对于NAND Flash,这个选项会指示J-Link通过SoC的NAND控制器去读取整个芯片。在读取过程中,它会自动跳过工厂坏块和运行中产生的坏块,并将每个页的有效数据(不包括OOB区域)拼接起来,形成一个连续的bin文件。这正是我们想要的"逻辑上"的完整镜像。
- 保存数据 :读取完成后,将数据保存为
readback_from_nand.bin。
emmc分析
一,使用RKDevTool读取eMMC数据并对比
二,使用J-Link/J-Flash读取eMMC
1. 硬件连接
将J-Link的JTAG引脚(如TDI、TDO、TMS、TCK、GND、VTREF)正确连接到单板的JTAG接口。
2. 打开J-Flash
- 启动J-Flash,创建新项目。
- 选择正确的CPU内核(如Cortex-A7、Cortex-A55等)。
3. 连接目标
- 点击
Target->Connect。 - 若连接成功,右下角会显示连接状态。
4. 设置读取范围
- 点击
Target->Read back->Range...。 - 设置地址范围:
- Start address :
0x14000000(eMMC起始地址)。 - End address :
0x14000000 + 0x1000000 - 1(即0x13FFFFFF,读取全部16MB)。
- Start address :
5. 执行读取
- 点击OK,J-Link将通过SoC的eMMC控制器读取数据。
- 等待读取完成(可能需要几分钟)。
6. 保存数据
- 读取完成后,点击
File->Save Data As...,保存为readback.bin。
读取数据后,使用beyond compare工具将烧写的软件包和读出来的bin文件进行对比分析。
编程器读取flash/emmc数据
RT809H编程器
1. 适用场景
- 芯片类型:支持SPI NOR/NAND Flash、eMMC、MCU内置Flash等。
- 封装:BGA、TSOP、SOP等,支持免拆焊飞线读取。
- 典型应用:电视主板eMMC修复、路由器NAND Flash读取、工业设备固件提取。
2. 操作步骤
(1)硬件连接
- 拆焊法:拆下芯片后放入专用转接座(如BGA转接板)。
- 飞线法:焊接5根线(CLK、CMD、D0、VCC、GND)到芯片引脚,无需拆焊。
- 测试夹法:使用SOP8/SOP16测试夹(需配合RT809H专用夹具)。
(2)软件操作
- 智能识别 :
- 打开RT809H软件,点击"智能识别",自动检测芯片型号。
- 若识别失败,手动输入芯片型号(如"EMMCAUTOISP")。
- 读取数据 :
- 点击"读取",选择保存路径(如
emmc_dump.bin)。 - 支持分区读取(如Bootloader、用户数据区)。
- 点击"读取",选择保存路径(如
- 高级功能 :
- 坏块管理:自动跳过坏块,修复ECC校验错误。
- 脱机烧录:支持批量烧录,无需连接电脑。
(3)实际案例
- eMMC引导修复 :
焊接飞线后读取eMMC,擦除坏块后重新写入固件,解决设备无法启动问题。