超级教师小说廖学兵:entry与bootloader_helloElectron

来源:百度文库 编辑:九乡新闻网 时间:2024/05/01 11:01:08
entry与bootloader2011-03-06 11:04

Build target 'LED'
linking...
.\obj\LED.axf: Warning: L6305W: Image does not have an entry point. (Not specified or not set due to multiple choices.)
Program Size: Code=1284 RO-data=0 RW-data=0 ZI-data=1288 
".\obj\LED.axf" - 0 Error(s), 1 Warning(s).

编译一个例程,出现警告,

"警告:L6305W:图像没有入口点。(由于有多种选择而未指定或未设置)

google一下。

////////////////////////////////////////////////////////////////////////

L6305WImage does not have an entry point. (Not specified or not set due to multiple choices.)

The entry point for the ELF image was either not specified, or was not set because there was more than one section with an entry point linked-in. You must use linker option --entry to specify the single, unique entry such as, for example:

--entry 0x0

or

--entry

The label form is typical for an embedded system.

////////////////////////////////////////////////////////////////////////////////////////////

解决:options for target---linker---misc controls

填写 --entry Reset_Handler   ;ENTRY 伪指令用于指定汇编程序的入口点

/--------------------------------------/

Vectors        
    ; ENTRY
                LDR     PC, Reset_Addr        
                LDR     PC, Undef_Addr

.............................................................

..............................................................

..............................................................

Reset_Addr      DCD     Reset_Handler
Undef_Addr      DCD     UndefHandler

.......................................................

.....................................................

..........................................................

/----------------------------------------/

摘要:ARM link的时候-entry ‘行标号’ 选项用于指定程序的入口地址,其实就是ICE把代码load完之后自动跳入的地址,最后的程序中这个工作是由bootloader来完成的,当然bootloader也可以跳到别的入口地址去。几乎所有的成品ARM芯片都有内置的bootloader,因此开发者看到的程序入口点就是entry point。对于FPGA上的ARM系统调试,ARM复位后跳转到一个固化地址,就需要自己写bootloader代码并通过scatter加载到rom中(我们的EAS片上存储器包括rom在内全部用FPGA的ram实现,tape out的时候bootloader代码会被固化到chip的rom中)

1.entry point在编译中的指定

   看了make file,entry point的指定是在link的时候用命令行参数的方式告诉编译器的,

armlink ... -Entry reset_handler

如果采用RVDS或ADS,工程属性中有entry point选项可供设置,但最终还是作为参数传递给armlink。

这样, 在连接ICE并loadimage之后,ICE会通过JTAG把代码映像搬移到内存中,然后把当前PC指针指向reset_handler,但引出了一个问题:在最终的产品中不存在ICE和JTAG,ARM上电复位后跳向固化的复位地址,如0xFFFF0000,那么由谁来让PC指针指向我们指定的entry point呢?答案是:由bootloader代码来完成,进一步引出2个问题:1,谁来生成bootloader?2,怎么把bootloader定位到硬件复位地址?

2. 自己写bootloader并通过scatter文件将之定位到硬件复位地址。

或许某些开发工具会自动的为我们生成bootloader,这里介绍的是自力更生的方法。

首先介绍bootloader,这里仅实现中断向跳转:

        AREA Vect, CODE, READONLY     ;编译器伪指令,scatter根据这些属性来组织程序映像

        ENTRY   ;这个entry和本文中的entry point是没有关系的,它表示的是汇编程序代码部分的开始

        LDR PC, Reset_Addr
        LDR PC, Undefined_Addr
        LDR PC, SWI_Addr
        LDR PC, Prefetch_Addr
        LDR PC, Abort_Addr
        NOP                         ; Reserved vector
        LDR PC, IRQ_Addr
        LDR PC, FIQ_Addr

        Reset_Addr          DCD Reset_Handler
        Undefined_Addr   DCD Undefined_Handler
        SWI_Addr             DCD SWI_Handler
        Prefetch_Addr      DCD Prefetch_Handler
        Abort_Addr           DCD Abort_Handler
        IRQ_Addr            DCD IRQ_Handler
        FIQ_Addr            DCD FIQ_Handler

Reset_Handler
        LDR PC, =0x00000000;

然后是scatter文件:

ROM_LOAD 0x00000000
{
    ROM_EXEC 0x00000000              
    { 
          * (InRoot$$Sections); 实现搬移scatter的代码,编译器自动生成
         *(+RO) ; 除了bootloader的所有代码段放这里
    }
    D-TCM 0x00400000 0x003FFFFF
    {
        * (+RW,+ZI);这里放所有的RW段(char ch=4;)和ZI段(char ch; ch会被初始化零)。
    }
}

ROM2 0xFFFF0000
{
   BOOTLOAD 0xFFFF0000
    {
        bootloader.o(+RO) ;bootloader的程序段放这里
    }
}

scatter也是在link的时候通过参数‘-scatter 文件名’传递的。

3.总结

在以上条件下,比较使用ICE和最终产品中的启动顺序:当使用ICE调试时,ICE读入映像文件,找到其中的scatter信息,通过JTAG把代码段和数据段放到指定的位置,然后把PC设为-entry所指定的标号,这就是为什么当我们loadimage之后看到的是在entry point中指定的行号所在的源代码。当脱离ICE运行时,ARM上电后跳转到硬件复位地址0xFFF0000 (ROM),我们已事先在那里烧入了我们的bootloader,bootloder从外设中读入加载映像文件(如片外nand,I2C,UART等)并放入scatter的加载域中(0x00000000),然后跳转到0x000000,由于我们已在scatter中将InRoot$$Sections定位在那里,所以它被执行,它负责把映像文件从加载域搬移到执行域中,然后跳转到__main,__main是arm编译器自动生成的,它负责清零ZI段和初始化C库,最后__main跳向C代码的入口main()