天天看点

Skyeye的安装与使用

1)下载必要的软件,我是在VMWare上建的环境,需要准备好下面这些软件

ARM-Linux的交叉平台编译工具arm-elf-tools

<a href="http://www.uclinux.org/pub/uClinux/arm-elf-tools/">http://www.uclinux.org/pub/uClinux/arm-elf-tools/</a>

里面都是rpm包,使用rpm命令安装就可以了.

skyeye-1.2.5和skyeye-testsuite-1.2.5

<a href="http://gro.clinux.org/frs/?group_id=327">http://gro.clinux.org/frs/?group_id=327</a>

2)安装skyeye

进入skyeye的解压目录后,执行下面的命令

#./configure

#./make

#./make install

3)安装和运行testsuite

#bzip2 -d skyeye-testsuite-1.2.5.tar.bz2

#tar -xf skyeye-testsuite-1.2.5.tar

#cd skyeye-testsuite-1.2.5/linux/s3c2410/s3c2410x-2.6.14

#skyeye -e vmlinux

看到ARM Linux启动了,就是运行成功了

上面的过程太顺利了,我想利用skyeye运行了一下自己的ARM程序,观察程序运行的效果。

所以开始了下面的步骤。

1)生成ARM elf可执行程序

我对汇编不是很熟,刚开始学,不想陷入汇编程序的泥潭里。

所以这里首先使用c作为开发语言。Sample程序如下:

test.c:

void _start()

{

int gint=-1;

int ret=-20;

ret=gint+ret;

}

注意上面的函数名必须是_start,这是arm-gcc认可的程序入口函数,就像c语言里的main函数一样。

然后使用arm-gcc进行编译。

#export PATH=/opt/cross/arm/2.95.3-2.15/arm-cacko-linux-gnu/bin:$PATH

#gcc -S test.c

#as test2.s -o test.o

#ld test.o -o test

2)运行ARM elf可执行程序

编译OK了,下面尝试运行它吧!

首先要准备skyeye.conf配置文件.你可以从一个Sample配置文件稍微改改就可以了,比如Skyeye README中的.

这里使用下面的简单的配置文件。

cpu: arm920t

mach: s3c2410x

# physical memory

mem_bank: map=M, type=RW, addr=0x00000000, size=0x00800000

mem_bank: map=M, type=RW, addr=0xff7fffff, size=0x00800000

lcd: type=s3c2410x, mod=gtk

下面执行前面的test ARM 程序。

#skyeye -e test

Your elf file is little endian.

arch: arm

cpu info: armv4, arm920t, 41009200, ff00fff0, 2

mach info: name s3c2410x, mach_init addr 0x806bd90

uart_mod:0, desc_in:, desc_out:, converter:

SKYEYE: use arm920t mmu ops

start addr is set to 0x00008074 by exec file.

现在它已经运行完了,不过看不到结果.下面准备通过日志观察结果.

在skyeye.conf配置文件中追加下面一行,指示Skyeye每次执行一条指令时,输出CPU内部的各组寄存器的值。

log: logon=2, logfile=/tmp/sk1.log, start=0, end=100

现在再执行一遍刚才的程序,日志应该已经生成了.对照一下前面编译时生成的汇编程序,和日志中记录的

CPU寄存器的值的变化吧。

# cat test2.s

@ Generated by gcc 2.95.3 20010315 (release) for ARM/elf

        .file   "test2.c"

gcc2_compiled.:

.text

        .align  2

        .global _start

        .type    _start,function

_start:

        @ args = 0, pretend = 0, frame = 8

        @ frame_needed = 1, current_function_anonymous_args = 0

        mov     ip, sp

        stmfd   sp!, {fp, ip, lr, pc}

        sub     fp, ip, #4

        sub     sp, sp, #8

        mvn     r3, #0

        str     r3, [fp, #-16]

        mvn     r3, #19

        str     r3, [fp, #-20]

        ldr     r3, [fp, #-20]

        ldr     r2, [fp, #-16]

        add     r3, r3, r2

.L2:

        ldmea   fp, {fp, sp, pc}

.Lfe1:

        .size    _start,.Lfe1-_start

        .ident  "GCC: (GNU) 2.95.3 20010315 (release)"

上面一共有13条指令,现在我们跟踪一下这13条指令的执行情况

# head -14 /tmp/sk1.log

N 0 :p 8074,i e1a0c00d,R 0,c1,0,0,0,0,0,0,0,0,0,0,0,0,0,807c,C d3,S 0,0,0,0,0,0,0,M 13,B 3,E 0,I 0,P 0,T 0,L 0,D 0,

N 1 :p 8078,i e92dd800,R 0,c1,0,0,0,0,0,0,0,0,0,0,0,0,0,8080,C d3,S 0,0,0,0,0,0,0,M 13,B 3,E 0,I 0,P 0,T 0,L 0,D 0,

N 2 :p 807c,i e24cb004,R 0,c1,0,0,0,0,0,0,0,0,0,0,0,fffffff0,0,8084,C d3,S 0,0,0,0,0,0,0,M 13,B 3,E 0,I 0,P 0,T 0,L 0,D 0,

N 3 :p 8080,i e24dd008,R 0,c1,0,0,0,0,0,0,0,0,0,fffffffc,0,fffffff0,0,8088,C d3,S 0,0,0,0,0,0,0,M 13,B 3,E 0,I 0,P 0,T 0,L 0,D 0,

N 4 :p 8084,i e3e03000,R 0,c1,0,0,0,0,0,0,0,0,0,fffffffc,0,ffffffe8,0,808c,C d3,S 0,0,0,0,0,0,0,M 13,B 3,E 0,I 0,P 0,T 0,L 0,D 0,

N 5 :p 8088,i e50b3010,R 0,c1,0,ffffffff,0,0,0,0,0,0,0,fffffffc,0,ffffffe8,0,8090,C d3,S 0,0,0,0,0,0,0,M 13,B 3,E 0,I 0,P 0,T 0,L 0,D 0,

N 6 :p 808c,i e3e03013,R 0,c1,0,ffffffff,0,0,0,0,0,0,0,fffffffc,0,ffffffe8,0,8094,C d3,S 0,0,0,0,0,0,0,M 13,B 3,E 0,I 0,P 0,T 0,L 0,D 0,

N 7 :p 8090,i e50b3014,R 0,c1,0,ffffffec,0,0,0,0,0,0,0,fffffffc,0,ffffffe8,0,8098,C d3,S 0,0,0,0,0,0,0,M 13,B 3,E 0,I 0,P 0,T 0,L 0,D 0,

N 8 :p 8094,i e51b0014,R 0,c1,0,ffffffec,0,0,0,0,0,0,0,fffffffc,0,ffffffe8,0,809c,C d3,S 0,0,0,0,0,0,0,M 13,B 3,E 0,I 0,P 0,T 0,L 0,D 0,

N 9 :p 8098,i e51b1010,R ffffffec,c1,0,ffffffec,0,0,0,0,0,0,0,fffffffc,0,ffffffe8,0,80a0,C d3,S 0,0,0,0,0,0,0,M 13,B 3,E 0,I 0,P 0,T 0,L 0,D 0,

N a :p 809c,i eb000000,R ffffffec,ffffffff,0,ffffffec,0,0,0,0,0,0,0,fffffffc,0,ffffffe8,0,80a4,C d3,S 0,0,0,0,0,0,0,M 13,B 3,E 0,I 0,P 0,T 0,L 0,D 0,

N b :p 80a4,i e1a0c00d,R ffffffec,ffffffff,0,ffffffec,0,0,0,0,0,0,0,fffffffc,0,ffffffe8,80a0,80ac,C d3,S 0,0,0,0,0,0,0,M 13,B 3,E 0,I 0,P 0,T 0,L 0,D 0,

N c :p 80a8,i e92ddbe0,R ffffffec,ffffffff,0,ffffffec,0,0,0,0,0,0,0,fffffffc,ffffffe8,ffffffe8,80a0,80b0,C d3,S 0,0,0,0,0,0,0,M 13,B 3,E 0,I 0,P 0,T 0,L 0,D 0,

N d :p 80ac,i e24cb004,R ffffffec,ffffffff,0,ffffffec,0,0,0,0,0,0,0,fffffffc,ffffffe8,ffffffc4,80a0,80b4,C d3,S 0,0,0,0,0,0,0,M 13,B 3,E 0,I 0,P 0,T 0,L 0,D 0,

题外话:

做这个练习的时候我正在学习ARM系统,对其中的一些东西不太理解,现在通过上面方法终于搞清楚了。

1)ARM系统里PC指向取指地址,而不是正在执行的指令的地址,由于流水线的原因,PC指向的是当前正在执行的指令的后面第2个指令。

   同时我证实了汇编器在计算相对地址时已经考虑到这个问题。比如下面的语句。

loop:b loop

   b跳转到自己,汇编器产生的跳转指令的偏移量是-2而不是0。

2)CPU的CZVN四个状态位,根据对它们的描述,有几位是关于有符号数的(VN),有的是关于无符号数的(C),但CPU如何区分有符号数操作和无符号数操作的呢?

  作了试验才明白,CPU是不做区分的,它按照一致的方法对应。以加法操作为例

C:逻辑上是针对无符号数的,所以CPU假设操作就是无符号数.

N:逻辑上是针对有符号数的,所以CPU假设操作就是有符号数.

V:逻辑上是针对有符号数的,所以CPU假设操作就是有符号数.

 另外,由于用于保存有符号数的补码的特点,使得不论是有符号数的加减和还是无符号数的加减,其产生的二进制数据都是一样。

继续阅读