本文转自: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:

/* Allow the board to save important registers */

/*b save_boot_params*/

ldr r1, =0x1002330c

ldr r0, [r1]

dmb

ldr r2, =0x300

orr r0, r0, r2

dmb

str r0, [r1]

ldr r1, =0x11000c08

mov r0, #0

dmb

str r0, [r1]

reset11:

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错误。网上有改过的该程序源码,为方便我直接粘贴如下

/*

* Copyright (c) 2010 Samsung Electronics Co., Ltd.

* http://www.samsung.com/

*

* This program is free software; you can redistribute it and/or modify

* it under the terms of the GNU General Public License version 2 as

* published by the Free Software Foundation.

*/

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

int main (int argc, char *argv[])

{

FILE *fp;

unsigned char src;

char *Buf, *a;

int BufLen;

int nbytes, fileLen;

unsigned int checksum = 0;

int i;

if (argc != 4)

{

printf("Usage: mkbl1 <source file> <destination file> <size> \n");

return -1;

}

BufLen = atoi(argv[3]);

Buf = (char *)malloc(BufLen);

memset(Buf, 0x00, BufLen);

fp = fopen(argv[1], "rb");

if( fp == NULL)

{

printf("source file open error\n");

free(Buf);

return -1;

}

fseek(fp, 0L, SEEK_END);

fileLen = ftell(fp);

fseek(fp, 0L, SEEK_SET);

/*

if ( BufLen > fileLen )

{

printf("Usage: unsupported size\n");

free(Buf);

fclose(fp);

return -1;

}

*/

//nbytes = fread(Buf, 1, BufLen, fp);

if(BufLen > fileLen)

nbytes = fread(Buf, 1, fileLen, fp);

else

nbytes = fread(Buf, 1, BufLen, fp);

/*

if ( nbytes != BufLen )

{

printf("source file read error\n");

free(Buf);

fclose(fp);

return -1;

}

*/

fclose(fp);

for(i = 0;i < (14 * 1024) - 4;i++)

{

checksum += (unsigned char)(Buf[i]);

}

*(unsigned int*)(Buf+i) = checksum;

fp = fopen(argv[2], "wb");

if (fp == NULL)

{

printf("destination file open error\n");

free(Buf);

return -1;

}

a = Buf;

nbytes = fwrite( a, 1, BufLen, fp);

if ( nbytes != BufLen )

{

printf("destination file write error\n");

free(Buf);

fclose(fp);

return -1;

}

free(Buf);

fclose(fp);

return 0;

}

读者可用此源码本地编译生成可用的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/sh

cat E4412_N.bl1.bin bl2.bin all00_padding.bin > u-boot-iTOP-4412.bin

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

Disassembly of section .data:

00000000 <.data>:

0: ea000006 b 0x20

4: eafffffe b 0x4

8: eafffffe b 0x8

c: eafffffe b 0xc

10: eafffffe b 0x10

14: eafffffe b 0x14

18: ea00301a b 0xc088

1c: ea00301b b 0xc090

20: e59f01a4 ldr r0,[pc, #420] ; 0x1cc

24: e3a01000 mov r1,#0

28: e5801000 str r1,[r0]

2c: e59f019c ldr r0,[pc, #412] ; 0x1d0

30: e5900000 ldr r0,[r0]

34: e200003e and r0,r0, #62 ; 0x3e

38: e330003e teq r0,#62 ; 0x3e

3c: 1a00000d bne 0x78

40: e59f018c ldr r0,[pc, #396] ; 0x1d4

44: e5900000 ldr r0,[r0]

48: e3100001 tst r0,#1

4c: 1a000009 bne 0x78

50: e59f2180 ldr r2,[pc, #384] ; 0x1d8

54: e5922000 ldr r2,[r2]

58: e3e03000 mvn r3,#0

5c: e1120003 tst r2,r3

60: 1a000003 bne 0x74

64: e59f0170 ldr r0,[pc, #368] ; 0x1dc

68: e59f1170 ldr r1,[pc, #368] ; 0x1e0

6c: e5801000 str r1,[r0]

70: e59f2164 ldr r2,[pc, #356] ; 0x1dc

74: e1a0f002 mov pc,r2

78: e321f0d3 msr CPSR_c,#211 ; 0xd3

7c: ee110f10 mrc 15,0, r0, cr1, cr0, {0}

80: e3c00001 bic r0,r0, #1

84: e3c00004 bic r0,r0, #4

88: e3a02281 mov r2,#268435464 ; 0x10000008

8c: e5923000 ldr r3,[r2]

90: e3130501 tst r3,#4194304 ; 0x400000

94: 0a000002 beq 0xa4

98: e3c00a01 bic r0,r0, #4096 ; 0x1000

9c: ee010f10 mcr 15,0, r0, cr1, cr0, {0}

a0: ea000006 b 0xc0

a4: e3a00000 mov r0,#0

a8: ee080f17 mcr 15,0, r0, cr8, cr7, {0}

ac: ee070f15 mcr 15,0, r0, cr7, cr5, {0}

b0: eb0022ea bl 0x8c60

b4: ee110f10 mrc 15,0, r0, cr1, cr0, {0}

b8: e3800a01 orr r0,r0, #4096 ; 0x1000

bc: ee010f10 mcr 15,0, r0, cr1, cr0, {0}

c0: ee10cfb0 mrc 15,0, ip, cr0, cr0, {5}

c4: e20cc003 and ip,ip, #3

c8: e59f2114 ldr r2,[pc, #276] ; 0x1e4

cc: e082010c add r0,r2, ip, lsl #2

d0: e35c0000 cmp ip,#0

d4: 1a0022da bne 0x8c44

d8: e59f0108 ldr r0,[pc, #264] ; 0x1e8

dc: e5900000 ldr r0,[r0]

e0: e3a01102 mov r1,#-2147483648 ; 0x80000000

e4: e1100001 tst r0,r1

e8: 0a000024 beq 0x180

ec: e59f00f8 ldr r0,[pc, #248] ; 0x1ec

f0: e5900000 ldr r0,[r0]

f4: e3100001 tst r0,#1

f8: 0a000020 beq 0x180

fc: e59f00ec ldr r0,[pc, #236] ; 0x1f0

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

开发板了解:

http://topeetboard.com/Product/iTOP4412-ss.html

【转载分享】 JLINKv9在迅为iTOP-4412精英板上的应用的更多相关文章

  1. 转载分享----一线交付眼中的为何"项目总是迟迟无法交付”

    当初博主在一线交付BOSS系统中承担过TC角色 交付的路途很艰辛,加班到10点多或1点多第二天8点上班,还有通宵的日子 还有无数个问题从开始到关闭的周期,各种催人,各种掐架拉会,各种被甲方嫌弃 看到这 ...

  2. 迅为4412开发板支持AVIN视频输入/AV监控摄像头输入模块

    AVIN模块(iTOP-4412开发板专用) 产品介绍:视频输入/AV监控摄像头输入模块: 该模块及配套的软件为开发视频采集.监控.车载后视等产品提供了很好的参考. iTOP-4412 开发平台 开发 ...

  3. 迅为4412开发板QtE系统源码-屏幕横竖屏切换修改方法

    迅为4412开发板QtE系统源码-屏幕横竖屏切换修改方法 详情了解:http://topeetboard.com 更多了解:https://arm-board.taobao.com/ 用户在开发板上运 ...

  4. ARM核心板_迅为4412核心板_核心板中的小新潮

    iTOP-4412核心板是迅为电子推出的一款高端四核核心板,配备三星Exynos 4412四核处理器,主频为1.4GHz,内置8GB存储空间. 该板设计小巧.配备三星自家电源管理芯片,具有9路DC/D ...

  5. 【转载】4412开发板嵌入式QtE应用开发环境搭建

    本文转自迅为iTOP-4412开发板实战教程书籍:http://topeetboard.com QtE应用需要使用开发工具qtcreator,本文介绍qtcreator-3.2.2的安装和使用.1. ...

  6. 迅为三星Exynos 4412开发板四核Cortex-A9ARM安卓linux开发板

    开发板光盘资料包含:原理图(PDF格式).底板PCB(Allegro格式).驱动程序源码.芯片和LCD数据手册.开发环境.产品使用手册. 4412开发板简介: iTOP-Exynos4412开发板采用 ...

  7. 【分享】4412开发板POP烧写ubuntu出错,如何挂载emmc分区解决方法

    本文转自:http://bbs.topeetboard.com 平台:4412精英版系统:ubuntu系统 按照教程烧写ubuntu文件系统,TF卡和EMMC分区都完成(总之之前的操作试了几遍都是没问 ...

  8. 【转帖】嵌入式4412开发板QT5.7编译安装到arm

    QT5.7.0+UBUNTU16.04+ARM-NONE-LINUX-GNUEABI4.8+busybox最小LINUX系统 Orandragon记录 本文转自迅为4412开发板群:http://to ...

  9. 【开学季】自学嵌入式开发|四核开发板|4412开发板|ARM+Android+linux技术

    淘宝店铺:迅为开发板http://arm-board.taobao.com 网站:http://www.topeetboard.com QQ咨询:2551456065 电话咨询:010-5895758 ...

随机推荐

  1. echarts图Y周坐标轴文字过长的解决方案

    解决方案  只贴出关键代码 在翻看echarts文档的过程中我看到了坐标轴文字可以自行定义模板,于是想到了我给一个固定12的字数限制,超出部分以省略号代替,这样就不会造成图形范围忽大忽小了. axis ...

  2. nginx搭建分布式简单配置

    1.下载安装nginx 2.编辑nginx.conf文件 upstream 172.100.10.52 { ip_hash; #保证每一个用户访问同一个网站 server 172.100.10.21: ...

  3. php mkdir No such file or director问题

    有时使用mkdir创建目录时会出现 No such file or director这样的错误,导致这个错误的原是 比如你要创建目录 a\b\c目录,但是创建时父目录b也不存在时就会出现这样的问题. ...

  4. linux之/proc

    /proc是Linux或UNIX中的一种伪文件系统机制,提供了访问内核运行结构.改变内核设置的实时数据. 与ext4.NFS.FAT32等文件系统不同,/proc中的数据存放在内存而不是硬盘上. 在/ ...

  5. Go语言反射规则

    Go语言反射规则 - The Laws of Reflection 转:http://my.oschina.net/qbit/blog/213720 原文地址:http://blog.golang.o ...

  6. layui获取子集表单中的值,关闭父级弹窗

    js代码 var GetParams = function(url,bool) { try { if(bool){ var index = url.indexOf('?'); url = url.ma ...

  7. css+div基本知识;

    1.居中: <div class="test"></div> css: .test{ margin: auto; //一行中居中: } 2.IE与其他浏览器 ...

  8. Centos 6.8编译安装LNMP环境

    Centos 6.8编译安装LNMP环境 参考资料: http://www.jb51.net/article/107429.htm https://phperzh.com/articles/1360 ...

  9. 2017-12-18python全栈9期第三天第四节之str的索引与切片

    #!/user/bin/python# -*- coding:utf-8 -*-s = 'zdlswwzl's1 = s[0]print(s1)s2 = s[-1]print(s2)s3 = s[0: ...

  10. spring集成Hessian的基本使用方法

    一.什么是RPC RPC全称Remote Procedure Call,中文名叫远程过程调用.RPC是一种远程调用技术,用于不同系统之间的远程相互调用.其在分布式系统中应用十分广泛. 二.什么是Hes ...