n DownloadImage
这个函数将执行把操作系统Image文件下载到目标机的操作。
n OEMLaunch函数
这个函数将PC指针直接设置到Image文件的开始地址,它是启动操作系统前BootLoader的最后一个函数,没有返回值。在此之后,BootLoader就消失了。
下面分析SMDK2410的OEMLaunch的实现代码:
void OEMLaunch(DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr,
const ROMHDR *pRomHdr)
{
DWORD dwPhysLaunchAddr;
EDBG_OS_CONFIG_DATA *pCfgData;
EDBG_ADDR EshellHostAddr;
EBOOT_CFG EbootCfg;
//从flash得到eboot配制
ReadEbootConfig(&EbootCfg);
//下载并从服务器得到IP和端口设置后,等待Platform Builder连接
//连接也发送KITL标志,稍后将用于OS(KITL)
if (g_bWaitForConnect)
{
……
}
//如果该下载未提供一个地址,那么记住kernel的启动地址或者重新调用保存的地址、、
//(也就是不下载kernel区域)
if (dwLaunchAddr && (EbootCfg.LaunchAddress != dwLaunchAddr))
{
EbootCfg.LaunchAddress = dwLaunchAddr;
WriteEbootConfig(&EbootCfg);
}
else
{
dwLaunchAddr = EbootCfg.LaunchAddress;
}
//如果用户请求一个储存在flash中的RAM映像,可以马上去请求.对于多个RAM BIN文件
//需要将RAM地址映射到flash地址
// RAM中基于地址偏移的映像在flash中是连续的
if (g_bDownloadImage && (EbootCfg.ConfigFlags & CONFIG_FLAGS_SAVETOFLASH))
{
if (!WriteRegionsToSmartMedia(&EbootCfg))
{
EdbgOutputDebugString("WARNING: OEMLaunch: Failed to store image
to Smart Media./r/n");
}
}
//跳到下载的映像(物理地址,因为马上将关闭MMU)
dwPhysLaunchAddr = ToPhysicalAddr(dwLaunchAddr);
EdbgOutputDebugString("INFO: OEMLaunch: Jumping to Physical Address 0x%Xh
(Virtual Address 0x%Xh).../r/n/r/n/r/n", dwPhysLaunchAddr, dwLaunchAddr);
Launch(dwPhysLaunchAddr);
//应该从不返回
SpinForever();
}
(2)下载模块函数
下载函数是由DownloadImage函数调用的。
下面列出下载模块函数并解释它们。
n OEMReadData
BLCOMMON调用这个函数从文件的传输器中读取数据。读者可以参看Public/Common/
Oak/Ethdbg/Eboot/Ebsimp.c文件中网络传输的例子
n OEMShowProgress
BLCOMMON在下载操作系统镜像文件的时候调用这个函数。在这个函数中,可以实现通知用户下载状态的各种手段比如可以用LED灯交替闪烁或者向主机的串口发送进度信息等。
n OEMMapMemAddr
如果目标系统的需求是要能支持把操作系统的镜像文件下载到FLASH中去,就必须调用本函数。由于FLASH操作速度比RAM慢,在片擦除的时候甚至会使读写操作停滞,这样在每次下载操作系统镜像文件时,由于FLASH的擦写都会使下载停滞。而OEMMapMemAddr使用了RAM缓冲操作系统镜像文件的方式,使得用户在下载操作系统镜像文件时感觉不到停滞,这个函数将FLASH地址映射到RAM地址,这样向FLASH写的数据实际上先被缓冲到RAM中,然后再写到FLASH中。
(3)FLASH编程模块
FLASH函数用于对不同的FLASH存储器进行编程。开发人员需要实现微软公司提供的框架里的函数。
n OEMIsFlashAddr函数
判别地址是否为有效的FLASH地址。注意,这里的FLASH地址与平台相关的,如S3C2410芯片和PXA255芯片的FLASH地址是不一样的,即便是同一款CPU,由于硬件结构的不同(FLASH大小、位置等)FLASH地址也不尽相同。
n OEMStartEraseFlash函数
BLCOMMON在获取FLASH的实际大小和开始地址后,将立即调用这个函数。这个函数将进行FLASH的擦除工作。
n OEMContinueEraseFlash函数
BLCOMMON在下载操作系统镜像文件的过程中可以调用这个函数。当FLASH擦除发生错误的时候,可以用这个函数来重复擦除操作,并且进行校验。
n OEMFinishEraseFlash函数
FLASH擦除完成时,BLCOMMON调用这个函数。这个函数将校验所有的擦除工作是否完成。
n OEMWriteFlash函数
调用这个函数,将缓冲在FLASH_CACHE中的操作系统镜像文件写入FLASH中。
3.代码分析
(1)Startup代码分析
在/PLATFORM/XSC1BD/EBOOT/ARM/fwp2.s文件中定义了BootLoader启动时执行的汇编指令:
GBLL ETHBOOT
ETHBOOT SETL {TRUE}
INCLUDE ..//..//kernel//hal//arm//fwxsc1.s
END
这里将..//..//kernel//hal//arm//fwxsc1.s中的代码引入。
kernel//hal//arm//fwxsc1.s:
; --- Setup interrupt / exception vectors
STARTUPTEXT
LEAF_ENTRY StartUp
IMPORT main
B Reset_Handler
B Undefined_Handler
B SWI_Handler
B Prefetch_Handler
B Abort_Handler
NOP ;
B IRQ_Handler
B FIQ_Handler ;
SWI_Handler
IF PLAT_LUBBOCK = "1"
ldr r1, =0x01000000
ldr r2, =FPGA_REGS_BASE_PHYSICAL
str r1, [r2, #HEXLED_OFFSET]
ENDIF
Prefetch_Handler
IF PLAT_LUBBOCK = "1"
ldr r1, =0x00100000
ldr r2, =FPGA_REGS_BASE_PHYSICAL
str r1, [r2, #HEXLED_OFFSET]
ENDIF
Abort_Handler
; 在此处不保存状态
IF B_STEP_PXA2X0 = "1"
; 在步骤B中,只对PXA250或PXA210芯片做这个操作
mrc p15, 0, r3, c15, c1, 0 ;Get Reg15 of CP15 for Access to CP7
; **********************************
IRQ_Handler
IF PLAT_LUBBOCK = "1"
ldr r1, =0xABCDEFAB
ldr r2, =0x08000010
str r1, [r2]
ENDIF
b IRQ_Handler
; **********************************
FIQ_Handler
IF PLAT_LUBBOCK = "1"
ldr r1, =0x00000100
ldr r2, =FPGA_REGS_BASE_PHYSICAL
str r1, [r2, #HEXLED_OFFSET]
ENDIF
FIQ_STAY
b FIQ_STAY
; **********************************
ALIGN 32
Reset_Handler
bl INITGPIO
bl INITMEMC
bl INITINTC
bl INITCLKS
bl INITOST
bl INITRTC
bl INITPWRMAN
bl ENABLECLKS
bl INITPLATFORM
bl DISPLAY_FREQS
b INITMMU