打印

HelloWorld on Skyeye,新手请进!

收到! 谢谢

TOP

太好了,感谢楼主!

TOP

非常感谢楼主啊

TOP

关于这个HelloWorld的程序执行流程

根据楼主的教程和原程序的readme,这个Hello4Skyeye的程序我已经能够运行起来了。只是关于这个程序里面的执行流程我有点问题。

我看了start.s文件,里面有
[code:1]
bl hello
b begin
[/code:1]
这一段语句,所以这个程序就不断输出:“helloworld”。
可是我想改成让他只输出一次,于是我就改成这样:
[code:1]
bl hello
@ b begin
[/code:1]
可是这样修改之后没有效果,还是不停地输出,所以我想请教一下这个程序的具体执行流程,为什么会不断输出呢?

另外,我调试的时候看了一下编译出来的汇编代码,发现程序的最后总有这么一句指令:
[code:1]
tsteq r0, r0
[/code:1]
我想问问这句指令到底怎么会编译出来的呢,原程序的.s文件和.c文件都没有相对应的指令阿。

新手提问,希望大家多多指教。

TOP

难道置顶贴里的问题没人关心的吗?

TOP

不好意思,这段时间我在忙另外一个项目。虽然我这次没有调试Hello4Skyeye,但我想还是可以回答你的第一个问题。

Hello4Skyeye结尾并没有终止语句,如果把b begin注释去。Skyeye运行的时候,运行到Hello4Skyeye的结尾并不会停止,而是继续往下执行。下面的指令因为不在Hello4Skyeye的代码段中,所以情况就难以预料了。

根据经验,后面未放代码的地方的指令往往是将程序指令寄存器重新置为0。所以这时程序会调转到0地址开始执行。Hello4Skyeye不是加载到0x01000000地址么,当程序执行到0x01000000地址的时候又会重新执行Hello4Skyeye。这样等于是个大循环。

如果你发现更改完的Hello4Skyeye运行是仍然不断输出Helloworld但是输出速度明显慢于未修改前的,那就基本可以断定是我上面所说的原因。

关于第二个问题,我现在只能大概说明一下,不要认为反汇编出来的就都是指令。有时候反汇编会把数据区的数据反汇编为指令。不知道是不是这个原因才显示tsteq r0, r0

如果你能用Skyeye的log功能调试程序,那么第一个问题是很好解决的。

使用SkyEye的log功能调试Hello4SkyEye:

上章介绍了源码级调试Hello4SkyEye的方法,之所以能进行源码级调试,是因为makefile中编译选项有-g参数,hello.lds文件中有和debug相关段的输出,并且hello可执行程序是elf格式的。这样SkyEye在装载hello程序的时候,就可以从文件中读取相关的调试信息。

但是很多情况下,SkyEye上运行的操作系统内核并非是ELF格式,那么Skeye就无法进行源码级调试了。这个时候使用串口输出调试信息,是调试内核的一个简单方法。但是在串口初始化之前,是无法使用这个方法调试的。其实使用SkyEye调试内核,有一个非常简单有效的方法,那就是使用SkyEye的log功能。我们可以记录下程序的运行流程,再和程序源码及反汇编代码对照,就可以分析出程序运行的流程和各步指令执行时Skyeye虚拟机的状态,根据这些信息就不难推断错误的原因。现在我们可以用Hello4SkyEye来尝试一下SkyEye这种神奇的功能。

SkyEye的log控制选项的说明如下:

log选项用于控制skyeye输出硬件系统的执行状态信息,包括每次执行指令时的执行指令值、寄存器值、各种硬件状态等。
格式:
log: logon=0|1, logfile=filename, start=number1, end=number2, length=number3
    logon=0|1|2|3,如果值等于0表示不进行记录,如果值等于1表示记录指令和指令地址流,如果值等于2表示记录指令和指令地址和主要寄存器内容,如果值等于3表示记录指令和指令地址和所有的寄存器内容。
    logfile=filename 其值是一个字符串,表示用于记录信息的文件名
    start=number1 其值是一个>=0的十进制整数,表示系统执行到第number1条指令时开始进行记录
    end =number2其值是一个>=0的十进制整数,表示系统执行到第number2条指令时停止记录
    length =number3其值是一个>=0的十进制整数,表示只记录系统最近执行的number3条指令时的信息

这里我们把skyeye.conf文件的最后一行改为:

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

再次运行skyeye hello后,使用Ctrl+C;quit指令退出SkyEye后,就可以在当前目录下的sk1.log中看到hello程序执行的指令流,和每步各主要寄存器的值。

sk1.log的59行到64行如下所示:

N 3b :p 1000044,i e2822001,R 100005c,fffd001c,9,64,0,0,0,0,0,0,0,1001ffc,1002000,......
N 3c :p 1000048,i e3520009,R 100005c,fffd001c,a,64,0,0,0,0,0,0,0,1001ffc,1002000,......
N 3d :p 100004c,i e5813000,R 100005c,fffd001c,a,64,0,0,0,0,0,0,0,1001ffc,1002000,......
N 3e :p 1000050,i dafffffa,R 100005c,fffd001c,a,64,0,0,0,0,0,0,0,1001ffc,1002000,......
N 3f :p 1000054,i e91ba800,R 100005c,fffd001c,a,64,0,0,0,0,0,0,0,1001ffc,1002000,......
N 40 :p 1000010,i eafffffa,R 100005c,fffd001c,a,64,0,0,0,0,0,0,0,0,1002000,......


现在就要说明log表与文件源码的对照技巧了。打开hello.s文件,该文件是make时,使用"objdump -xS hello"指令产生的反汇编文件。其中部分如下所示:

for(i=0;i<10;i++)
1000038: e3a02000 mov r2, #0 ; 0x0
100003c: e59f0014 ldr r0, [pc, #20] ; 1000058 <hello+0x38>
{
      * paddr=hellostr;
1000040: e7d03002 ldrb r3, [r0, r2]
1000044: e2822001 add r2, r2, #1 ; 0x1
1000048: e3520009 cmp r2, #9 ; 0x9
100004c: e5813000 str r3, [r1]
1000050: dafffffa ble 1000040 <hello+0x20>
      return;
}
1000054: e91ba800 ldmdb fp, {fp, sp, pc}


从log表中可以看出在执行了0x3b步指令后,程序的指令地址是0x1000044,指令内容是0xe2822001。再看反汇编表,0x1000044地址的指令正是0xe2822001,对应的汇编代码是“add r2, r2, #1”,程序正运行在hello函数中的for循环中。

可以从反汇编表的下面两步(0x1000044,0x100004

    add r2,r2, #1;
    cmp r2, #9

两句指令看出,计数器i就是寄存器r2。然后看log表中第0x3b步,此时r2=9,这说明hello函数的for循环已经执行了9次,现在正在执行第10次。下步0x3c的时候r2就是0xa(10)了,这正是执行了add r2, r2, #1的结果。这时执行cmp r2,#9判断语句显然r2>9,程序就不再循环而是接着执行下面三步(0x100004c,0x1000050,0x1000054)

   str r3,[r1];
   ble 1000040;
   ldmdb fp, {fp, sp, pd}。

这些指令的执行效果就是退出循环,hello函数返回。可以看到log表结果与此相符,第0x40步的时候,程序跳转到0x1000010处执行了。

从上面的分析可以看出既便不使用skyeye源码级调试的方法,我们也可以通过log表和反汇编表,看出程序运行的流程和关键处的寄存器值,如果发生错误,就可以通过流程变化和寄存器的值分析错误的原因。

TOP

呵呵,真是要谢谢楼主了,回帖很详细,很有价值。明天我去试试看log功能调试。

楼主真是热心人!

TOP

[quote:680d2d4e5d="shang79"]
如果你发现更改完的Hello4Skyeye运行是仍然不断输出Helloworld但是输出速度明显慢于未修改前的,那就基本可以断定是我上面所说的原因。
[/quote]

补充一下,观察到的现象的确如此的。

TOP

我是用户,为何看不到源码的链接,
谁可以给我一个?iolinux@163.com  

3q先

TOP

楼上的,已经给你发了。

你是不是没有登陆呢?
先登陆后再看楼主的帖子应该就能看到的。

TOP

继续我的问题

今天按照楼主说的方法用了一下log调试功能,只是那个logon=2的情况下,前两项是指令地址和指令,这个看的明白,可是后面记录的那些主要寄存器有哪些呢?顺序是什么样的呢?

我先贴一下部分代码和log文件:

这里是我的start.s文件:
[code:1]
begin:

        @set up irq stack

        mov         r0, #0xd2                @ make irq mode with all irqs disabled

        msr         cpsr, r0

        ldr         sp, =irq_stack           @ set sp_irq = irq_stack
        bl        hello

        @b        begin
               

.data

        .align  4

irq_stack:

        .space        4096
[/code:1]

可以看到这里我还是把那句调到begin的给注释掉了。

下面是编译后的那个hello.s的反汇编文件:
[code:1]
01000000 <begin>:
1000000:        e3a000d2         mov        r0, #210        ; 0xd2
1000004:        e129f000         msr        CPSR_all, r0
1000008:        e59fd000         ldr        sp, [pc, #0]        ; 1000010 <begin+0x10>
100000c:        eb000000         bl        1000014 <hello>
1000010:        01002000         tsteq        r0, r0
[/code:1]
这一段是对应前面那个start.s的代码。下面部分是hello函数中return的部分:
[code:1]
    return;       
}
1000048:        e91ba800         ldmdb        r11, {r11, sp, pc}
100004c:        01000050         tsteq        r0, r0, asr r0
1000050:        6c6c6568         stcvsl        5, cr6, [r12], -#416
1000054:        726f776f         rsbvc        r7, pc, #29097984        ; 0x1bc0000
1000058:        Address 0x1000058 is out of bounds.
[/code:1]

下面是那个log文件的一部分:
[code:1]
N 3a :p 1000034,i e7d03002,R 1000050,fffd001c,9,6c,0,0,0,0,0,0,0,1001ffc,1002000,1001ff0,1000010,100003c,C d2,S 0,0,0,0,0,0,0,M 12,B 2,E 0,I 0,P 1000030,T 0,L e2822001,D e7d03002,
N 3b :p 1000038,i e2822001,R 1000050,fffd001c,9,64,0,0,0,0,0,0,0,1001ffc,1002000,1001ff0,1000010,1000040,C d2,S 0,0,0,0,0,0,0,M 12,B 2,E 0,I 0,P 1000030,T 0,L e2822001,D e7d03002,
N 3c :p 100003c,i e3520009,R 1000050,fffd001c,a,64,0,0,0,0,0,0,0,1001ffc,1002000,1001ff0,1000010,1000044,C d2,S 0,0,0,0,0,0,0,M 12,B 2,E 0,I 0,P 1000030,T 0,L e2822001,D e7d03002,
N 3d :p 1000040,i e5813000,R 1000050,fffd001c,a,64,0,0,0,0,0,0,0,1001ffc,1002000,1001ff0,1000010,1000048,C d2,S 0,0,0,0,0,0,0,M 12,B 2,E 0,I 0,P 1000030,T 0,L e2822001,D e7d03002,
N 3e :p 1000044,i dafffffa,R 1000050,fffd001c,a,64,0,0,0,0,0,0,0,1001ffc,1002000,1001ff0,1000010,100004c,C d2,S 0,0,0,0,0,0,0,M 12,B 2,E 0,I 0,P 1000030,T 0,L e2822001,D e7d03002,
N 3f :p 1000048,i e7ffdefe,R 1000050,fffd001c,a,64,0,0,0,0,0,0,0,1001ffc,1002000,1001ff0,1000010,1000050,C d2,S 0,0,0,0,0,0,0,M 12,B 2,E 0,I 0,P 1000030,T 0,L e2822001,D e7d03002,
N 40 :p 1000048,i e91ba800,R 1000050,fffd001c,a,64,0,0,0,0,0,0,0,1001ffc,1002000,1001ff0,1000010,1000050,C d2,S 0,0,0,0,0,0,0,M 12,B 2,E 0,I 0,P 1000048,T 0,L 6c6c6568,D 1000050,
N 41 :p 1000010,i 1002000,R 1000050,fffd001c,a,64,0,0,0,0,0,0,0,0,1002000,1002000,1000010,1000018,C d2,S 0,0,0,0,0,0,0,M 12,B 2,E 0,I 0,P 1000048,T 0,L 6c6c6568,D 1000050,
N 41 :p 1000010,i 1002000,R 1000050,fffd001c,a,64,0,0,0,0,0,0,0,0,1002000,1002000,1000010,1000018,C d2,S 0,0,0,0,0,0,0,M 12,B 2,E 0,I 0,P 1000010,T 0,L e92dd800,D e1a0c00d,
N 42 :p 1000014,i e1a0c00d,R 1000050,fffd001c,a,64,0,0,0,0,0,0,0,0,1002000,1002000,1000010,100001c,C d2,S 0,0,0,0,0,0,0,M 12,B 2,E 0,I 0,P 1000010,T 0,L e92dd800,D e1a0c00d,
N 42 :p 1000014,i e1a0c00d,R 1000050,fffd001c,a,64,0,0,0,0,0,0,0,0,1002000,1002000,1000010,100001c,C d2,S 0,0,0,0,0,0,0,M 12,B 2,E 0,I 0,P 1000014,T 0,L e24cb004,D e92dd800,
N 43 :p 1000018,i e92dd800,R 1000050,fffd001c,a,64,0,0,0,0,0,0,0,0,1002000,1002000,1000010,1000020,C d2,S 0,0,0,0,0,0,0,M 12,B 2,E 0,I 0,P 1000014,T 0,L e24cb004,D e92dd800,
N 44 :p 100001c,i e24cb004,R 1000050,fffd001c,a,64,0,0,0,0,0,0,0,0,1002000,1001ff0,1000010,1000024,C d2,S 0,0,0,0,0,0,0,M 12,B 2,E 0,I 0,P 1000014,T 0,L e24cb004,D e92dd800,
N 45 :p 1000020,i e3e01bbf,R 1000050,fffd001c,a,64,0,0,0,0,0,0,0,1001ffc,1002000,1001ff0,1000010,1000028,C d2,S 0,0,0,0,0,0,0,M 12,B 2,E 0,I 0,P 1000014,T 0,L e24cb004,D e92dd800,
N 46 :p 1000024,i e2411e3e,R 1000050,fffd03ff,a,64,0,0,0,0,0,0,0,1001ffc,1002000,1001ff0,1000010,100002c,C d2,S 0,0,0,0,0,0,0,M 12,B 2,E 0,I 0,P 1000014,T 0,L e24cb004,D e92dd800,
N 47 :p 1000028,i e2411003,R 1000050,fffd001f,a,64,0,0,0,0,0,0,0,1001ffc,1002000,1001ff0,1000010,1000030,C d2,S 0,0,0,0,0,0,0,M 12,B 2,E 0,I 0,P 1000014,T 0,L e24cb004,D e92dd800,
N 48 :p 100002c,i e7ffdefe,R 1000050,fffd001c,a,64,0,0,0,0,0,0,0,1001ffc,1002000,1001ff0,1000010,1000034,C d2,S 0,0,0,0,0,0,0,M 12,B 2,E 0,I 0,P 1000014,T 0,L e24cb004,D e92dd800,
[/code:1]

下面是这段log里相关的一部分代码:
[code:1]
01000014 <hello>:
1000014:        e1a0c00d         mov        r12, sp
1000018:        e92dd800         stmdb        sp!, {r11, r12, lr, pc}
100001c:        e24cb004         sub        r11, r12, #4        ; 0x4
void hello(void)
{       
        int i;
        char * hellostr="helloworld";
        long* paddr=(long*)0xfffd001c;
1000020:        e3e01bbf         mvn        r1, #195584        ; 0x2fc00
1000024:        e2411e3e         sub        r1, r1, #992        ; 0x3e0
1000028:        e2411003         sub        r1, r1, #3        ; 0x3
[/code:1]

根据log文件可以看到在1000048执行了2次,而且第一次的指令是e7ffdefe,不是反汇编对应的指令,而后面那条1000048才是。之后就跳到了1000010,同样执行了2次,然后就又顺序执行到了hello里面。

这个过程就是我上次的问题所在了。看了log之后,还是没想明白,呵呵


麻烦老大继续来解释解释吧。  

另外我还有个问题,因为不了解GNU的汇编,所以想问问那下面终止语句是什么?
网上搜到了GNU AS的参考手册,可是没有找到该指令。

所以我想问问有什么可以学学GNU AS的,麻烦楼主继续指点~~~~

TOP

呵呵,我Skyeye执行的log怎么没有重复的记录?你用的Skyeye版本是多少的?
如果想要系统学习Skyeye,请看看下面这本书,会非常有帮助。
《源码开放得嵌入式系统软件分析和实践--基于skyeye和ARM开发平台》
另外,GNU AS讲的只是AT&T的汇编语法,真正的ARM汇编指令还是要查ARM开发书籍。这个和GNU AS是两回事

TOP

hello4skyeye 这个程序在哪呀?

刚开始学习skyeye,我下了skyeye.bin,但是请问上面提到的hello4skyeye的源码在什么?

TOP

[quote:fc7807dea3="shang79"]呵呵,我Skyeye执行的log怎么没有重复的记录?你用的Skyeye版本是多少的?
[/quote]
最新的那个吧,好象是0.8.8?具体忘了,明天看看,呵呵。
我这个是用skyinsight加了断点调试的,让他走了一次hello函数,再进入第二次后,我就把它退出了。
我就是好奇为什么会有重复记录呢,呵呵。


[quote:fc7807dea3="shang79"]
如果想要系统学习Skyeye,请看看下面这本书,会非常有帮助。
《源码开放得嵌入式系统软件分析和实践--基于skyeye和ARM开发平台》
[/quote]
已经在网上订了这本书了,只是还没送来,呵呵


[quote:fc7807dea3="shang79"]
另外,GNU AS讲的只是AT&T的汇编语法,真正的ARM汇编指令还是要查ARM开发书籍。这个和GNU AS是两回事[/quote]
哦,知道了。
只是在那下面开发,编译器是只支持GNU AS的呢?还是同样支持ARM指令的呢?是不是可以用ARM汇编指令重写你的那个start.s文件呢?

呵呵,问题较多,还忘多多指教~~

TOP

Re: hello4skyeye 这个程序在哪呀?

[quote:d102efd4b3="pace"]刚开始学习skyeye,我下了skyeye.bin,但是请问上面提到的hello4skyeye的源码在什么?[/quote]

源码见本贴的顶楼,呵呵

TOP