JTAG 读取闪存

逆向工程 标签
2021-06-19 08:08:03

我正在尝试读取摩托罗拉微控制器 MPC5606B 的闪存。我看到了他的引脚,看到它使用 jtag 进行调试,因此我尝试使用它的 JTAG 接口来读取其闪存内容。

我使用工具 (UPA) 和 PC 读取 MPC 的闪存内容,但是,我想自己完成,使用我自己的嵌入式硬件而不使用 PC 工具。我在互联网上阅读了 JTAG 标准( JTAG_IEEE-Std-1149.1-2001 ),以及一些视频和解释。我阅读了 TAP 控制器状态图并阅读了一些说明。

为了更好的理解JTAG的读取,我用PC的工具读取了MCP的flash和示波器,看看通信是如何进行的,但是通信的持续时间接近10s。于是,我把整个flash都填满了零,读了内存,这样,我就可以用示波器识别内存的读数了。然而,虽然我可以使用示波器识别内存读数,但我还不能确定执行读数的确切命令顺序。阅读时间太大了,快10s了。

所以,在深入之前,我想知道是否有某种保护来访问闪存。我试图了解通信的开始,我可以在 TAP 控制器的状态机中识别进度,但我无法理解这一步的含义以及为什么要这样做。所以,我想知道:

1) 我可以确定通信是否有某种保护吗?我真的需要在进一步了解任务之前知道它,因为我需要知道任务的复杂程度才能更深入

2) 虽然我阅读了 JTAG 标准和 TAP 控制器状态机,但我无法说出我需要什么命令序列来读取闪存内容。

Abaixo está a leitura do flash do MPC5606B realizada pela ferramenta com o auxílio do PC。图像由一系列图像组成。第一个是通讯完整的图像,第二个是通讯的开始,有一个箭头指示它被撤回的地方。

在此处输入图片说明

这是我迄今为止的解释

图1:

1.1 - (TMS = 1) 测试逻辑复位

1.2 - (CLK 宽脉冲)我不知道为什么。

1.3 - (8 个 CLK 脉冲,TMS = 1)

由于 TMS 没有出现 1 我知道它没有退出 Test-logic-Reset

1.4 - (TMS = 0, 1 脉冲时钟) 进入 Run-Test-Idle


图 2:

2.1 -(TMS = 1, 2 个时钟脉冲)进入“Select IR-Scan”状态

2.2 - (TMS = 0, 2 个时钟脉冲) 进入“Shif-IR”状态

2.3 - (TMS = 0, 4 个时钟脉冲) 保持在“Shift-IR”

TDI:1000 TDO:1000 2.4 -(TMS = 1,1 个时钟脉冲)转到“Exit1-IR”

2.5 -(TMS = 1,1 个时钟脉冲)进入状态“Update-IR”

2.6 - (TMS = 0, 1 个时钟脉冲) 进入“运行-测试-空闲”


图 3:

3.1 -(TMS = 1,1 个时钟脉冲)进入“选择 DR-Scan”状态

3.2 - (TMS = 0, 2 个时钟脉冲) 进入“Shif-DR”状态

3.3 - (TMS = 0, 31 个时钟脉冲) 进入“Shif-DR”状态

32 个时钟周期相当于 4 个字节:

TDI:0x00 0x00 0x00 0x00 TDO:0xB8 0x0C 0x27 0x54 (10111000 00001100 00100111 01010100)

3.4 -(TMS = 1,1 个时钟脉冲)转到“Exit1-DR”

3.5 -(TMS = 1,1 个时钟脉冲)进入“Update-DR”状态

3.6 - (TMS = 0, 1 个时钟脉冲) 进入“运行-测试-空闲”

2个回答

手动解释 JTAG 事务可能非常令人厌烦。如果您可以将数据导出为或多或少通用的数据格式,例如 VCD 甚至 CSV 文件,您可以使用Sigrok 和 Pulseview来解码您的数据。这将解码低级 JTAG 数据;如果您了解 TAP 寄存器布局和命令集等控制器的详细信息,您可以使用运行在现有 IEEE-1149 解码器之上的解码器来扩展 Sigrok。

标签

你的解释看起来很接近我。但是,这是非常低级的视图,您需要将其带回更高的级别,至少是IR/DR。比如整个交易所1-3可以概括为:

写IR=0b100 (8),读DR=0x2AE4301D

(DR 位从最低位移入,因此您需要交换位串)

此 IR 值非常接近标准 IDCODE(4),因此我认为您的解释中存在一对一的情况,并且此交换正在读取设备 ID。事实上,值 0x2AE4301D 与我在本文档中找到的 MPC5606BF 值相匹配

至于实际的闪存读取,我怀疑它是使用原始 JTAG 命令完成的。AFAIK读取flash的常用方法如下:

  1. 使用边界扫描,设置和读取连接到闪存芯片的 CPU 引脚;基本上把 CPU 变成了一个 bit-bang flash 编程器。这显然只适用于外部闪光灯所以可能不是你的情况
  2. 使用自定义芯片特定的调试命令,在 CPU 存储空间中读取和写入闪存设备 I/O 寄存器。
  3. 使用自定义芯片特定的调试命令,将一个小的 flasher 程序上传到 CPU 的 RAM 中并让它执行。该程序会将闪存块放入 RAM 区域,然后可以通过 JTAG 将其取回主机。通过在每次执行之前设置寄存器状态,可以访问闪存的不同部分。

如果您想重现 flasher 程序正在执行的操作,我建议您使用 urJTAG 或 OpenOCD 之类的程序来执行高级 JTAG 操作(例如发送 IR 和读取 DR)。urJTAG 也有一个模式来暴力破解可能的 IR 值,它可以让你发现供应商特定的命令。