原创 AT91SAM9261 EBOOT 分析 startup.s

2010-4-8 23:32 2917 2 2 分类: MCU/ 嵌入式

StartUp()函数是EBOOT运行的第一个函数,在sources文件中是这样定义的
  
  TARGETNAME=eboot
  TARGETTYPE=PROGRAM
  RELEASETYPE=PLATFORM
  EXEENTRY=StartUp
  
  如果把EXEENTRY的参数改掉,就可以用其他的函数名作为入口,但是没有必要。
  详情参考<<Windows CE 工程实践完全解析>> p29


1) LEAF_ENTRY StartUp  
  声明StartUp()函数入口,关于LEAF_ENTRY,可以查看MSDN的帮助文档。
  只要知道这是干什么的就行了,也不要细究,下面是MSDN中的解释.
 
  LEAF_ENTRY (ARM)See Also
  ENTRY_END (ARM) | PROLOG_END (ARM)


  Requirements
  OS Versions: Windows CE .NET 4.0 and later.
  Header: Kxarm.h.
  This macro declares the beginning of a routine that does not require prolog code.


  LEAF_ENTRY Name[,
  [Section=]SectionName]
  Parameters
  Name
  The routine name.
  SectionName
  Optional. The name of the section where the entry appears. I
  Defaults to .text.


  Return Values
  None.


  Remarks
  Name is in the global name space.


  A LEAF_ENTRY must have an associated ENTRY_END (ARM).


  Requirements
  OS Versions: Windows CE .NET 4.0 and later.
  Header: Kxarm.h.


  


2) 设置cpu进入特权模式,同时禁止IRQ和FIQ中断
  禁能MMU,缓存,写缓冲和刷新
  关于MMU方面的详细的内容可以参考<<ARM体系结构与编程>>


3) OALStartUp()
  OEM bootloader的引导启动代码。如果bootloader的映像不是在RAM中运行的话
  就将映像复制到RAM中,设置MMU和Dcache。基于MemoryMap数组构造一级页表。
  使能MMU和caches。
  这里的MemoryMap指的就是g_oalAddressTable数组,这个数组的位置在
  C:\WINCE600\PLATFORM\AT91SAM9261EK\SRC\INC\cfg.inc
  
  a)设置特权模式的堆栈指针
  b)如果需要把bootloader的镜像从flash中拷贝到SDRAM中。
  但是在这里是不需要的,因为ROM Boot已经自动完成这一步了。
  c)调用BUILDTTB()函数,这个函数具体负责创建页表并且启用MMU。
  d)跳转到main()函数,这是个c语言函数,之后就不再返回。


在StartUp.s文件中还有一个非常重要的函数 void Launch(UINT32 pFunc)
这个函数将PC指向pFunc参数指向的地址(物理地址),实现跳转。在跳转前需要禁止MMU。
这个函数将被OEMLaunch()调用,调用之后,操作系统将开始运行,EBOOT程序执行完毕。
下面我们把这个函数详细分析一下。


;------------------------------------------------------------------------------
函数原型:void Launch(UINT32 pFunc)
     This function launches the program at pFunc (pFunc
     is a physical address).  The MMU is disabled just
     before jumping to specified address.


输入参数: pFunc (r0) - Physical address of program to Launch.
          将要跳转的物理地址,保存在r0中
 
返回:   None - the launched program never returns.
     不返回,一旦跳转永不返回。
;------------------------------------------------------------------------------


    ALIGN
    LEAF_ENTRY Launch   ;定义函数名
  
    ; r3 now contains the physical launch address.
    ; 转存一下到r3
    mov     r3, r0


    ; Compute the physical address of the PhysicalStart tag.  We'll jump to this
    ; address once we've turned the MMU and caches off.
    ; 下面的语句是将PhysicalStart标号的物理地址,因为在这之前已经启用了MMU,启用MMU之后
    ; 所有的地址就都是虚拟地址了,包括PhysicalStart标号的地址。把PhysicalStart标号的虚拟
    ; 地址转换为物理地址存放到r0中。
    stmdb   sp!, {r3}
    ldr     r0, =PhysicalStart ; we must keep this therwise it doesn't work
  add  r0,pc,#PhysicalStart - (. + 8)
    bl      OALVAtoPA
    nop 
    ldmia   sp!, {r3}
   
    ; r0 now contains the physical address of 'PhysicalStart'.
    ; r0 存放的是PhysicalStart的物理地址
    ; r3 now contains the physical launch address.
  ; r3 存放的是将要跳转的物理地址
  
    ; clean entire data cache
    ; 清空数据缓存
10 mrc p15, 0, r15, c7, c10, 3
  bne %b10
          
    ; Next, we disable the MMU, and I&D caches.
    ; 禁用MMU,数据缓存,指令缓存
    mov     r1, #0x0078
    mcr     p15, 0, r1, c1, c0, 0


   
    ; Jump to 'PhysicalStart'.
    ; 跳转到 PhysicalStart标号处
    mov  pc, r0
    nop
    nop
    nop
    nop


PhysicalStart


    ; Flush the I&D TLBs.
    ; 使快表中的数据无效
    mcr     p15, 0, r2, c8, c7, 0   ; Flush the I&D TLBs


    ; Jump to the physical launch address.  This should never return...
    ; 跳转到r3指向的地址处,实际上是WindowsCE操作系统的起始运行地址
    mov     pc, r3 
    nop
    nop
    nop
    nop
    nop
    nop
;------------------------------------------------------------------------------
  

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
2
关闭 站长推荐上一条 /3 下一条