天天看点

Windows CE嵌入式开发入门——基于Xscale架构(3)

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