EDA365欢迎您!
您需要 登录 才可以下载或查看,没有帐号?注册
x
; h2 g; M/ g4 u! E
本文转自:https://www.amobbs.com/thread-5680586-1-1.html 很多人买迅为iTop4412精英板,在Android或Linux+Qt跑起来后学习开发调试应用程序或驱动,但在linux内核运行前发生了什么?能进行什么开发工作?并没有完整资料。其实,只要一根百元价位的JLINKv9,就可以搭建一个实用的boot阶段程序开发环境,使我们可以深入到貌似神秘的史前时代一探究竟。 我的精英板和JLINKv9刚到手一周左右,花了两三天功夫在环境搭建上,也遇到了一些坑,幸运的是都解决了。下面我就总结介绍一下这几天的工作,希望能对感兴趣的人有所帮助,能抛砖引玉就更好了。当然,在解决问题过程中,除了靠自己积累的知识外,也参考学习了网上的一些资料,在此向作者表示谢意,并尽量列出所参考的文章。 还要声明一点,就是boot阶段的开发当然需要一定的底层硬件知识。虽然本文所涉较少,但还是提醒初学者谨慎操作,以免损坏硬件。 正文: 系统环境:win8.1+VMWare+ubuntu14.04LTS 硬件:iTop4412精英板+JLINKv9调试电缆+SD卡及读卡器。JLINKv9电缆常用JTAG接头是2.54mm间距的大头,精英板上的JTAG接口是2mm间距的小头,所以还需要购买或自制转接板和小头电缆(淘宝售价10元以内)。硬件上一个小坑是我买的JLINKv9的JTAG接口的2脚有3.3V输出(SEGGER手册上写明NC,但有3.3V输出不知为什么),而精英板的JTAG口的1脚和2脚是短路的,这就使得如果不做改动直接连接,就使得JTAG1脚的检测电压是自身2脚输出的3.3V,而不是精英版输出的1.8V,使JLINK识别目标失败。改起来很简单,吧转接板大头和小头2脚间的连线划断就可以了。 关于JLINK软件的安装,只要去SEGGER官网下载最新版的Linux版的DEB安装包,用dpkg命令安装就可以了。还应该在Windows宿主机上安装win版的JLINK软件,这样宿主机也可以识别JLINK,出问题时也可和Linux虚拟机作对照。 首先确认JLINK可以识别4412。把JLINK电缆和串口电缆接好,开启Ubuntu虚拟机,在虚拟机Wokstation->虚拟机->可移动设备 菜单下把串口和SEGGER J-link与虚拟机连接好。开启虚拟机串口终端(我用的C-kermit),精英板上电进入u-boot状态。进入JLINK安装目录(缺省/opt/SEGGER/JLink/),运行 JLinkExe,如果没问题应该有VTref = 1.8xxV的目标检测电压输出(如果检测电压为3.3V,说明JTAG转接板未改,参考前面)。由于JLINKv9不直接支持4412,所以不能自动识别目标,需手动连接。按提示输入connect命令,依次输入“CORTEX-A9”,回车,“J”,回车,“-1,-1”,回车,4000,回车。界面如下图。 此时若JLINK和目标板软硬件没问题,则4412的cortex-a9 CPU#0能被识别,这正是我们期待的。截图如下。 在此基础上可以做些实验,发现如下问题:cp15协处理器读写命令无效;只能调试单核;0x02000000物理地址开始的内存无法读取,而这是关键的iROM和iRAM映射区域,史前文明的秘密宝藏就在这里。第一个问题可以在编程时用汇编指令读cp15到通用寄存器然后设置相应断点来一定程度规避。第二个问题对于调试boot阶段程序来说不是问题,因为这时本来只有CPU#0运行。第三个问题就得认真对待了。从上图可以看到此时MMU使能,物理地址已不能直接应用。我还没有深究此版本u-boot源码,不知道该段物理地址是否映射到某个虚拟地址。换个思路,可以重写一个BL2阶段的程序,该程序为目的只是一个无限循环,用JLinkExe的halt命令终止其运行,就可保留BL1刚结束而BL2刚开始时的现场。让我们实现这个思路看看会得到什么。 我利用较新版(建议2017以后)的u-boot源码改造生成SPL的方式产生所需要的BL2程序。ARM交叉工具链用Linaro的arm-eabi-系列。按照上述思路,只要在u-boot源码的arch/arm/cpu/armv7/start.S的第一条指令改为跳转自身地址的指令即可。但经过实验,以此生成的BL2程序在精英板运行后,JLinkExe检测到的VTref为0V,JLINK无法连接目标。由此猜想是BL2程序缺少必要的电源管理设置。参考网上文章http://blog.csdn.net/techping/article/details/69911634,找到该文中arch/arm/mach-exynos/board.c的电源管理部分代码,根据相关4412的寄存器地址,查4412手册知道要设置PSHOLD引脚输出,又对照精英板的原理图,发现PSHOLD信号确实是控制电源管理芯片的,就用汇编实现此功能。修改后的start.S入口处代码如下: reset:
9 E% E, p; r I+ j. ^7 n& x/* Allow the board to save important registers */
# p! |( Z9 T% d4 ?% J/*b save_boot_params*/ n5 o$ `" {3 n/ Y
ldr r1, =0x1002330c) B- P, q3 q5 k. x% N& H
ldr r0, [r1]
4 @9 k e( N" D& n9 a; Odmb
1 B3 l/ @2 ~6 S1 |ldr r2, =0x300! L& K T' |# ~% s" B, ^; P0 Q- M
orr r0, r0, r2 J" s! A) i! g. h8 H- f& {9 L
dmb$ R, T3 Q+ G1 d' y( \
str r0, [r1]' N& L/ V+ J2 t2 Z
4 W) H/ U( Z8 {* n. d. F$ O3 S! H5 cldr r1, =0x11000c088 I4 Q* [9 D* U8 ~) \# e; o
mov r0, #0: H1 D. U q! M0 g) E
dmb
4 P9 |8 j3 E* J6 V' X) L. O* e ]8 ]4 Dstr r0, [r1]$ M' ?6 x T/ q/ i2 M
reset11:" ?5 Q+ c- m0 A
breset11 那u-boot的配置用什么?也是这篇网文建议用三星origen板子的配置改。只要把include/configs/origen.h中#define CONFIG_SPL_TEXT_BASE 的值改为0x02023400即可。这个地址是三星提供的BL1程序对它引导的BL2程序的要求。此配置项的作用就是生成SPL程序的lds链接文件的.ram区域的起始地址和设置.TEXT段的起始地址(二者相同),这可在SPL的Makefile文件中看到。然后在新版u-boot目录下运行make origen_defconfig,配置完后交叉编译新版u-boot即可。此时在新版u-boot源码目录下生成spl目录,其中的u-boot-spl.bin就是我们要得到的BL2程序镜像。 下面的工作需要借用精英板光盘提供的CodeSign4SecureBoot_SCP目录文件和旧版u-boot源码。在旧版u-boot源码下有个mkbl2程序是用来生成最终14K大小的bl2.bin文件的,但此程序有问题,用它生成会产生Unsupported szie错误。网上有改过的该程序源码,为方便我直接粘贴如下 /* - e, _7 Z6 w+ n5 U7 M' U
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
: S+ b. }4 [, X( N4 P4 W * http://www.samsung.com/
9 [. P9 D( ~+ k' `$ i7 q * ' E* Y, W. q, @' F$ B
* This program is free software; you can redistribute it and/or modify 8 l3 o; T& A$ `
* it under the terms of the GNU General Public License version 2 as ' w9 H! c" l# r
* published by the Free Software Foundation.
: e- f2 s2 w2 O */
3 L* l. X9 U x 6 m4 h9 f$ B I- M( `( u9 _
#include <stdio.h> 6 C& f3 |* J# R7 T Y. t. j
#include <string.h> y( \; u; b0 O; H
#include <stdlib.h> + Z) p. |' H+ q3 s7 q U4 U ^
7 ?% @. P$ |$ c! s0 n, X" Y3 Yint main (int argc, char *argv[])
{ G: W; \$ l& N{ 3 N$ Q9 N9 }# F \9 N
FILE *fp;
0 X+ q5 z Z& s% [2 A# u unsigned char src; 9 b* O& u. L: }7 U* P5 ~
char *Buf, *a;
$ }+ t" M. y/ {. c int BufLen;
) e. R, Z; G f1 A int nbytes, fileLen; $ f- S6 s& A" U: x. F
unsigned int checksum = 0;
7 a2 ^$ Z6 t* ^. X int i; ! C8 n$ ^- N. W; E* c" s6 ]
6 n0 z' l9 N9 q1 f/ G& x( s1 p2 A! ? `
if (argc != 4)
' S) T, E0 V9 P; [1 t1 P w { 1 d; o' e. U5 l* N7 A! V5 w
printf("Usage: mkbl1 <source file> <destination file> <size> \n");
4 t3 [4 _7 i; ^9 p y2 B return -1;
7 _. b& K3 \% E; V: a+ a6 S C' j } ) m' `, t3 _6 U% z" @+ a
. }% K. z7 b: w0 ^- |4 x5 m
BufLen = atoi(argv[3]);
8 b" x* y! m+ ] Buf = (char *)malloc(BufLen);
# \' D. k) R3 k0 J, Q2 ]+ s% s memset(Buf, 0x00, BufLen); " M/ ]' a; J! f& \
0 @ w0 r/ L# q) G; o fp = fopen(argv[1], "rb");
7 i: y8 [8 C \4 E7 P n if( fp == NULL) * U% }- F0 l2 Q
{
& C' `, u: B1 @2 U' Q2 f8 l printf("source file open error\n");
& d. D2 n8 J9 X% S, H' f free(Buf);
* j% Q2 _& z; N return -1; # Q) n: H$ E9 w* u
}
# ^8 C) T3 g! j
2 |; k2 y3 _& `, N1 h$ F q( { fseek(fp, 0L, SEEK_END); ' d- o4 L. {, C! E) i7 p
fileLen = ftell(fp); : ?4 K4 x; }, O7 U7 g4 E
fseek(fp, 0L, SEEK_SET);
+ d) O! Z7 ~1 e/* & m" g. T+ E) p, e) [9 ?
if ( BufLen > fileLen ) ; W4 t$ C" L1 p8 i$ |& }
{ % G8 d0 l' _2 S# E0 ]4 U
printf("Usage: unsupported size\n"); ' H6 Y1 W8 h5 C3 f4 C. u
free(Buf); 0 U. M5 l1 k: h. ~. a
fclose(fp); ( u$ i e2 U z! F8 a2 a B
return -1; " \# e$ N+ I, c$ d* \
}
( }3 Q s; b. m# B) N0 I2 z. j9 y*/ 8 A* a) C3 n- k. h% a
//nbytes = fread(Buf, 1, BufLen, fp); ( l# }. {1 R7 ^; N/ E: d# s
if(BufLen > fileLen) # j1 x3 F: h* q4 ]4 H- t+ A1 l
nbytes = fread(Buf, 1, fileLen, fp); $ a( h0 E5 V- @8 e% r' `
else
0 U% H7 b8 c4 ^/ T# m3 J* ` nbytes = fread(Buf, 1, BufLen, fp); 1 u$ R4 Q; b$ S6 I+ M- c, d) m
/* 8 F- t' h0 z4 ], W+ C/ X0 o
if ( nbytes != BufLen )
0 }! E1 B. Y# Y5 R# ~. h: @! a; [( o { : N7 \/ H( w# v
printf("source file read error\n"); $ m8 g1 C3 f" P+ m, _/ I
free(Buf);
4 t4 n& C& G7 {4 ] i6 T% u- n fclose(fp);
`6 e3 ~( `" S7 R8 h4 S* e* N return -1; . p- g/ \5 t+ U" R% v" F
} & ^) Q: o u- P; |* ]4 w3 d& M3 k
*/ " S( n: n6 o+ C' `+ Y( |0 U
fclose(fp);
* o: o. {% K# Y* I, I; [/ m& u q5 P( G* ~* f, ~+ ]6 n+ X1 h# H/ P
for(i = 0;i < (14 * 1024) - 4;i++) 7 U' X$ o. h5 B8 ~& [: X# K
{ - x( q: a s, y/ F X; [: E
checksum += (unsigned char)(Buf); 2 u V( T7 b- m, i6 W& W* B6 X
} , O$ y6 I, O' I
*(unsigned int*)(Buf+i) = checksum;
6 u3 V; b. b/ K! K5 V0 c9 G
$ u2 G3 n' b( w4 @9 W fp = fopen(argv[2], "wb"); $ o+ b/ ], ]4 g& x L
if (fp == NULL)
# D4 j% H; R7 _4 h {
# E2 z" i5 t0 w$ m1 k6 } printf("destination file open error\n"); : d0 K6 X: b) f, z- e
free(Buf); 3 Y# }( z$ S3 r/ m$ a* i" I
return -1;
8 p; f; T2 z+ q! [+ h3 }- `, {0 m* Q } 8 {/ }& ]) {$ z3 ~+ |
" d3 \0 Z- k8 j! i
a = Buf; 5 h) l1 W0 E" h( G
nbytes = fwrite( a, 1, BufLen, fp);
( ^2 j0 p7 l) l , `6 K' S F4 \. v4 r6 i& M
if ( nbytes != BufLen )
: t6 S h: Y/ R; r5 t, U {
) G$ e; [1 s1 X! X: X printf("destination file write error\n"); 3 A6 Y% v! _. a J. \
free(Buf);
* Z4 {# E( f; U; z fclose(fp); * x1 N4 y; C7 A' u* y3 I
return -1;
4 \) v* @$ D$ P! X1 _ } 8 x* ^& J9 e0 M# R; ?% y3 U% f
0 T% B" Z: ?5 a; L+ L
free(Buf);
: @( z; T ~2 S0 g fclose(fp); 6 r7 Y+ h7 D) v1 Z& Y1 u% D& y
3 ]! N# V G. A" Y& M# O: w
return 0; 8 S G# j" q; c* p8 I
} 读者可用此源码本地编译生成可用的mkbl2程序来代替旧版的。然后把编译新版u-boot生成的u-boot-spl.bin拷贝在旧版u-boot源码下。在旧版u-boot源码目录下运行如下命令 ./mkbl2 u-boot-spl.bin bl2.bin 14336 生成可用的bl2.bin镜像。把bl2.bin拷贝到CodeSign4SecureBoot_SCP目录下,并把旧版u-boot目录下的E4412_N.bl1.bin拷贝到CodeSign4SecureBoot_SCP目录下。在CodeSign4SecureBoot_SCP目录下新建一shell脚本文件my_build_bin.sh,内容如下 #!/bin/sh2 ^8 Y" b- m m) k
cat E4412_N.bl1.bin bl2.bin all00_padding.bin > u-boot-iTOP-4412.bin5 m7 D( a# Q& f( Q) G4 n
mv u-boot-iTOP-4412.bin ~/iTop/iTop4412_uboot/ 其中mv命令的目标目录是我的旧版u-boot源码目录,读者应改为自己的相应路径。 在CodeSign4SecureBoot_SCP目录下运行./my_build_bin命令,在旧版u-boot目录下就有u-boot-iTop-4412.bin文件生成,该文件大小正好为24k,就是我们要烧到SD卡的启动镜像,包括BL1和BL2阶段的程序。然后参考ITop4412 精英板手册出厂前首次烧录TF卡方法用旧版u-boot目录下的mkuboot命令制作SD卡。把SD卡插入精英板,拨码开关设置为TF卡启动模式,启动精英板,用JLinkExe连接目标板,此时输出部分截图如下 可以看到此时MMU是关闭的。现在用mem再查看0x02000000物理地址区域,可以访问了!貌似JLINK不支持一次读取大量内存内容,我用savebin命令分次读取了iROM在0x02000000的64k映像,合并成一个文件,并用arm-eabi-objdump反汇编之,就可以弄清完整史前时代的来龙去脉了。下面是iROM程序的反汇编成果的开始部分,有兴趣的读者可以留邮箱,我会把完整的64k iROM程序镜像发给你。 irom: fileformat binary
* o2 O+ ^6 a7 b% {; h) k6 ^! ]
' c2 a7 T) Z* g* k1 {
9 J# P1 t( E; ^Disassembly of section .data:
" `! N- x, a; {- x+ r
0 ^& A+ U1 ~4 |6 @2 X# i+ P: Y00000000 <.data>:
) r. A$ _6 ~7 |& S7 L 0: ea000006 b 0x20
`/ Q/ F* I! m4 M: U 4: eafffffe b 0x42 _8 H: j: \( C
8: eafffffe b 0x8+ H( B. Z) u' [ ^2 w3 {4 W4 `
c: eafffffe b 0xc
/ O8 g0 n: w7 D; C) ? 10: eafffffe b 0x10
$ E$ O* R# T/ z1 Z) g/ g/ N 14: eafffffe b 0x14. a9 W$ w4 \: V
18: ea00301a b 0xc088# Z' T# H. B* @
1c: ea00301b b 0xc090
+ \* X2 P$ z, g$ U- Z 20: e59f01a4 ldr r0,[pc, #420] ; 0x1cc
' G3 s( ~, x- T1 @& [7 O 24: e3a01000 mov r1,#0. o. {# E* q& k* I ]
28: e5801000 str r1,[r0]
! Z; i: t2 q' E( S E0 L ]- N 2c: e59f019c ldr r0,[pc, #412] ; 0x1d07 M, F9 ?, p/ o3 k- C' b4 R9 m
30: e5900000 ldr r0,[r0]
5 X& P5 B3 i( J- e4 I" U 34: e200003e and r0,r0, #62 ; 0x3e' W! I/ M0 |8 b0 G! r/ w" |
38: e330003e teq r0,#62 ; 0x3e
5 t1 U; T" n% l 3c: 1a00000d bne 0x78$ j' P# E* u3 Y* i v
40: e59f018c ldr r0,[pc, #396] ; 0x1d4& i( M1 G# K, K( t( }7 }
44: e5900000 ldr r0,[r0]# Y0 J7 `4 t5 ?/ i, _
48: e3100001 tst r0,#1 Z& D, J3 T$ g/ q" w$ {
4c: 1a000009 bne 0x78 m7 ]/ ~% a: x1 L+ T" |
50: e59f2180 ldr r2,[pc, #384] ; 0x1d8
) R: N6 Y" r. S( N 54: e5922000 ldr r2,[r2]
P# }9 P' Q! B3 k6 M$ p! v$ a 58: e3e03000 mvn r3,#0
: g0 D) \" [% o2 M" x 5c: e1120003 tst r2,r3, _2 B4 d$ O' M. [6 r
60: 1a000003 bne 0x749 ?7 r+ _( M4 O2 h) k4 `+ S6 P1 k
64: e59f0170 ldr r0,[pc, #368] ; 0x1dc/ z' n! N; N% q2 W
68: e59f1170 ldr r1,[pc, #368] ; 0x1e09 a/ o! J% Z4 L _5 T0 v
6c: e5801000 str r1,[r0]" H3 Y0 ]7 q) o* f# s/ C( s8 i
70: e59f2164 ldr r2,[pc, #356] ; 0x1dc+ H) T0 ^% l3 ~& |* A& _
74: e1a0f002 mov pc,r2
2 O" l9 {+ l; R9 i 78: e321f0d3 msr CPSR_c,#211 ; 0xd3: M& Y+ X# Y; v L/ p
7c: ee110f10 mrc 15,0, r0, cr1, cr0, {0}1 G- w; ~8 N3 f) Z
80: e3c00001 bic r0,r0, #1
! \* Q1 |0 m! l; R- S 84: e3c00004 bic r0,r0, #4% t2 K. a* w6 s' w$ L
88: e3a02281 mov r2,#268435464 ; 0x10000008
5 E* O3 d1 X: H3 d 8c: e5923000 ldr r3,[r2]
|7 ^( v1 g5 P 90: e3130501 tst r3,#4194304 ; 0x400000. X9 x* W4 r& a, b
94: 0a000002 beq 0xa45 Q3 `0 }( y. R5 |( G" \
98: e3c00a01 bic r0,r0, #4096 ; 0x1000
4 o' j! O( r7 B N& ?3 y 9c: ee010f10 mcr 15,0, r0, cr1, cr0, {0}
5 R3 ?7 i6 T3 e+ z# l5 C a0: ea000006 b 0xc03 Y% a2 Z. _; m" n
a4: e3a00000 mov r0,#0: V- ?. g( ^- D) q5 m7 G p4 k- }
a8: ee080f17 mcr 15,0, r0, cr8, cr7, {0}
4 e" s% R4 j$ q. b) q ac: ee070f15 mcr 15,0, r0, cr7, cr5, {0}' ?; i, E/ r) _
b0: eb0022ea bl 0x8c60
0 V- s- Y7 Y; V1 ~' `0 G) o b4: ee110f10 mrc 15,0, r0, cr1, cr0, {0}
4 |8 |8 d5 N7 {3 h2 [ b8: e3800a01 orr r0,r0, #4096 ; 0x1000
/ Y8 {5 ^' y. R) d7 q( b6 T bc: ee010f10 mcr 15,0, r0, cr1, cr0, {0}+ X) Z1 Z4 M* g2 @8 e! Z! x3 V1 z
c0: ee10cfb0 mrc 15,0, ip, cr0, cr0, {5}1 _0 T1 _( ?% c: W
c4: e20cc003 and ip,ip, #3: I) U) p! U; ^+ U
c8: e59f2114 ldr r2,[pc, #276] ; 0x1e4+ i* B" x; ~7 X* k: b+ Z
cc: e082010c add r0,r2, ip, lsl #2
% \8 A; z8 [/ R; E ^ d0: e35c0000 cmp ip,#0% l: k+ y6 Q/ R( K, Q. E
d4: 1a0022da bne 0x8c44: y' ^* y9 M5 |7 a% h
d8: e59f0108 ldr r0,[pc, #264] ; 0x1e8/ B7 T; V8 h% Z6 M% R0 ?2 c
dc: e5900000 ldr r0,[r0]
& T9 L2 U+ D6 k; B8 ` e0: e3a01102 mov r1,#-2147483648 ; 0x80000000
* Q. R0 A! a1 ?! Q e4: e1100001 tst r0,r1
' _2 B: k. m3 C! f+ c, q6 | e8: 0a000024 beq 0x180
3 I+ x& v8 z9 @5 e. h* D ec: e59f00f8 ldr r0,[pc, #248] ; 0x1ec
( y" H. z$ f* I$ D- J. @ f0: e5900000 ldr r0,[r0]4 x! |4 K7 i$ d0 h
f4: e3100001 tst r0,#1
$ h9 ~3 O$ y7 a# H4 g% k f8: 0a000020 beq 0x180
3 j- x0 a( G" ?0 j8 V, S' C# m, p fc: e59f00ec ldr r0,[pc, #236] ; 0x1f06 a5 C7 J, I- w5 K
100: e5900000 ldr r0,[r0] 至此,我们的史前时代探险完成了。作为一个有价值的副产品,我们也建立了用JLINK搭建的boot阶段程序调试环境。下面我简要介绍下gdb调试环境的搭建。 退出JLinkExe,运行JLinkGDBServer -device CORTEX-A9 -speed 4000命令,则JLinkGDBServer就与目标建立了连接,并等待gdb连入。在另一个虚拟终端下运行arm-eabi-gdb命令,在(gdb)提示符下输入target remote localhost:2331命令与JLinkGDBServer建立连接,用file命令关联新版u-boot源码spl目录下的u-boot-spl文件,就可以进行源码级调试了。这样,我们就搭建了一个实用的boot阶段程序调试环境,并可以借用新版u-boot源码平台开发属于自己的boot程序了。 附主要参考的文章链接: http://blog.csdn.net/techping/article/details/69911634 http://www.cnblogs.com/humaoxiao/p/4166230.html http://blog.csdn.net/lizuobin2/article/details/52832857
" h8 _+ q) ]9 c# h |