EDA365欢迎您!
您需要 登录 才可以下载或查看,没有帐号?注册
x
6 L$ Y, S h# p! y* X5 P q
本文转自: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:
3 x! ^ j1 U: W& `' \3 z/* Allow the board to save important registers */8 v. C6 \- k* x; s$ o
/*b save_boot_params*/ y: k( R* _' f" ^: f2 c1 O
ldr r1, =0x1002330c3 n% H9 _- |- h, i6 B( I, }
ldr r0, [r1]& G8 [% W0 e. J G# y6 @% O
dmb
9 }0 g; L: `4 k1 Vldr r2, =0x300
7 E; i; c* V" G' ?2 u- U( jorr r0, r0, r2
3 n2 i( Q1 @8 M4 o' V7 y% T' idmb/ C3 O5 X3 v6 G3 L& I
str r0, [r1]3 \% H4 O( ~0 f6 T }% G, K/ B
7 _- D, F/ M9 L, T) w( |% c' ]+ _ldr r1, =0x11000c08
4 r! Y/ I+ D; m- H! A5 fmov r0, #0
: Z5 ?( W% K# ]9 G' M: Cdmb
7 c4 B" F1 s( g# g f- Jstr r0, [r1]
^/ b9 Y" Q$ o2 i5 n! rreset11: M1 Y* S) @7 w2 ~; W$ ]
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错误。网上有改过的该程序源码,为方便我直接粘贴如下 /* 0 J/ J1 \: g" X
* Copyright (c) 2010 Samsung Electronics Co., Ltd. / V$ C& u; J9 r& A: ]4 ?: Q) _
* http://www.samsung.com/ 3 D" b; o( o3 n9 d6 Q
* ) A- a4 M, E5 e) X6 A
* This program is free software; you can redistribute it and/or modify * D& W1 H* T2 |- L- O% ?" {
* it under the terms of the GNU General Public License version 2 as
% J$ B0 \# u- c& W * published by the Free Software Foundation.
2 ?6 P7 |& Q' u; H3 J */
) G! s1 I Y# {3 N 1 M# E: L. J6 _+ C! r# g
#include <stdio.h>
. \+ M( n- K1 T#include <string.h>
/ b9 S: V7 ~$ W8 {#include <stdlib.h>
5 R% R0 }; }" |3 C' I ( q& z, P/ p+ g3 u
int main (int argc, char *argv[])
5 P9 ?. z6 W$ G# ]' N2 p; ~{
; r3 j* o. u7 S( d- i FILE *fp; ; I. s- R, S8 ?# Z9 X
unsigned char src;
$ H9 y8 R) {/ [. v" { char *Buf, *a;
3 w* [& p5 C# y int BufLen; - B0 k, F" f7 ]( {
int nbytes, fileLen;
- L5 R0 S0 j2 @$ W$ e5 L unsigned int checksum = 0;
' F- J) M: n5 B) P int i;
+ W% t1 V3 l/ l. G' I% E! k8 e; E3 q
& F" P; _/ E* S+ v if (argc != 4) " ]. r5 e5 v+ I. S# g+ V# ]
{
: j# e: S2 e! I' ^1 }9 v1 u# d0 | printf("Usage: mkbl1 <source file> <destination file> <size> \n");
, U0 Q# d* |: r: M) L return -1; ' O j8 t' o+ \2 y5 a& p( o) J
}
. U7 O h6 T" w% x& U( w; a* L& Y1 w 7 Z: C0 v$ s4 @6 N5 B
BufLen = atoi(argv[3]);
/ K6 ^$ y! L. Z( F! j" F: ? Buf = (char *)malloc(BufLen);
+ d! b+ w' h4 t. |, A3 l memset(Buf, 0x00, BufLen); . U' z' l0 O4 k f8 |
) u4 m7 b- j! j# q5 I fp = fopen(argv[1], "rb");
6 k9 E Y# l+ v# n; x Y" }8 K if( fp == NULL)
+ p9 c& q0 D: V d- i {
# R! z) y# K! }; n7 v) { printf("source file open error\n");
' F. z) r. U) O free(Buf); 0 w8 ^# q$ W7 p2 C+ L; e$ e
return -1;
7 X: e$ p3 K Z" E }
/ ]! w; q, t- s! {& i
7 P* X2 p% _( V fseek(fp, 0L, SEEK_END);
8 w$ B' Q5 J: q$ u fileLen = ftell(fp); 3 i- t7 J8 d* y( x2 I
fseek(fp, 0L, SEEK_SET);
1 I. g. _+ v" `+ ~3 w/* 0 p: Q2 f' S& ^6 G, z6 ^
if ( BufLen > fileLen ) 6 c3 j: ?6 l) u2 v
{
+ F8 u# V4 A( P2 N( f) J printf("Usage: unsupported size\n");
* m( x" N% p" p8 V* d free(Buf); 7 `6 Q* o2 M1 i* {0 t; I+ t M
fclose(fp);
7 S9 L6 i) G6 d return -1; % X) r+ J3 H3 Q
}
) X% {( @/ p7 d6 Z* w) e6 ?*/ 6 B# d H% G0 } p: G
//nbytes = fread(Buf, 1, BufLen, fp);
! o6 T- w O+ s) x* I( e3 _ if(BufLen > fileLen)
% x: q% n# E1 b3 v nbytes = fread(Buf, 1, fileLen, fp); & ^4 F; G$ K! L& t0 a
else / @0 N# `5 D; ~4 _; z5 a8 F
nbytes = fread(Buf, 1, BufLen, fp); 5 [8 B7 c, y8 u3 Q' I6 x5 R6 M7 x- r6 G
/*
) j. N4 Y- u& ]" W5 r# \: B. e. ] if ( nbytes != BufLen )
+ n) C' ` E1 Q& L6 A& v1 o+ y7 T {
- n' r* ^1 O4 j& h$ G printf("source file read error\n"); * H/ H |' b; U( b' c: E
free(Buf); $ O+ w/ I G( j, ]
fclose(fp);
- }3 }& Q& D7 v* x1 A- E. s return -1;
. y4 s, o& v( G6 I2 D7 z6 _! j0 H } $ M# K8 H8 M7 o' |7 B
*/ 3 P+ _3 i* ^2 _7 D% v. L4 e7 R
fclose(fp);
' U) O! f1 ?7 M$ h , p/ e6 r5 j( @/ ^
for(i = 0;i < (14 * 1024) - 4;i++) . _2 B( A+ K1 a: V% {9 i/ q
{
4 S: Q5 k" l1 H% ?/ N checksum += (unsigned char)(Buf);
# P3 F6 l8 B4 K. Q3 v1 f% i" Y }
! _" h/ y$ L+ ^ *(unsigned int*)(Buf+i) = checksum;
; h: c( y& r$ ]
8 |- h/ d! _: ?0 J/ | fp = fopen(argv[2], "wb"); ! k2 Q* [( t5 X8 H1 ]8 G
if (fp == NULL)
1 B* c; E+ l3 f {
4 F+ |* a6 r* K# b: x P printf("destination file open error\n"); ) j$ Z' n4 H: C' `1 G
free(Buf);
5 H7 S/ C. V& z& U return -1; ' y( c+ ^7 {( a4 g5 f$ n, |6 D
}
' `+ m) i" s& V; I! U 6 P7 c& n3 ~0 E, Y1 [ }% ?% `
a = Buf; % j ~5 |0 h$ g: M- f; S
nbytes = fwrite( a, 1, BufLen, fp);
1 C1 L' t+ L3 x' P- Z
$ l1 V4 y, I* ?+ D v, D if ( nbytes != BufLen )
$ d& H( o) N- S9 b$ D {
" T2 x- V/ v3 K* T8 h5 v printf("destination file write error\n"); 9 v7 Y1 o9 z4 J+ h m
free(Buf); 3 C8 Z: h. `* U* a
fclose(fp);
# B) Y& Y; ]# N return -1; + ?8 k3 |( S% w
}
4 {6 A/ b7 `" S9 D# q6 ~. S3 G! h
. j' x k1 z$ U+ P3 |, p" P; m free(Buf); 1 P) o& ^$ T+ c/ p, `( B
fclose(fp);
9 C" |: C- _) M9 d: U( x
! f5 Y. b X( q' K return 0;
) d8 o0 u1 F$ E$ I# u} 读者可用此源码本地编译生成可用的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/sh7 f7 q/ G n# H5 _9 z! r
cat E4412_N.bl1.bin bl2.bin all00_padding.bin > u-boot-iTOP-4412.bin
9 h' M% v/ D+ [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 l% j0 r4 X5 l/ B2 l" z7 P4 [% I
* K" Z0 m2 r* [1 ?( w3 c% I E
* @; J: |; X* HDisassembly of section .data:: c% m; l; i; l0 Y8 e8 S1 J
( v9 e* j& ]: n& o. C
00000000 <.data>:
0 H$ e- ?. t8 `7 Y& E 0: ea000006 b 0x20
5 S8 T5 b7 u% z7 ^+ N' u) @% m+ L% d 4: eafffffe b 0x4! S, ^; \# Y/ S+ ^
8: eafffffe b 0x8# [7 h& c9 F, k* I) g- H1 V, g3 i
c: eafffffe b 0xc5 o' U7 [9 ~: a- G8 D# {! V' D0 v
10: eafffffe b 0x10
1 I- i. U* g' L" D6 C) v% p T 14: eafffffe b 0x14
% n1 W: d/ D9 }! g& g% f 18: ea00301a b 0xc088
2 B1 E X% V9 n: e7 C' M 1c: ea00301b b 0xc090 c6 v$ D; e1 G8 V: b
20: e59f01a4 ldr r0,[pc, #420] ; 0x1cc
]1 N2 ^( x6 D6 S+ ]$ V8 o; |6 g 24: e3a01000 mov r1,#0- h! T( L( y" z
28: e5801000 str r1,[r0]
( n8 p2 L# _6 u$ U5 g- y& e9 T 2c: e59f019c ldr r0,[pc, #412] ; 0x1d08 a4 y9 z3 S5 G. r
30: e5900000 ldr r0,[r0]
, a- l' Y/ D q. Z) { Y% B 34: e200003e and r0,r0, #62 ; 0x3e% {% L6 A( t) e( v, ~
38: e330003e teq r0,#62 ; 0x3e
}8 z8 O2 r; t" ^! i7 P 3c: 1a00000d bne 0x78
1 H3 n4 u T$ B! A+ r 40: e59f018c ldr r0,[pc, #396] ; 0x1d4
( r# }3 [4 z' c6 d9 r* U4 |5 \ 44: e5900000 ldr r0,[r0]+ N4 S" Z, x. A6 K5 A) \1 J3 |
48: e3100001 tst r0,#1! Z* ~' G) z0 U" V
4c: 1a000009 bne 0x789 u) i9 Y' b/ B4 T$ j5 y7 Y
50: e59f2180 ldr r2,[pc, #384] ; 0x1d8
; q1 j' e; V, P+ ~ 54: e5922000 ldr r2,[r2]
! F( m+ R) S- F. [/ Q/ E 58: e3e03000 mvn r3,#0; C! Y1 J6 [$ L0 I2 ]0 t
5c: e1120003 tst r2,r3
( A# C3 x: I" S7 ]) o+ x6 E" U2 v 60: 1a000003 bne 0x74
( `$ s# J- Q4 T5 v2 G) N6 s4 r 64: e59f0170 ldr r0,[pc, #368] ; 0x1dc
# x( Z4 n+ }' R2 e 68: e59f1170 ldr r1,[pc, #368] ; 0x1e0
^- o& o' M R2 T 6c: e5801000 str r1,[r0]3 t7 M" H, G+ _* y/ f3 L2 V( ]$ k
70: e59f2164 ldr r2,[pc, #356] ; 0x1dc
6 X4 u) s+ }5 {" x, P$ e 74: e1a0f002 mov pc,r2
3 K4 s. k, H9 ^; v( w 78: e321f0d3 msr CPSR_c,#211 ; 0xd3/ M! A% ^, H" `: K" T4 R; H0 T! Y
7c: ee110f10 mrc 15,0, r0, cr1, cr0, {0}3 |9 S6 K% \- F7 H
80: e3c00001 bic r0,r0, #19 \* y. G# E. Y0 ^, `- I
84: e3c00004 bic r0,r0, #4
5 Z- @; ^: a# w; I2 C2 ]1 R 88: e3a02281 mov r2,#268435464 ; 0x10000008& {- v [; E. ]7 y4 x
8c: e5923000 ldr r3,[r2]- ^' q4 ?" e) |( m# p
90: e3130501 tst r3,#4194304 ; 0x4000004 i% Q' A' }8 t/ v
94: 0a000002 beq 0xa4
) }# t0 o" v/ z. U9 Q 98: e3c00a01 bic r0,r0, #4096 ; 0x1000
2 k/ M9 x% f) f4 a8 ]9 ~2 C 9c: ee010f10 mcr 15,0, r0, cr1, cr0, {0}/ b, i1 e' _) y+ @, i) a
a0: ea000006 b 0xc0! A, g% o8 y# L9 f0 |+ a
a4: e3a00000 mov r0,#0
% A* a5 @$ X: N2 G1 n a8: ee080f17 mcr 15,0, r0, cr8, cr7, {0}% e! p" D1 w* h; m* M7 i u
ac: ee070f15 mcr 15,0, r0, cr7, cr5, {0}/ t5 A/ t. x& W' W
b0: eb0022ea bl 0x8c609 Z( s. Y- i- ?2 o
b4: ee110f10 mrc 15,0, r0, cr1, cr0, {0}& D4 d2 s" [2 G$ `0 l9 z) R+ o
b8: e3800a01 orr r0,r0, #4096 ; 0x1000* e6 s5 _% r% x0 c8 Q, Q% A
bc: ee010f10 mcr 15,0, r0, cr1, cr0, {0}+ p5 o8 r9 y# F6 n
c0: ee10cfb0 mrc 15,0, ip, cr0, cr0, {5}
?2 ?" e* o0 l# Z! q c4: e20cc003 and ip,ip, #32 _% L, j, i! j( k4 g
c8: e59f2114 ldr r2,[pc, #276] ; 0x1e4+ M" ] _! Q' S5 m! i
cc: e082010c add r0,r2, ip, lsl #2' s5 S3 h0 H! G# Q2 r5 Z
d0: e35c0000 cmp ip,#05 F2 ]: r2 l8 T1 ^3 r/ h
d4: 1a0022da bne 0x8c44
/ w( q, _# E+ @. D d8: e59f0108 ldr r0,[pc, #264] ; 0x1e80 [. V0 f) G/ Z& s; i: g
dc: e5900000 ldr r0,[r0]( O/ ?' ?" U9 F l9 c
e0: e3a01102 mov r1,#-2147483648 ; 0x80000000# d0 Z% b1 _2 O+ H
e4: e1100001 tst r0,r1
! a1 d: j ^! ], i- z% q e8: 0a000024 beq 0x180- |' G' C& u$ [$ b) \# V
ec: e59f00f8 ldr r0,[pc, #248] ; 0x1ec ~) O5 |2 z: z0 p
f0: e5900000 ldr r0,[r0]' c. n. {/ W. Y3 j) K# G
f4: e3100001 tst r0,#1
* o) p0 L9 o, D: u f8: 0a000020 beq 0x180
, {# L4 _4 Z. L# M; A2 U; t: c fc: e59f00ec ldr r0,[pc, #236] ; 0x1f0* n9 P; s! V* k8 E2 n! b
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 $ l) K& x) \4 [& s
|