hg226g 虚拟服务器,华为HG8245H救砖番外篇之利用JTAG完成硬件初始化

原文发在我的bloghttp://blog.csersoft.net/archives/196

前言

前几天使用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内部会有一个bootrombootrom在上电时会从非可直接寻址的存储设备的固定位置装载固定大小的内容到片内SRAM比如从Nand Flash的0地址读取2KB内容到片内SRAM然后设置pc过去并运行。这很小的一部分bootloader就会做简单的初始化操作然后读取完整的bootloader到内存中的指定位置并运行。

逆向分析StartCode

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24seg000:00000000;---------------------------------------------------------------------------

seg000:00000000Bsub_5C

seg000:00000004;---------------------------------------------------------------------------

seg000:00000004LDRPC,=sub_820003A0

seg000:00000008;---------------------------------------------------------------------------

seg000:00000008LDRPC,=loc_82000400

seg000:0000000C;---------------------------------------------------------------------------

seg000:0000000CLDRPC,=loc_82000460

seg000:00000010;---------------------------------------------------------------------------

seg000:00000010LDRPC,=loc_820004C0

seg000:00000014;---------------------------------------------------------------------------

seg000:00000014LDRPC,=loc_82000520

seg000:00000018;---------------------------------------------------------------------------

seg000:00000018LDRPC,=loc_82000580

seg000:0000001C;---------------------------------------------------------------------------

seg000:0000001CLDRPC,=loc_820005E0

seg000:0000001C;---------------------------------------------------------------------------

seg000:00000020off_20DCDsub_820003A0;DATAXREF:seg000:00000004

seg000:00000024off_24DCDloc_82000400;DATAXREF:seg000:00000008

seg000:00000028off_28DCDloc_82000460;DATAXREF:seg000:0000000C

seg000:0000002Coff_2CDCDloc_820004C0;DATAXREF:seg000:00000010

seg000:00000030off_30DCDloc_82000520;DATAXREF:seg000:00000014

seg000:00000034off_34DCDloc_82000580;DATAXREF:seg000:00000018

seg000:00000038off_38DCDloc_820005E0;DATAXREF:seg000:0000001C

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

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119voidsub_5C()

{

unsignedint_R0;// r0@1

signedintv5;// r3@1

signedintv6;// r0@1

signedintv7;// r1@2

_DWORD*v8;// r2@14

int(*v9)();// r0@16

void(__noreturn*v10)();// r1@16

intv11;// r3@17

intv12;// r4@17

intv13;// r5@17

intv14;// r6@17

intv15;// r7@17

intv16;// r8@17

intv17;// r9@17

intv18;// r10@17

//enter Supervisor mode

_R0=__get_CPSR()&0xFFFFFFE0|0xD3;

__asm{MSRCPSR_cf,R0}

//arm cp15 coprocessor

__mcr(15,0,0,8,7,0);

__mcr(15,0,0,7,5,0);

__mcr(15,2,0,0,0,0);

v5=((unsignedint)__mrc(15,1,0,0,0)>>13)&0x1FF;

v6=0;

do

{

v7=0;

do

__mcr(15,0,(v6<<30)|32*v7++,7,6,2);

while(v7<=v5);

++v6;

}

while(v6<4);

if(__mrc(15,0,0,0,5)&0xF)

gotoLABEL_25;

__mcr(15,0,__mrc(15,0,1,0,0)&0xFFFFDFF8|0x802,1,0,0);

if(!(__mrc(15,0,0,0,5)&0xF))

{

sub_6EC();

sub_700();

sub_710();

}

__mcr(15,0,__mrc(15,0,1,0,0)|0x1000,1,0,0);

v10A30004=853;

v10A20100|=2u;

sub_FAD4();

dword_1010007C=-1;

dword_1010008C=-1;

dword_1010012C=-1;

dword_10100130=0xFE7FFFFF;

dword_10100138|=0x7Fu;

dword_10100140|=0x80000000;

if(dword_10100800==0x51152100)

{

if((dword_10100190&1)==1)

dword_1010005C=0x8103844D;

dword_1010005C=0x8103444D;

}

while((dword_10100038&0x10000)!=0x10000)

;

while((dword_10100038&0x40000)!=0x40000)

;

dword_1010013C=dword_1010013C&0xFFFFFFE3|0x10;

sub_FCD4();

dword_1010013C&=0xFFFFF3FF;

dword_10100138&=0xFFDFFFFF;

dword_10100138&=0xFFF7FFFF;

dword_10100054=0xFFFFFFE0;

dword_10100050=0x7FF00;

dword_10100000|=4u;

while((*v8&4)!=4)

;

sub_FAF4();

sub_FBD8();

sub_FED4();

//判断装载地址准备自搬移

v9=sub_0;

v10=sub_82000000;

if((char*)sub_0!=(char*)sub_82000000)

{

do

{

v11=*(_DWORD*)v9;

v12=*((_DWORD*)v9+1);

v13=*((_DWORD*)v9+2);

v14=*((_DWORD*)v9+3);

v15=*((_DWORD*)v9+4);

v16=*((_DWORD*)v9+5);

v17=*((_DWORD*)v9+6);

v18=*((_DWORD*)v9+7);

v9=(int(*)())((char*)v9+32);

*(_DWORD*)v10=v11;

*((_DWORD*)v10+1)=v12;

*((_DWORD*)v10+2)=v13;

*((_DWORD*)v10+3)=v14;

*((_DWORD*)v10+4)=v15;

*((_DWORD*)v10+5)=v16;

*((_DWORD*)v10+6)=v17;

*((_DWORD*)v10+7)=v18;

v10=(void(__noreturn*)())((char*)v10+32);

}

while((signedint)v9<=(signedint)&unk_1F1B4);

if(dword_10100800!=0x51152100)

LABEL_21:

JUMPOUT(&loc_820002C8);

if(__mrc(15,0,0,0,5)&0xF)

{

LABEL_25:

while(3538!=dword_10100120)

;

gotoLABEL_21;

}

}

JUMPOUT(&loc_82000304);

}

可以看出在v9 = sub_0;

v10 = sub_82000000;

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

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

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

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380

381

382

383

384

385

386

387

388

389

390

391

392

393

394

395

396

397

398

399

400

401

402

403

404

405

406

407

408

409

410

411

412

413

414

415

416

417

418

419

420

421

422

423

424

425

426

427

428

429

430

431

432

433

434

435

436

437

438

439

440

441

442

443

444

445

446

447

448

449

450

451

452

453

454

455

456

457

458

459

460

461

462

463

464

465

466

467

468

469

470

471

472

473

474

475

476

477

478

479

480

481

482

483

484

485

486#

# Hisilicon SD5115 (T?)

#

# Author : CserSoft

# Version : 1.2.2

#

transportselectjtag

if{[infoexistsCHIPNAME]}{

set_CHIPNAME$CHIPNAME

}else{

set_CHIPNAMEsd5115

}

if{[infoexistsCPUTAPID]}{

set_CPU_TAPID$CPUTAPID

}else{

set_CPU_TAPID0x4ba00477

}

if{[infoexistsENDIAN]}{

set_ENDIAN$ENDIAN

}else{

# this defaults to a bigendian

set_ENDIANlittle

}

if{[infoexistsETB_TAPID]}{

set_ETB_TAPID$ETB_TAPID

}else{

set_ETB_TAPID0x410CF231

}

jtagnewtap$_CHIPNAMEcpu-irlen4-ircapture0x1-irmask0xf-expected-id$_CPU_TAPID

# jtag newtap $_CHIPNAME etb -irlen 4 -expected-id $_ETB_TAPID

set_TARGETNAME$_CHIPNAME.cpu

targetcreate$_TARGETNAMEcortex_a-endian$_ENDIAN-chain-position$_TARGETNAME

# etm_dummy config $_TARGETNAME

# etb config $_TARGETNAME $_CHIPNAME.etb

procsd5115_dbginit{target}{

cortex_adbginit

}

procgetmem32{addr}{

mem2arrayatmp32$addr1

return[lindex$atmp1]

}

procsetmem32{addrvalue}{

mwwphys$addr$value1

}

procandmem32{addrvalue}{

setvmem[getmem32$addr]

return[expr$vmem&$value]

}

procandmem32w{addrvalue}{

setvmem[expr[getmem32$addr]&$value]

mwwphys$addr$vmem1

return$vmem

}

procormem32{addrvalue}{

setvmem[getmem32$addr]

return[expr$vmem|$value]

}

procormem32w{addrvalue}{

setvmem[expr[getmem32$addr]|$value]

mwwphys$addr$vmem1

return$vmem

}

procsd5115_startcode_offset_0x6EC{}{

andmem32w0x101800000xFFFFFFFE

}

procsd5115_startcode_offset_0x700{}{

mwwphys0x1018000C0xFFFFFFFF1

}

procsd5115_startcode_offset_0x710{}{

ormem32w0x101800540xFF

ormem32w0x101800000x1

}

procsd5115_startcode_offset_0xFAD4{}{

setmem320x10100144[expr[andmem320x101001440xFFF803FF]|0x400]

}

procsd5115_startcode_offset_0xFAF4{}{

setvcpuid[getmem320x10100800]

if{$vcpuid==0x51151100}{

ormem32w0x130000000x80000

ormem32w0x101060080xC0

ormem32w0x101060080x300

}elseif{$vcpuid==0x51152100}{

ormem32w0x130000000x60000

ormem32w0x101080080xF0

}else{

ormem32w0x130001C80x100

ormem32w0x101060080xC00

andmem32w0x130000000xFFFFFFFB

andmem32w0x130001C80xFFFFFFDF

ormem32w0x101060080x3000

andmem32w0x130000000xFFFDFFFF

andmem32w0x130001C80xFFFFFFBF

}

}

procsd5115_startcode_offset_0xFBD8{}{

setvcpuid[getmem320x10100800]

if{$vcpuid!=0x51151100}{

if{$vcpuid==0x51152100}{

setmem320x104005000x1FFF800

andmem32w0x101001340xFFFFFFFC

andmem32w0x101070080xDDFFFFFF

ormem32w0x101070040x22000000

ormem32w0x101070000x22000000

andmem32w0x101080080xFFF7FFFF

ormem32w0x101080040x80000

ormem32w0x101080000x80000

andmem32w0x101001440x3FFFFFFF

}else{

setmem320x104005000x1FFF800

andmem32w0x101001340xFFFFFFFC

ormem32w0x101070040x18000

andmem32w0x101070000xFFFE7FFF

ormem32w0x101070000x18000

andmem32w0x1300016C0xFFFFFFFC

}

}

}

procsd5115_startcode_offset_0xFCD4{}{

setvcpuid[getmem320x10100800]

if{$vcpuid==0x51151100}{

andmem32w0x1010012C0xFFBFFFFF

andmem32w0x101001380xFFFFFFBF

ormem32w0x101000800x9

andmem32w0x1010013C0xFFFFEFFF

setmem320x1010005C0x81020248

while{[andmem320x101000380x10000]!=0x10000}{sleep1}

ormem32w0x1010007C0x9

ormem32w0x101001480x2

ormem32w0x1010012C0x400000

ormem32w0x101001380x40

}elseif{$vcpuid==0x51152100}{

if{[andmem320x101001901]==1}{

andmem32w0x1010012C0xFFBFFFFF

andmem32w0x101001380xFFFFFFBF

ormem32w0x101000800x9

andmem32w0x101001440xFEFFFFFF

andmem32w0x101001400xFFFFCFFF

ormem32w0x101001400x40000000

setmem320x101000740x81028249

while{[andmem320x101000380x40000]!=0x40000}{sleep1}

ormem32w0x1010007C0x9

ormem32w0x101001480x2

ormem32w0x1010012C0x400000

ormem32w0x101001380x40

}else{

while{[andmem320x101000380x20000]!=0x20000}{sleep1}

}

}else{

andmem32w0x1010012C0xFFBFFFFF

andmem32w0x101001380xFFFFFFBF

ormem32w0x101000800x9

setmem320x1010011C0x81028648

while{[andmem320x101000380x20000]!=0x20000}{sleep1}

ormem32w0x1010007C0x9

ormem32w0x101001480x2

ormem32w0x1010012C0x400000

ormem32w0x101001380x40

}

}

procsd5115_startcode_offset_0xFED4{}{

setvcpuid[getmem320x10100800]

if{$vcpuid==0x51151100}{

setmem320x101020101

setmem320x1010201C0x8DF40630

setmem320x101020200x10184

setmem320x1010202C0x132

setmem320x101020400x80000000

setmem320x101020500x62330A08

setmem320x101020540x7F525616

setmem320x1010205C0x4BE58352

setmem320x101020F41

setmem320x101020580x6230A000

setmem320x101020040

while{[andmem320x101020004]!=0}{sleep1}

setmem320x101024040x80000000

while{[andmem320x101024101]!=1}{sleep1}

setmem320x101024180xDC000

setmem320x101025840x5D

setmem320x1010240C0x3008401

setmem320x101024440x48B

setmem320x101024480x51106644

setmem320x1010244C0x1A81629A

setmem320x101024500x100220C8

setmem320x101024540x1520

setmem320x101024586

setmem320x1010245C0

setmem320x101024600

setmem320x101025C00x44000887

setmem320x101024400xF008003E

setmem320x101024680x1001541

setmem320x101024040xFFF3

while{[andmem320x101024100x80000FFF]!=0x80000FFF}{sleep1}

setmem320x101020580x6230A05F

setmem320x101020200x410185

setmem320x1010201C0x8DF40630

setmem320x101022000x305133

setmem320x101022040x3062CC

}elseif{$vcpuid==0x51152100}{

if{[andmem320x101001901]==1}{

setmem320x101020101

setmem320x1010201C0x80000600

setmem320x101020200x584

setmem320x1010202C0x142

setmem320x101020400x80000000

setmem320x101020500x63440E0A

setmem320x101020540xFF526720

setmem320x101020580x6240A000

setmem320x1010205C0xFFDFF5F2

setmem320x101020F40x21

setmem320x101020AC0x3000501

setmem320x101020040

while{[andmem320x101020004]!=0}{sleep1}

setmem320x101024040x80000000

while{[andmem320x101024101]!=1}{sleep1}

setmem320x101024180x5C000

setmem320x1010248C0xF01E78

setmem320x1010241C0x1F40FA10

setmem320x101024200x61A808CA

setmem320x101024280xC83D090

setmem320x1010242C0x1F4186A0

setmem320x101024440x48B

setmem320x101024480x6D538844

setmem320x1010244C0x22820282

setmem320x101024500x1002EA00

setmem320x101024540x1930

setmem320x101024580x42

setmem320x1010245C8

setmem320x101024600

setmem320x101024640x210000

setmem320x101024680x210035C3

setmem320x101025840x2D

setmem320x101025C00x44000E81

setmem320x101026000x44000E81

setmem320x101024400xF000603E

setmem320x101024040xFFF3

while{[andmem320x101024101]!=1}{sleep1}

setmem320x101020580x6240A079

setmem320x101022000x304132

setmem320x101022040x306132

setmem320x101022080x304066

setmem320x101022100x306132

}else{

setmem320x101020101

setmem320x1010201C0x80000601

setmem320x101020200x580

setmem320x1010202C0x142

setmem320x101020400x80000000

setmem320x101020500xC466150F

setmem320x101020540xFF545540

setmem320x101020580x84610000

setmem320x1010205C0xFFDFF4F4

setmem320x101020F40x21

setmem320x101020AC0x3000501

setmem320x101020040

while{[andmem320x101020004]!=0}{sleep1}

setmem320x101024040x80000000

while{[andmem320x101024101]!=1}{sleep1}

setmem320x101024180x5C000

setmem320x1010248C0xF01860

setmem320x1010241C0x1900C810

setmem320x101024200x4E200708

setmem320x101024280xA030D40

setmem320x1010242C0x19013880

setmem320x101024440x48B

setmem320x101024480x550F6644

setmem320x1010244C0x22820202

setmem320x101024500x1002EA00

setmem320x101024540x1510

setmem320x101024580x42

setmem320x1010245C0

setmem320x101024600

setmem320x101024640x210000

setmem320x101024680x210035C3

setmem320x101025840x2D

setmem320x101025C00x44000E81

setmem320x101026000x44000E81

setmem320x101024400xF008603E

setmem320x101024040xFFF3

while{[andmem320x101024101]!=1}{sleep1}

setmem320x101020580x846100C3

setmem320x101022000x304132

setmem320x101022040x306132

setmem320x101022080x304066

setmem320x101022100x306132

}

}else{

setmem320x101020101

setmem320x1010201C0xE92E0601

setmem320x101020200x1F180

setmem320x1010202C0x132

setmem320x101020400x80000000

setmem320x101020500xC466130E

setmem320x101020540xFF535625

setmem320x1010205C0x7E58484

setmem320x101020F41

setmem320x101020580x74511000

setmem320x101020AC0x3000501

setmem320x101020040

while{[andmem320x101020004]!=0}{sleep1}

setmem320x101024040x80000000

while{[andmem320x101024101]!=1}{sleep1}

setmem320x101024180xDC000

setmem320x1010240C0x3008401

setmem320x101024440x48B

setmem320x101024480x4D0E6644

setmem320x1010244C0x1A812A30

setmem320x101024500x1001A0C8

setmem320x101024540x1320

setmem320x101024580x42

setmem320x1010245C0

setmem320x101024600

setmem320x101024680x11001547

setmem320x101025C00x44000887

setmem320x101026000x44000E81

setmem320x101024400xF008003E

setmem320x101025840x1D

setmem320x101024040xFFF3

while{[andmem320x101024100x80000FFF]!=0x80000FFF}{sleep1}

setmem320x101020580x7450F09E

setmem320x101020200x40EF01

setmem320x101020F80

setmem320x101022000x305133

setmem320x101022040x306266

setmem320x101022080x306066

setmem320x1010220C0

setmem320x1010201C0xB9D60601

}

}

procsd5115_hwinit{}{

halt

#enter Supervisor mode

regcpsr0x1D3

armmcr1508700

armmcr1507500

armmcr1520000

setv5[expr([armmrc151000]>>13)&0x1ff]

setv60

while{$v6<4}{

setv70

while{$v7<=$v5}{

setvtmp[expr($v6<<30)|32*$v7]

setv7[incr$v7]

armmcr150762$vtmp

}

setv6[incr$v6]

}

if{[expr[armmrc150005]&0xf]!=0}{

echo"Error 1 !"

return

}

armmcr150100[expr[armmrc150001]&0xFFFFDFF8|0x802]

if{[expr[armmrc150005]&0xf]!=0}{

sd5115_startcode_offset_0x6EC

sd5115_startcode_offset_0x700

sd5115_startcode_offset_0x710

}

armmcr150100[expr[armmrc150100]|0x1000]

setmem320x10A300040x00000355

ormem32w0x10A201000x2

sd5115_startcode_offset_0xFAD4

setmem320x1010007C0xFFFFFFFF

setmem320x1010008C0xFFFFFFFF

setmem320x1010012C0xFFFFFFFF

setmem320x101001300xFE7FFFFF

ormem32w0x101001380x7F

ormem32w0x101001400x80000000

setvcpuid[getmem320x10100800]

if{$vcpuid==0x51152100}{

if{[expr[getmem320x10100190]&1]==1}{

mwwphys0x1010005C0x8103844D1

}

mwwphys0x1010005C0x8103444D1

}

while{[andmem320x101000380x10000]!=0x10000}{sleep1}

while{[andmem320x101000380x40000]!=0x40000}{sleep1}

setmem320x1010013C[expr[andmem320x1010013C0xFFFFFFE3]|0x10]

sd5115_startcode_offset_0xFCD4

andmem32w0x1010013C0xFFFFF3FF

andmem32w0x101001380xFFDFFFFF

andmem32w0x101001380xFFF7FFFF

setmem320x101000540xFFFFFFE0

setmem320x101000500x7FF00

ormem32w0x101000000x4

while{[andmem320x101000000x4]!=0x4}{sleep1}

sd5115_startcode_offset_0xFAF4

sd5115_startcode_offset_0xFBD8

sd5115_startcode_offset_0xFED4

echo"Hardware initialization is complete!"

}

$_TARGETNAMEconfigure-eventreset-assert-post"sd5115_dbginit $_TARGETNAME"

# init

# dap apsel 1

使用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写入内存并运行

1halt ; load_image binary/mtd0.bin 0x82000000 ; resume 0x82000000

这时应该可以看见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

最新sd5115 openocd 配置文件见https://github.com/csersoft/hi_sd5115_openocd_config

安卓应用层抓包通杀脚本发布《高研班》2021年3月班开始招生

上传的附件

hi_sd5115_jtag.zip

2.61kb28次下载

blog.csersoft.net-华为HG8245H救砖番外篇之利用JTAG完成硬件初始化.pdf

154.44kb29次下载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值