天天看點

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