全部博文(35)
2010年(35)
分类: 嵌入式
2010-06-21 21:35:39
StartUp()函数是EBOOT运行的第一个函数,在sources文件中是这样定义的
TARGETNAME=eboot
TARGETTYPE=PROGRAM
RELEASETYPE=PLATFORM
EXEENTRY=StartUp
如果把EXEENTRY的参数改掉,就可以用其他的函数名作为入口,但是没有必要。
详情参考<
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方面的详细的内容可以参考<
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
;------------------------------------------------------------------------------