华为HG8245H救砖番外篇之利用JTAG完成硬件初始化

前言

前几天使用UBoot恢复mtd分区时,因为误操作,导致flash全部被擦除。这下设备上电时连StartCode都跑不了。写内存跑StartCode都不行(外部设备没有初始化,无法访问DRAM):

> mdw 0x82000000
data abort at 0x82000000, dfsr = 0x00001008

可以看到,原本是放置StartCode的地址,现在都无法访问。折腾了几天,大致成功的利用JTAG完成硬件初步初始化,并且可以加载StartCode到内存并成功运行了。

问题解决思路

想要写内存来运行代码,就必须对内存进行初始化操作。但这个初始化操作应该都是StartCode里做的。现在StartCode都跑不起,更别说写内存了。

如果用JTAG来模拟StartCode的初始操作的话,也不太现实,毕竟100多KB的代码分析起来就够累人了,别说模拟了。但是如果能找到一个平衡点,模拟少量的操作,让硬件环境刚好够我利用来跑StartCode,这样实现还是比较容易的。

在网上查了很多关于ARM处理器复位时的流程和低级bootloader做的工作相关的资料。大致感觉有路可走:

一般对于采用非可直接寻址的存储设备(Nand Flash)来引导的话,CPU内部会有一个bootrom,bootrom在上电时会从非可直接寻址的存储设备的固定位置装载固定大小的内容到片内SRAM(比如从Nand Flash的0地址读取2KB内容到片内SRAM),然后设置pc过去并运行。这很小的一部分bootloader就会做简单的初始化操作,然后读取完整的bootloader到内存中的指定位置并运行。

逆向分析StartCode

StartCode的一开始就是ARM经典的中断向量表:

 

第一个中断向量就是偏移0的复位中断向量。CPU在复位时会从这里开始执行,复位中断向量直接跳到0x5C处(处理reset中断的实际代码位置)。

在StartCode的0x5C处,IDA Pro就可以直接F5了,以下为还原的伪代码(部分地方还原的有问题,手工修改过):

可以看出,在

v9 = sub_0;
v10 = sub_82000000;

之后就开始代码的自搬移了。其中v9是程序装载的位置,v10是StartCode应该被放置的地址。

也就是说,只要通过JTAG完成这两句代码之前StartCode所做的操作,就可以使用JTAG访问外部RAM了(起始地址大约在0x80000000)。

使用TCL脚本模拟实现初始化操作

好在OpenOCD支持tcl脚本,大概熟悉了一下tcl的语法,并结合逆向的数据,写了个模拟初始化操作的脚本:

使用JTAG完成基本硬件初始化

为了确保初始化准确无误,需要保证CPU上电时完全无法找到可以引导的代码。

因为我之前清空flash时,也曾尝试立刻刷回StartCode,可惜不知什么原因,只写入了2KB的StartCode,这样仍然无法完成基本的初始化。但不清楚这2KB的代码完成了哪些操作,所以一个办法就是先将flash的CE#(CE#这种后面带#字的引脚,都是低电平有效)与3.3V短接(最好是能与输出3.3V的GPIO短接,与3.3V的VCC短接电流可能较大,不知是否有不良影响),再给板子上电。HG8245H的CE#引脚在板子背面电源led附近有个上拉电阻R1542,可以在这里短接。

CPU上电后,在OpenOCD的telnet里执行上面脚本提供的sd5115_hwinit函数,等看到输出

Hardware initialization is complete!

字样的提示后,把之前dump出来的StartCode写入内存并运行:

这时应该可以看见UART里输出了久违的StartCode信息:

HuaWei StartCode 2012.02 (R13C10 Apr 22 2014 – 18:06:02)

NAND: Nand(Hardware): 128 MiB
startcode select the uboot to load
the high RAM is :8080103c
startcode uboot boot count:-1
Slave struct initializtion success!!
Use the UbootA to load first
Start from UbootA ERROR, Change to UbootB
Both UbootA and UbootB are wrong, load it by JTAG!

补充:

新版本的OpenOCD配置文件见:https://github.com/csersoft/hi_sd5115_openocd_config

Print Friendly, PDF & Email

《华为HG8245H救砖番外篇之利用JTAG完成硬件初始化》有18条留言

  1. 意思是用您的方法用jtag连上猫(确认无误),初始化cpu,加载startcode,加载uboot,整个过程ttl都没任何信息输出。但调试多次,偶尔1次2次会有输出。换不同TTL小板和不同光猫试过都这样。

    回复
  2. 用ft2232h连接8245c2(与H硬件、电路完全一样),pl2303(或ch341a)连接8245C2的TTL,8245C2的nand已拆下,给8245C2上电,cmd下运行“bin-x64\openocd.exe -s ..\scripts -f ft2232h.cfg -f hi_sd5115_jtag.cfg”(我的配置文件与openocd位于同一目录),正确识别出cpu并等待命令并显示“Info : sd5115.cpu: hardware has 6 breakpoints, 4 watchpoints”,另一cmd窗口下telnet 127.0.0.1 14444,执行sd5115_hwinit初始cpu成功,加载startcode“halt ; load_image mtd0.bin 0x82000000 ; resume 0x82000000(mtd0.bin位于上述同一目录下),显示下载成功,但这是TTL没任何输出,再加载uboot”halt ; load_image 8245H_R16_UB.BIN 0x81F00000 ; resume 0x81F00000“(也是同一目录下),显示下载成功,但TTL也没有输出结果。试过多次(所有步骤重新来),偶尔会有一两次TTL会输出。

    回复
    • 正常情况下,加载成功sc之后肯定会有输出的,没有输出就不要继续加载uboot了。
      hi_sd5115_jtag.cfg是否是github上那个最新的?是最新的话,执行sd5115_help查看示例操作,文章中的命令可能过时了。

      回复
    • proc sd5115_help { } {
      echo “Usage 1:”
      echo ” *Step1: {sd5115_hwinit}”
      echo ” *Step2: {sd5115_loadsc mtd0.bin}”
      echo ” Step3: {sd5115_enter_svc_mode}”
      echo ” *Step4: {sd5115_goto_entry} or {sd5115_goto_continue}”
      echo ” !Note!: {sd5115_goto_continue} is not recommended”
      echo ” ”
      echo “Usage 2:”
      echo ” *Step1: {sd5115_init_dram}”
      echo ” *Step2: {sd5115_loadsc mtd0.bin}”
      echo ” Step3: {sd5115_enter_svc_mode}”
      echo ” *Step4: {sd5115_goto_entry} or {resume 0x82000000}”
      echo ” ”
      }

      回复
  3. 按着sd5115_help 的步骤来,执行到sd5115_goto_entry这上一步显示“ Can’t resume (1)!”,我看了一下sd5115_goto_entry代码,是要满足getmem32 0x10100800] != 0x51152100 才会 resume ,但我看了一下getmem32 0x10100800的返回值就是0x51152100,造成不执行 resume 。请问会是什么原因造成的呢?

    回复
  4. 上述是按Usage 1来的,按Usage 2来做的话,执行到sd5115_goto_entry也是返回Can’t resume ,但如果执行resume 0x82000000,没显示结果就完成了,TTL也没输出。

    回复
  5. sd5115_hwinit
    sd5115.cpu rev 1, partnum c09, arch f, variant 4, implementor 41
    sd5115.cpu cluster 0 core 0 multi core
    target halted in ARM state due to debug-request, current mode: Abort
    cpsr: 0x000001d7 pc: 0x0000000c
    MMU: disabled, D-Cache: disabled, I-Cache: disabled
    Data fault registers DFSR: 00001897, DFAR: 47298f08
    Instruction fault registers IFSR: 00001008, IFAR: ff3448e4
    background polling: on
    TAP: sd5115.cpu (enabled)
    target halted in ARM state due to debug-request, current mode: Abort
    cpsr: 0x000001d7 pc: 0x0000000c
    MMU: disabled, D-Cache: disabled, I-Cache: disabled
    Data fault registers DFSR: 00001897, DFAR: 47298f08
    Instruction fault registers IFSR: 00001008, IFAR: ff3448e4
    cpsr (/32): 0x000001D3
    Info: (arm mrc 15 0 0 0 5) & 0xf == 0 .
    Info: call offset 0x6EC .
    Info: call offset 0x700 .
    Info: call offset 0x710 .
    Info: call offset 0xFAD4 .
    Info: call offset 0xFCD4 .
    Info: call offset 0xFAF4 .
    Info: call offset 0xFBD8 .
    Info: call offset 0xFED4 (init dram).
    Info: init dram…
    Hardware initialization is complete!
    sd5115_loadsc mtd0.bin
    127412 bytes written at address 0x82000000
    downloaded 127412 bytes in 0.343752s (361.964 KiB/s)
    sd5115_enter_svc_mode
    cpsr (/32): 0x000001D3
    sd5115_enter_svc_mode
    cpsr (/32): 0x000001D3
    sd5115_goto_entry
    Warn: Can’t resume (1)!
    sd5115_goto_continue
    Warn: Can’t resume (2)!
    getmem32 0x10100800
    1360339200
    expr [arm mrc 15 0 0 0 5] & 0xf
    0

    回复

留下评论

4 + 20 =

*

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据

%d 博主赞过: