Ejtag详解 独家公布调试秘籍

朱杏 发布于 2012/08/15 10:53
阅读 2K+
收藏 0

ejtag是mips的onchip debug调试标准。现在龙芯1号和龙芯3号系列都支持ejtag调试。在本次“龙芯杯”全国开源软件设计大赛中,多道选题都涉及到ejtag方面的问题。到底ejtag的原理是什么? 如何通过ejtag快速简化软件方面的调试?为了给正在研发阶段的选手们一些参考,本人千辛万苦搜罗到了这方面的专家——龙芯中科的乔崇博士对ejtag分析的一篇文章。特别是独家公布乔博士编写的ejtag调试调试工具。它支持读写寄存器、内存、反汇编、执行用户编写的小程序、gdb远程调试和脚本语言。希望对选手们有所帮助!

 

mips ejtag原理和实现

June 21, 2012

 

Contents

1 ejtag基础:jtag 1

1.1 jtag信号. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

1.2 jtag. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

1.3 jtag. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

1.4 jtag的寄存器. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

2 ejtag-debug的架构4

2.1 运行方法. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

2.2 ejtag-debug参数. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

2.3 ejtag-debug里面的目录结. . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2.4 ejtag-debug的命令. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2.4.1 callbin实现. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

2.5 ejtag-debug的脚本. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

2.5.1 source命令. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

2.5.2 外部perl脚本. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

2.6 ejtaggdb . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

2.6.1 gdb remote协议. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

2.6.2 gdbserver实现. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

2.6.3 gdbserver的使用. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

3 ejtag硬件11

3.1 并口电缆. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

3.2 usb电缆. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

3.2.1 windows下安装. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

3.2.2 Linux下安装. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

1

CONTENTS 2

Abstract

ejtagmipsonchip debug调试标1号和3号系列都支持ejtag调试。通ejtag可以

大大方便调试,讲讲ejtag原理和ejtag-debug件。

ejtag-debug是我写的一个ejtag调试调试工具,支持写寄存器、内存、反汇编行用户编写的小程

序、gdb调试和脚本言。

1

1 ejtag基础:jtag

ejtagjtag:

ejtag利用了jtag pin,jtag tap机器,访问jtag寄存器。通jtag寄存器来控制理器ejtag

常,在异常里面访问dmseg(0xff2000000-0xff2fffff0)实现pc主机行交互。一章的内容是jtag

信号、状机和寄存器。1

1.1 jtag信号

Figure 1: ejtag

Figure 2: ejtag座信号定

1jtag参考ieee1149.1,ejtag参考MD00047-2B-EJTAG-SPC-03.10.pdf

1.2 jtag2

TRST test reset 位任

TDI test data in 串行入到cpu

TDO test data out cpu串行

TCLK test clock 时钟

TMS test mode select 机控制

tclk的上升沿采集tms,tdi,tdo的信号。

1.2 jtag链互联

Figure 3: jtag chain

当有多个设备jtag接起来的候,将设备tdo接接到另一个设备tdi上,成一个jtag

接。

tms,tclk,trst信号是直接设备上的。

1.3 jtag3

1.3 jtag状态机

Figure 4: ejtag

上面的两个形象的画出ejtag tap controller工作的程,一个是移位,另一个是ir,dr寄存器。通

ir访问dr,就实现访问ir指向的寄存器。ejtag ir5位,dr32-64位。

Figure 5: jtag

jtagir,dr寄存器,访问jtag/ejtag的寄存器。

1.4 jtag的寄存器4

1.4 jtag的寄存器

ejtag展了jtag寄存器,如增加了address,data,control寄存器等。要实现ejtag调试主要是反复访

问这3个寄存器。

Table 1: Table 6-1 TAP Instruction Overview

Code Instruction Function

All 0s (Free for other use) Free for other use, such as JTAG boundary scan

0x01 IDCODE Selects Device Identi?cation (ID) register

0x02 (Free for other use) Free for other use, such as JTAG boundary scan

0x03 IMPCODE Selects Implementation register

0x04 - 0x07 (Free for other use) Free for other use, such as JTAG boundary scan

0x08 ADDRESS Selects Address register

0x09 DATA Selects Data register

0x0A CONTROL Selects EJTAG Control register

0x0B ALL Selects the Address, Data and EJTAG Control registers

0x0C EJTAGBOOT Makes the processor take a debug exception after reset

0x0D NORMALBOOT Makes the processor execute the reset handler after reset

0x0E FASTDATA Selects the Data and Fastdata registers

0x0F (EJTAG reserved) Reserved for future EJTAG use

0x10 TCBCONTROLA Selects the control register TCBTraceControl in the Trace

Control Block

0x11 TCBCONTROLB Selects another trace control block register,Used to access

the registers specified by the TCBCONTROLBREG field

0x12 TCBDATA and transfers data between the TAP and the TCB control

register

0x13 TCBCONTROLC Selects another trace control block register

0x14 PCSAMPLE Selects the PCsample register

0x15 - 0x1B (EJTAG reserved) Reserved for future EJTAG use

0x1C - All 1s (Free for other use) Free for other use, such as JTAG boundary scan

All 1s BYPASS Select Bypass register

2 ejtag-debug的架构

由很多小命令成,支持脚本言。

2.1 运行方法

需要超级用户权限

sudo ./ejtag_debug_usb

配置文件是ejtag.cfg

程序会自动打开./ejtag.cfg并执行里面的内容。

2.2 ejtag-debug参数

./ejtag_debug_usb [-dlStch] [-e cmd] [-T n]

-d: verbose on,show debug messags

-e 'cmd': run cmd

-l: do not use read line

-S: log disassemble info

-s: run cmdserver

-t: disable timer

-T n: set timer n ms

-c: do not load cfg file

-h: show this help

2.3 ejtag-debug里面的目录结5

2.3 ejtag-debug里面的目录结构

Table 2: ejtag-debug里的目录结

/文件名型功能

ejtag_debug_usb.exe 文件usb ejtag的可行文件

ejtag_debug_pp.exe 文件并口ejtag的可行文件

ejtag.cfg 文件ejtag的配置文件,可行行文件启动时候会先个文件里面的内容

ejtag.rc 文件在ejtag命令行上的命令被保存在ejtag.rc

Makefile,example.c,ejtag.a,include,mycc,mycpp 文件ejtag 支持二次开发example.c是一个事例程序

ddr.txt 文件1bddr参数文件

mipsel-gdb 文件mips gdb, gdb命令需要用到个文件

scripts 命令里面用到的脚本

configs ddr初始化和flash写脚本

bin bin文件开发环境,可以通callbin

logic 最新版本逻辑编程文件

driver windows下的驱动文件

2.4 ejtag-debug的命令

ejtag-debug由很多小命令成,支持名字自动补齐。在行首加#表示注

h [cmd] 看帮助

setconfig [configname] [value]

重要的:

helpaddr: 帮助地址,帮助程序行的地址,地址应该指向ddr,cache/uncache都可以put,get,callbin,call

等命令会将帮助程序先上helpaddr上,然后helpaddr

usb_ejtag.put_speed: usb速度,16bit,越大越慢

putelf.uncached: putelfuncached,1put前刷cache,2不刷cache.

core.cpucount : cpu数目

core.cpuno : 置当前调试cpu

core.cpuwidth : cpu的数据

display.cmd : ejtag态变候运行命令,如断点jtag.showins : jtag态变

示指令。有很到配置用setconfig命令可以列出来

set [regnamejregno] [value] 写寄存器

1 set 出所有寄存器

2 set pc pc

3 set at at

4 set pc 0xffffffffbfc00000

5 #pc的数0xffffffffbfc00000

setenv [envname] [value]

ejtag向内核量是通ENV_开头量来置的,如:

setenv ENV_memsize 256

setenv ENV_highmemsize 0

setenv ENV_cpuclock 266000000

置内核内存大小和cpu时钟

d1-d8,d1q-d8q,m1-m8 1-8dump/modify的意思,实现候是函数指,具体功能有先选择

内存。相的命令有mems,cp0s,regs,jtagregs,spiroms

mems:select access mem

cp0s:select access cp0

cp0_config1:

1 cp0s 1

2 d8 16 1

2.4 ejtag-debug的命令6

也可以这样

1 cp0s 1 d8 16 1

source file file中的命令,如果命令返回错误停止行后面的命令

Source filesourcefork一个程来

loop count cmd args.. 环执countcmd args...

echo args 打印args

echo_on 行的命令

echo_off 不回显执行的命令

verbose [onjoffj&fdno|filename] 关闭debug调试,或存到fd中。

下面命令实现打印出ejtag行的汇编

1 timer 0

2 verbose on

3 setconfig log.level 15

4 setconfug log.disas 1

waitreg reg data 等待ejtag regdata

waitfacc [startaddr] [endaddr] 等代cpu访问dmseg且地址在startaddr-endaddr或者0xff200200

goback [addr] 跳到dmseg addr

run binfile 运行bin文件,如run gzrom.bin

msleep n 等待n ms

shell cmd shell命令,或者用脚本程序

timer n nms检查一次ejtag,n==0候不检查

b addr,件断点,在addr上插入sdbbp

unb addr 件断点,原来的指令

hb addr [ibm] 在硬件断点,ibm1的位不比地址

1 hb 0xbfc00000 0x7ffff #程序行到0xbfc00000 0xbfc7ffff都会生硬件断点

unhb addr 除硬件断点

hbls 列出硬件指令断点

watchls 列出硬件数据断点

s单步执

uns取消单步执

cont 退出ejtag模式,继续执

cpu cpuno cpucpuno

map filemame start [size] 映射文件到dmseg start大小size

unmap filemame start [size] 取消映射文件到dmseg start大小sizedmseg内容写代文件中

memsetx/fmemsetx/smemsetx addr value size 理器上运行memset,其中x1,2,41写,2

双字写,44写。

memcpy/fmemcpy/smemcpy saddr dassr size 理器上运行memcpy

put/fput/sput file address ,文件到板子上,的配置usb_ejtag.put_speed,put.pack_size,put.md5sum

2.4 ejtag-debug的命令7

get/fget/sget filename address size,从板子上下文件,配置get.pack_size

putelf/fputelf/sputelf elffile, elf文件

initrd initrdfile ,initrd

karg "kernel args" ,置内存参数

disas address [count] ,汇编

callbin/fcallbin/scallbin binfile [arg0 arg1 ...],bin文件

call/fcall/scall address [arg0 arg1 ...],用函数

erase 擦除整个flash芯片

erase_area start end sectorsize 檫除部分flash芯片

program ramaddr flashaddr size flash

些命令用来flash,使用方法如下:(以后准callbin直接c言来flash)

1 setconfig flash.type st25vf080

2 erase_area 0 0x7ffff 0x10000

3 program 0x81000000 0 0x70000

server [port] 命令server,另外一个ejtag-debug程序可以通络发命令,端口

8880

shell program [args] 命令server,运行shell命令program

gdbserver [port] gdbserver,可以gdb remote调试,端口50010

gdb elffile 一个命令运行perl scripts/ gdb.pl,实现后台启gdbserver,前台运行gdb调试

elffile

expr [expressionj#regname]

expr命令简单+-*/n转换,从左向右算,支持括号.

expr寄存器内容,主要了方便调试用的

翻引号里的内容会传给expr,并用果替代,如

disas `pc` 10 #汇编pc10条指令

newcmd cmdname oldcmd note,增加一个新的命令

cache op addr size cache opaddraddr+size

cacheflush addr size cache使得内存和cache一致,根据cache配置刷icachedcache或者二

cache

cache_config perl脚本cpupridconfig寄存器来cache参数,cachecacheflush会用到

些参数

selectcore coreno 3b选择调试cpu,0xf8cpu串起来

2.4.1 callbin的实现

callbin用的bin文件是pic位置无,通got行重定位。c言的入口函数是mymaincallbin

的参数直接作mymain的参数。如果参数是字符串callbin会将字符串地址拷到内存里面,并将内存地

址作参数。callbin中包含叫做tinycc,实现printf,内存,字符串操作等。

实现memsetbin程序test.c

1 int mymain(char *buf,int len)

2 {

3 printf("this is a test\n");

4 memset(buf,c,len);

5 return 0;

6 }

编译:

2.5 ejtag-debug的脚本8

1 make CROSS_COMPILE=mipsel��linux�� test.bin

:

1 callbin bin/test.bin 0xa0000000 0x12

打印是通ejtag打印到pc机端,如果要打印到串口,可以定putchar函数:

实现memsetbin程序test.c

1 int putchar(c)

2 {

3 *(volatile char *)0xb4000000=c;

4 }

5 int mymain(char *buf,int len)

6 {

7 printf("this is a test\n");

8 memset(buf,c,len);

9 return 0;

10 }

callbin的从定位和clear bssstart.Sstart64.S中做的。got section存的是函数的地址,要用当前的

实际地址修正函数的地址和gp,然后才能正确行。编译候的起始地址是0,运行的候的起始

地址是helpaddrcallbin位于lib/callbin.c中。

2.5 ejtag-debug的脚本语言

2.5.1 source命令

ejtag-debugsource fileSource file命令可以file文件里面的命令依次.

loop命令可以实现简单的固定循

expr命令可以作简单计算和寄存器参数

1 d4 0xbfc00000+0x10 10

2 loop 10 d4 0xbfc00000 10

2.5.2 外部perl脚本

本来想在内部直接集成一脚本言,如awk,但后来发现。因此采用了shell命令方法来实现

言。跟busybox原理差不多. ejtag-debug候要打开设备作初始化,如果行一个命

开关闭一遍设备会性能很差。里采用server,clint的方法来解决。要行脚本言前server,

端口8880来接收命令。在另一个端象这样运行

1 ejtag��debug set

telnet 8880入命令,打印出也重定向到网。上面的程可以化成1shell命令

1 shell ejtag��debug set

2 shell perl scipts/test.pl

perl脚本分析

scripts/io.pm是将命令封装成perl的函数

inb就是d1q

outb就是m1

inb/inh/inw/inq

outb/outh/outw/outq

do_cmd行命令,直接出到

2.6 ejtaggdb 9

do_cmd1行命令,果返回

要写一个perl脚本test.pl访问ejtag,只要写一个perl程序,前面包含

1 #!/usr/bin/perl

2 use bignum;

3 push @INC,qq(./scripts);

4 require qq(io.pm);

后面就可以inb/outb/do_cmd等函数访问ejtag了。用的候,运行:

1 shell perl scipts/test.pl

test.pl

1 #!/usr/bin/perl

2 use bignum;

3 push @INC,qq(./scripts);

4 require qq(io.pm);

5 outb(0xffffffffbfe001e3,0x80);

6 outb(0xffffffffbfe001e0,0xd);

7 outb(0xffffffffbfe001e3,0x3);

8 printf "value is %x",inb(0xffffffffbfe001e3);

9 do_cmd("cont");

2.6 ejtaggdb

实现gdb利用ejtag调试程序,ejtag-debug中增加了gdbserver命令,可以直接gdb

令,内部gdbserver

2.6.1 gdb remote协议

运行info gdb命令可以到相信的gdb remote准。

1 * Remote Protocol:: GDB Remote Serial Protocol

2 * Packets:

运行gdb调试候,可以打remote调试功能,能打印出remote packet的内容

1 gdb) set debug remote ��1

2.6.2 gdbserver的实现

• 打tcp端口50010,置成非阻塞方式,等待端口上的数据

• 解析packet,根据packet内容行内存写,置断点等

查询ejtag,从正常状态进ejtag送信号gdb

2.6.3 gdbserver的使用

运行gdb命令:

1 cpu0 ��gdb /mnt/sdd3/work/3afirewall/linux��loongson��release/vmlinux

2 + EJTAGEXE=/mnt/sdd2/work/bioscfg/ejtag_debug_pp

3 ++ /mnt/sdd2/work/bioscfg/ejtag_debug_pp setconfig core.abisize

4 + abisize=00000040

5 + /mnt/sdd2/work/bioscfg/ejtag_debug_pp gdbserver 50010 1

6 ++ mktemp /tmp/gdbXXX

7 + tmpfile=/tmp/gdbDeq

8 + '[' 00000040 = 00000040 ']'

9 + echo 'set mips abi n64 '

10 + echo 'target remote :50010'

11 + mipsel��gdb ��q ��x /tmp/gdbDeq /mnt/sdd3/work/3afirewall/linux��loongson��release/vmlinux

12 (no debugging symbols found)

2.6 ejtaggdb 10

13 [New Thread 1]

14 0xffffffff802053d4 in cpu_idle ()

15 (gdb) info threads

16 [New Thread 2]

17 [New Thread 3]

18 [New Thread 4]

19 4 Thread 4 0xffffffff80205414 in cpu_idle ()

20 3 Thread 3 0xffffffff802053d4 in cpu_idle ()

21 2 Thread 2 0xffffffff80205414 in cpu_idle ()

22 * 1 Thread 1 0xffffffff802053d4 in cpu_idle ()

• 可以利用gdbmonitor命令从gdb端在ejtag-debug行命令

1 gdb)monitor setconfig

2 gdb)monitor d1 0xffffffffbfc00000 10

理器是一个线程,info threads列出理器信息

detach gdb remote

• 目前于多cpugdb候只停止当前的cpu,info threads会停止所有的cpu

b,hb,watch,rwatch,awatch置断点

11

3 ejtag硬件

3.1 并口电缆

访问并口可以直接pcio地址,或者打并口/dev/parport0,ioctl访问端口。

并口的pin2-pin9对应数据0-7,作为输出,11,13,15可以作为输入。

两个config和并口配置有关:

pp.pins : 0x00421730:pp pins {23..0}={rst,tclk,tms,tdo,tdi,trst}: 0x401763,

0x421730

pp.ppdev : 0x00000000:pp use /dev/parport0

3.2 usb电缆

usb电缆包括:ezusb芯片,FPGA

FPGA内部有一个mips理器和一个完成一次ejtag寄存器访问的状,一个使用4096fifo.

mips理器是李写的mips789 http://opencores.org/project,mips789

usb采用bulk传输

• 除了实现对ejtagtap寄存器访问外,还对和下作了特,速度可以达到1MB/s

3.2.1 windows下安装

ejtagwindows下使用需要安装驱动,如果windows下没有安装驱动执ejtag_debug_usb.exe

提示缺少libusb,或者找不到设备驱动按照程如下:

1. 首先将usb电缆插入pc机的usb口,windows检测出未知的usb设备插入提示按照驱动

2. 选择安装,并指定安装目录为ejtag-debug/driver,然后下一来自安装驱动

3. 可以在设备管理器里面找未安装驱动usb设备vid: 2961,pid: 6688,然后指定按照

ejtag-debug/driver里面的驱动即可。

驱动安装完后,直接双ejtag_debug_usb.exe行就可以了。

ejtag程序的一些命令会到脚本,需要安装perl。可以下active perl或者strawberry perl都可

http://www.perl.org/get.html#win32.

• 如果在cygwin行,需要将ejtag-debug里面的cygwin1.dll除,否程序会自退出去。

3.2.2 Linux下安装

linux下不需要安装驱动,直接以超户权ejtag_debug_usb.exe即可。

 

加载中
0
1
1987my
不错的东东,感谢分享!
0
z
zynwxn
顶一个~
0
x
xiaoguaiguai

有些地方不太了解,楼主能否留下在线联系方式.

0
a
aideliwu
支持一下
0
w
wanzjh
对于俺们这种菜鸟来说,,有点深奥啊
返回顶部
顶部