(一)%WINCE\PLATFORM\COMMON\SRC\ARM\Freescale\MX21\Startup\startup.s
WinCE_MX21_BSP用户手册里提到的OAL层源代码,用于在OEM板级初始化前先初始化MX21处理器的核心模块。
主要的函数代码解读如下:
1.StartUp()---这部分代码是Eboot和OAL共享的。
movr0, #(SVCMode:OR:IRQDisable:OR:FIQDisable)
msrcpsr_c, r0
//在板子上电后,第一步是将处理器设置为特权模式
blMMUCacheDisable
//跳转到MMUCacheDisable( ),使TLB和cache、写缓冲无效,并关闭MMU、cache。
ldrr1, =CSP_BASE_REG_PA_AIPI1
ldrr0, =0x00040304
……
strr0, [r1, #AIPI_PAR_OFFSET]
//设置AIPI寄存器
blOALSetUpSystemControl
blOALSetUpFrequencies
//跳转到OALSetUpSystemControl和OALSetUpFrequencies,初始化系统控制模式和时钟频率。
mrcp15, 0, r0, c1, c0, 0
orrr0, r0, #0x00001000
mcrp15, 0, r0, c1, c0, 0
//启用I Cache
blOALIsImageInRAM
blOALSetUpExtMemories
//跳转到OALIsImageInRAM、OALSetUpExtMemories以初始化外部存储设备。
ldrr1, =CSP_BASE_REG_PA_MAX
ldrr0, =0x77123045
strr0, [r1, #MAX_MPR0_OFFSET]
……
strr0, [r1, #AITC_NIPRIORITY0_OFFSET]
//设置MAX寄存器、配置AITC中断控制器、屏蔽和清中断的一段代码。
blOALSetUpGpio
blOALSetUpKeypad
bOALStartUp
//先后跳转到OALSetUpGpio、OALSetUpKeypad,即初始化系统GPIO和键盘设备。最后程序转到OALStartUp(),执行代码重定位和从RAM中启动Eboot功能。
上面提到的OALSetUpSystemControl、OALSetUpFrequencies、OALSetUpExtMemories、OALSetUpGpio、OALSetUpKeypad这几个函数位于 %WINCE\PLATFORM \iMX21\ Imx21ads\Src\Kernel\Oal\oal_startup.c中;OALIsImageInRAM()和OALStartUp()则位于%WINCE\PLATFORM\Imx21ads\Src\Kernel\Oal\startup.s中。
2.MMUSetup()---这个函数将被%Eboot\startup.s调用,它根据OEMAddressTable设置MMU,并使能MMU、启用cache。
(二)%WINCE\PLATFORM\Imx21ads\Src\Kernel\Oal\startup.s
功能:OEM板级初始化
这部分代码首先定义了flash、RAM的物理地址和虚拟地址:
FlashPABaseEQUCSP_BASE_MEM_PA_CS0
FlashVABaseEQU0x80000000
RamPABaseEQUCSP_BASE_MEM_PA_CSD0
RamVABaseEQU0x88000000
RamMaxSizeEQU0x04000000 ; 64M
接下来的代码可以分成四个函数:
OALStartUp()
adrr0, g_oalAddressTable
bKernelStart
//加载OEMAddressTable地址,跳转到KernelStart()
OALIsImageInRAM()---检查Image是否正跑在RAM里
BSPAmdBurstCfg44M()---将iMX21标准板的flash设置为burst模式44M频率
BSPAmdBurstCfg66M()---将iMX21标准板的flash设置为burst模式66M频率
(三)%WINCE\PLATFORM\Imx21ads\Src\Bootloader\Eboot\startup.s
功能:调用了OAL的Startup.s(位于%WINCE\Platform\Common\Src\Arm\Freescale\MX21),将Eboot重定位至RAM中运行,并初始化MMU,使能MMU、cache,引导启动CE内核等。
基本流程:
首先给出了一系列宏定义,比如Eboot的大小和地址信息:
EbootRamOffsetEQU0x00010000
EbootImageSizeEQU0x00040000
EbootFlashPAStartEQU(FlashPABase)
EbootFlashVAStartEQU(FlashVABase)
EbootRamPAStart EQU(RamPABase + EbootRamOffset)
EbootRamVAStart EQU(RamVABase + EbootRamOffset)
//这里的信息是和eboot.bib相对应的,要对照着改动。
MmuPageTableOffsetEQU0x00001000
MmuPageTableBaseEQU (RamPABase + MmuPageTableOffset)
//MMU页表在RAM中的物理地址和大小
StackEndOffsetEQU0x00070000
StackEndVAEQU(RamVABase + StackEndOffset)
//栈尾的偏移地址和虚拟地址
接着进入KernelStart()函数,先跳转到OALIsImageInRAM程序段判断Image是否正跑在RAM里。
blOALIsImageInRAM
cmpr0, #1
beqRamStart
//如果已经在RAM里,则跳转到RamStart程序段
如果不是,则在接下来的RelocateEBOOT程序段里进行代码重定位:
ldrr1, =FlashPABase
ldrr0, =EbootRamPAStart
ldrr2, =(EbootImageSize/16)
ldmiar1!, {r3-r6}
stmiar0!, {r3-r6}
subsr2, r2, #1
bne%b10
adrr2, RamStart
ldrr3, =(FlashPABase)
subr3, r2, r3
ldrr4, =(EbootRamPAStart)
addr2, r4, r3
bxr2
RamStart段代码如下:
adrr2, MMUSetupDone
ldrr3, =(EbootRamPAStart)
subr2, r2, r3
ldrr3, =(EbootRamVAStart)
addr2, r2, r3
movlr, r2
//设置连接寄存器LR
adrlr0, g_oalAddressTable
//加载OEMAddressTable和页表的地址
ldrr1, =(MmuPageTableBase)
//加载页表的地址
bMMUSetup
nop
nop
nop
nop
nop
//跳转到OAL层核心源代码的MMUSetup函数,使能MMU、设置虚拟内存模式,并通过g_oalAddressTable初始化MMU页表
MMUSetupDone
ldrsp, =(StackEndVA-4)
//MMU配置完成,使栈指针处于虚拟内存中
bBootloaderMain
//跳转到% blcommon.c中的BootloaderMain()
最后的Launch()代码段是由EBOOT启动函数OEMLaunch( )所调用的,用来关闭MMU,跳转到CE内核。
movr1, #0
mcrp15, 0, r1, c7, c7, 0//初始化I, D cache
mcrp15, 0, r1, c7, c10, 4//初始化write buffer
mcrp15, 0, r1, c8, c7, 0 //设置TLB无效
movr1, #0x0078
mcrp15, 0, r1, c1, c0, 0 // Disable MMU, caches和write buffer
movpc, r0//跳转到PhysicalStart
nop
nop
nop
nop
一般认为%WINCE\PLATFORM\COMMON\SRC\ARM\Freescale\MX21\Startup\startup.s里的Startup( )是i.MX21标准板Eboot的第一个函数,上电后首先完成系统CPU初始化。
posted on 2008-08-06 10:23 milkyway 阅读(2344) 评论(0) 编辑 收藏 引用 所属分类: Wince学习小结