基于S3C2410A的WINCE下Stepldr程序移植详细分析[三]

#include <windows.h>
#include <pehdr.h>
#include <romldr.h>
#include "option.h"
#include "s2410addr.h"

// Constants.
//
#define LED_ON                 0xA
#define LED_OFF                 0x0

#define NAND_BLOCK_SIZE_BYTES   0x00004000
#define NAND_PAGE_SIZE_BYTES    0x00000200
#define NAND_PAGES_PER_BLOCK    (NAND_BLOCK_SIZE_BYTES / NAND_PAGE_SIZE_BYTES)

    // NOTE: we assume that this Steppingstone loader occupies *part* the first (good) NAND flash block.  More
    // specifically, the loader takes up 4096 bytes (or 8 NAND pages) of the first block.  We'll start our image
    // copy on the very next page.
#define NAND_COPY_PAGE_OFFSET   2*NAND_PAGES_PER_BLOCK

#define LOAD_ADDRESS_PHYSICAL   0x30038000
#define LOAD_SIZE_BYTES         0x00040000
#define LOAD_SIZE_PAGES         (LOAD_SIZE_BYTES / NAND_PAGE_SIZE_BYTES)

#define SIGN_ON "/nWinCE nBoot v1.00 " __DATE__ " " __TIME__ "/r/n"

// Globals variables.
//
ROMHDR * volatile const pTOC = (ROMHDR *)-1;

// Function prototypes.
//
void MMU_EnableICache(void);
void Led_Display(int);
void Port_Init(void);
void ChangeClockDivider(int hdivn, int pdivn);
void ChangeMPllValue(int mdiv, int pdiv, int sdiv);
void NF_Init(void);
int NF_ReadPage(UINT32 block, UINT32 page, volatile BYTE *buffer);

//
typedef void (*PFN_IMAGE_LAUNCH)();

 

/*
    @func   BOOLEAN | SetupCopySection | Copies the IPL image's copy section data (initialized globals) to the correct fix-up location.  Once completed, the IPLs initialized globals are valid.
    @rdesc  TRUE == Success and FALSE == Failure.
    @comm
    @xref
*/
static BOOLEAN SetupCopySection(ROMHDR *const pTOC)
{
    // This code doesn't make use of global variables so there are no copy sections.  To reduce code size, this is a stub function...
    //
    return(TRUE);
}


/*
    @func   void | main | C entrypoint function for the Steppingstone loader.
    @rdesc  None.
    @comm   
    @xref  
*/
void main(void)
{
    register nBlock;
    register nPage;
    register nBadBlocks;
    volatile BYTE *pCopyPtr;
   
    // Set up copy section (initialized globals).
    //
    // NOTE: after this call, globals become valid.
    //
    SetupCopySection(pTOC);

    // Enable the ICache.
    //
    MMU_EnableICache();
   
    // Set up clock and PLL.
    //
    ChangeClockDivider(1, 1);       // 1:2:4.
    ChangeMPllValue(0x5C, 0x4, 0x0);  // Fin=12MHz FCLK=202.8MHz.


    // Set up all GPIO ports.
    //
    Port_Init();

    Uart_Init();
    Uart_SendString(SIGN_ON);

    // Initialize the NAND flash interface.
    //
    NF_Init();

    // Turn the LEDs off.
    //
    Led_Display(LED_OFF);

    // Copy image from NAND flash to RAM.
    //
    pCopyPtr = (BYTE *)LOAD_ADDRESS_PHYSICAL; //指向跳转的地址

    // NOTE: we assume that this Steppingstone loader occupies *part* the first (good) NAND flash block.  More
    // specifically, the loader takes up 4096 bytes (or 8 NAND pages) of the first block.  We'll start our image
    // copy on the very next page.
   
    nBadBlocks = 0;
    for (nPage = NAND_COPY_PAGE_OFFSET ; nPage < (LOAD_SIZE_PAGES + NAND_COPY_PAGE_OFFSET) ; nPage++)
    {
        nBlock = ((nPage / NAND_PAGES_PER_BLOCK) + nBadBlocks);

        if (!NF_ReadPage(nBlock, (nPage % NAND_PAGES_PER_BLOCK), pCopyPtr))
        {
            if ((nPage % NAND_PAGES_PER_BLOCK) != 0)
            {
                Led_Display(0x9);    // real ECC Error.

                // Spin forever...
                while(1)
                {
                }
            }

            // ECC error on a block boundary is (likely) a bad block - retry the page 0 read on the next block.
            nBadBlocks++;
            nPage--;
            continue;
        }

        pCopyPtr += NAND_PAGE_SIZE_BYTES;
    }

    // Turn the LEDs on.
    //
    Led_Display(LED_ON);
 
    // Jump to the image...
    //
    ((PFN_IMAGE_LAUNCH)(LOAD_ADDRESS_PHYSICAL))(); //跳转到EBOOT的起始地址,可以参考BOOT.BIB

}

本文只分析红色部分,其他部分,请大家自己分析了哦。。

#define NAND_BLOCK_SIZE_BYTES   0x00004000
#define NAND_PAGE_SIZE_BYTES    0x00000200
#define NAND_PAGES_PER_BLOCK    (NAND_BLOCK_SIZE_BYTES / NAND_PAGE_SIZE_BYTES)

    // NOTE: we assume that this Steppingstone loader occupies *part* the first (good) NAND flash block.  More
    // specifically, the loader takes up 4096 bytes (or 8 NAND pages) of the first block.  We'll start our image
    // copy on the very next page.
#define NAND_COPY_PAGE_OFFSET   2*NAND_PAGES_PER_BLOCK

#define LOAD_ADDRESS_PHYSICAL   0x30038000
#define LOAD_SIZE_BYTES         0x00040000
#define LOAD_SIZE_PAGES         (LOAD_SIZE_BYTES / NAND_PAGE_SIZE_BYTES)

NAND FLASH的BLOCK0作为BOOT引导。由于NAND FLASH的特性,1BLOCK = 32PAGE = 32X512BYTE=16K。所以NAND_PAGE_SIZE_BYTES被定义为0x200=512。NAND_PAGES_PER_BLOCK的意思是每块有多少页。按着上面的公式算出为32页。NAND_COPY_PAGE_OFFSET=2*NAND_PAGE_PER_BLOCK,为什么要偏移64页呢。。这是因为TOC_BLOCK是被定义在BLOCK2,而NBOOT被定义在BLOCK1,所以需要偏移64页。

LOAD_SIZE_BYTES被定义为256K。这是因为在BOOT.BIB文件中定义滴,见下面的定义:

MEMORY
;   Name     Start     Size      Type
;   -------  --------  --------  ----
    ARGS     80020800  00000800  RESERVED
    BINFS    80021000  00005000  RESERVED
    RAM      80026000  00006000  RAM   
    STACK    8002c000  00004000  RESERVED
    EBOOT    80038000  00040000  RAMIMAGE

看到了吧LOAD_ADDRESS_PHYSICAL=0x30038000,而在Oemaddrtab_cfg.inc中有这样的定义:[红色部分]

;------------------------------------------------------------------------------
;
;  File:  Oemaddrtab_cfg.inc
;
;  This file is used to define g_oalAddressTable. This table is passed to
;  KernelStart to estabilish physical to virtual memory mapping. This table
;  is used also in IOMEM OAL module to map between physical and virtual
;  memory addresses via OALPAtoVA/OALVAtoPA functions.
;
;------------------------------------------------------------------------------

; Export Definition

        EXPORT  g_oalAddressTable[DATA]

;------------------------------------------------------------------------------
;
; TABLE FORMAT
;       cached address, physical address, size
;------------------------------------------------------------------------------

g_oalAddressTable

        DCD     0x80000000, 0x30000000, 64      ; 32 MB DRAM BANK 6
        DCD     0x84000000, 0x10000000, 32      ; nGCS2: PCMCIA/PCCARD
        DCD     0x86000000, 0x18000000, 32      ; 32 MB SROM(SRAM/ROM) BANK 3
        DCD     0x88000000, 0x20000000, 32      ; 32 MB SROM(SRAM/ROM) BANK 4
        DCD     0x8A000000, 0x28000000, 32      ; 32 MB SROM(SRAM/ROM) BANK 5
        DCD     0x8C000000, 0x08000000, 32      ; 32 MB SROM(SRAM/ROM) BANK 1

因此LOAD_ADDRESS_PHYSICAL=0x30038000和0x80038000是指向同一个地址滴。

下面的代码是从NAND FLASH中的BLOCK3开始读取256K的EBOOT程序:

nBadBlocks = 0;
    for (nPage = NAND_COPY_PAGE_OFFSET ; nPage < (LOAD_SIZE_PAGES + NAND_COPY_PAGE_OFFSET) ; nPage++)
    {
        nBlock = ((nPage / NAND_PAGES_PER_BLOCK) + nBadBlocks);

        if (!NF_ReadPage(nBlock, (nPage % NAND_PAGES_PER_BLOCK), pCopyPtr))
        {
            if ((nPage % NAND_PAGES_PER_BLOCK) != 0)
            {
                Led_Display(0x9);    // real ECC Error.

                // Spin forever...
                while(1)
                {
                }
            }

            // ECC error on a block boundary is (likely) a bad block - retry the page 0 read on the next block.
            nBadBlocks++;
            nPage--;
            continue;
        }

        pCopyPtr += NAND_PAGE_SIZE_BYTES;
    }

具体是怎样实现的,请自行分析了哦。嘿嘿。。好累。。去休息去了哦。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值