(原创)构建基于aemb的sopc系统(四)--修改setup文件

现在从读xilinx.ldcrt0.scrtinit.s开始,构建自己的的setup文件,并实现仿真。

Rom.dump文件真实个非常有用的文件,iprinkf的函数具体怎样调用到outbyte函数的就可以从这个文件中追踪到。

现在可以把crt0.srom.dump文件结合着阅读。

_start跳转到_start1

_start1

       la      r13, r0, _SDA_BASE_     /* Set the Small Data Anchors and the stack pointer */

       la      r2, r0, _SDA2_BASE_

       la      r1, r0, _stack-16           /* 16 bytes (4 words are needed by crtinit for args and link reg */

       brlid   r15, _crtinit               /* Initialize BSS and run program */

       nop

       brlid   r15, exit                  /* Call exit with the return value of main */

       addik   r5, r3, 0                  

        /* Control does not reach here */

la的命令在《mb_ref_guide》中没有找到,在rom.dump反汇编文件中可以看到

00000050 <_start1>:

      50:              b0000000               imm              0

      54:              31a093a              addik              r13, r0, -27736              // 93a8 <_SDA_BASE_>

      58:              b0000000               imm              0

      5c:              30408e70               addik              r2, r0, -29072              // 8e70 <_SDA2_BASE_>

      60:              b0000000               imm              0

      64:              3020d408               addik              r1, r0, -11256

      68:              b9f400e4               brlid              r15, 228              // 14c <_crtinit>

      6c:              80000000               or              r0, r0, r0

      70:              b9f42818               brlid              r15, 10264              // 2888 <exit>

      74:              30a30000               addik              r5, r3, 0

La对应的指令时addik在《mb_ref_guide》中可以查到

addik rD, rA, IMM ;Add Immediate and Keep Carry

是个不改变进位标志位的加立即数的指令R0的作用如下:

Bits

Name

Description

Reset Value

0:31

R0

R0 is defined to always have the value of zero. Anything written to R0 is discarded.

0x00000000

R0的值始终为零。这条指令的作用就是把_SDA_BASE_的值赋给R13R13做什么用的,参见表Register usage conventionsR13用于指定.sdata段,类似的R2指定.sdata2R1指定堆栈指针,堆栈中的16个字节用于存储crtinit的参数

 

发现了一个还没有解决的问题,就是怎样设置standard output。就是怎样按自己的设置生成C库。EDK中有一个libgen工具,可以结合mss文件设置。在Nios2中也可以在IDE中设置,但若果用GUN的工具链该怎样操作呢?

       brlid   r15, _crtinit              /* Initialize BSS and run program */

brlid跳转到相对地址_crtinit执行crtinit中的初始化程序R15就是程序计数器。

当从 _crtinit返回时,就调用了exit

00002888 <exit>:

    2888:              3021ffe0               addik              r1, r1, -32

    288c:              10c00000               addk              r6, r0, r0

    2890:              fa61001c               swi              r19, r1, 28

    2894:              f9e10000               swi              r15, r1, 0

    2898:              b9f426d8               brlid              r15, 9944              // 4f70 <__call_exitprocs>

    289c:              12650000               addk              r19, r5, r0

    28a0:              b0000000               imm              0

    28a4:              e8a08acc               lwi              r5, r0, -30004              // 8acc <_global_impure_ptr>

    28a8:              e8650028               lwi              r3, r5, 40

    28ac:              bc03000c               beqi              r3, 12                            // 28b8

    28b0:              99fc1800               brald              r15, r3

    28b4:              80000000               or              r0, r0, r0

    28b8:              b9f4d7c              brlid              r15, -10304              // 78 <_exit>

28bc:              10b30000               addk              r5, r19, r0

exit做了一些收尾的工作就跳到了_exit,一个无限循环

/*  _exit    Our simple _exit */   

        .globl _exit

        .align 2

        .ent _exit

_exit:

        bri     0

       .end _exit

阅读一下crtinit.s文件

主要做的工作.sbss段和.bss段清零,调用_program_init程序,调用语言初始化函数__init,调用main函数,调用语言清理函__finit,调用_program_clean程序,返回crt

 

下面按Embedded System Tools Reference Guide--GNU Compiler Tools一章中所讲的Modifying Startup Files”“Compiler Libraries所讲。

用用户编写setup文件的方法来编译程序本文中只是了解这个流程,采用link scriptscrtn.scrtinit.s文件。

aemb/trunk/sw目录下新建一个custom_crt目录,把EDK软件中的crt0.scrtinit.s拷贝到这个目录下,把链接脚本文件xilinx.ld文件拷贝到aemb/trunk/sw目录下。然后修改gccrom脚本文件

修改之后只需在sw文件目录下运行

$ ./gccrom

即可,显示结果与未改之前相同

xgcc=0

dump=0

copy=0

srec=0

sha1=1811964ac2872266f5eda1289c314b8c

主要修改的选项:

CXXFLAGS变量

-O0改成-Os,主程序在编译时需设定大于等于-O1的优化选项

添加-nostartfiles选项,不适用默认的setup file

 

LNKFLAGS变量

添加-T xilinux.ld,指定自己修改的脚本文件

 

添加了INPUT变量,输入的源码文件,在这里,把C run time的文件也当做源码文件输入了。本应该先编译crt文件,再-B directory想指定C run time库的搜索路径的。

 

修改了crtinit.s中的文件,

        brlid   r15, __init                    /* Invoke language initialization functions */

        nop

        brlid   r15, __fini                    /* Invoke language cleanup functions */

        nop

注释掉可以避免引用重构和结构操作时所产生的额外的代码,减小了代码尺寸。

 

与采用默认的setup文件相比,减少了1076字节

再进行一下仿真

# AEMB2 32-bit Microprocessor Core Tests

#

              1. Integer Arithmetic

#

                            -PASS-

#

              2. Integer Factorisation

#

                            -PASS-

#

              3. Floating Point Arithmetic

#

                            -PASS-

#

              4. Memory Allocation

#

                            -PASS-

#

              5. Hardware Interrupts

#

                            -PASS-

#

              6. Accellerator Link

#

                            -PASS-

#

              7. Hardware Exceptions

#

                            -PASS-

#

#

# *** EXIT 0018d2d8 ***

# ** Note: $finish    : ./verilog/edk63.v(212)

#    Time: 1626840 ps  Iteration: 0  Instance: /edk63

可以看一下,仿真结果与之前的仿真是相同的。

其实,本次编译与上次编译几乎所有的代码都是一样的,所不一样的是,本次编译过程,是按自行编写C run time文件及link script的步骤操作的,它可以使我们认识newlib C库时系统的启动过程自定制地控制代码的编译过程。

以后会继续学习一下Newlib C库。

接下来,开始构建aembsopc软硬件系统并作系统仿真。


posted @ 2010-05-29 17:19  任怀鲁  阅读(1164)  评论(4编辑  收藏  举报