📄 main.c
字号:
#include <windows.h>
#include <pehdr.h>
#include <romldr.h>
#include "option.h"
#include "s2443ADDR.h"
// Constants.
//
#define MESSAGE_ON TRUE
#define LED_ON 0xa
#define LED_OFF 0x0
#define NAND_BLOCK_SIZE_BYTES (0x00020000) // 1 BLock = 16 KB
#define NAND_PAGE_SIZE_BYTES (512) // 1 Page = 512 Bytes
#define NAND_PAGES_PER_BLOCK (NAND_BLOCK_SIZE_BYTES / NAND_PAGE_SIZE_BYTES) // 32-pages
// 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)
// 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;
volatile DWORD boot_code;
// Set up copy section (initialized globals).
//
// NOTE: after this call, globals become valid.
//
SetupCopySection(pTOC);
// Enable the ICache.
//
MMU_EnableICache();
// Set up all GPIO ports.
//
// TBD - DonGo
//Port_Init();
Uart_Init();
Uart_SendString("\r\n\r\nWince 5.0 Steploader for SMDK2443.\r\n");
// Initialize the NAND flash interface.
//
Uart_SendString("NF_Init...");
NF_Init();
// Turn the LEDs off.
Led_Display(LED_OFF);
//---------------------------------
// Copy image from NAND flash to RAM.
//
pCopyPtr = (BYTE *)LOAD_ADDRESS_PHYSICAL;
#if MESSAGE_ON==1
Uart_SendString("Image copy NAND block from ");
Uart_SendDWORD(NAND_COPY_PAGE_OFFSET/NAND_PAGES_PER_BLOCK,0);
Uart_SendString(" to ");
Uart_SendDWORD((LOAD_SIZE_PAGES + NAND_COPY_PAGE_OFFSET)/NAND_PAGES_PER_BLOCK,1);
Uart_SendString("Download memory address at ");
Uart_SendDWORD(LOAD_ADDRESS_PHYSICAL,1);
#endif
nBadBlocks = 0;
for (nPage = NAND_COPY_PAGE_OFFSET ; nPage < (LOAD_SIZE_PAGES + NAND_COPY_PAGE_OFFSET) ; nPage++)
{
nBlock = ((nPage / NAND_PAGES_PER_BLOCK) + nBadBlocks);
//Uart_SendDWORD(nPage,0);
//Uart_SendString(" ");
if (!NF_ReadPage(nBlock, (nPage % NAND_PAGES_PER_BLOCK), pCopyPtr))
{
//Uart_SendString(hex2char(nBlock));
if ((nPage % NAND_PAGES_PER_BLOCK) != 0)
{
Led_Display(0x9); // real ECC Error.
//Uart_SendString("ECC Error.\r\n");
// 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;
}
//Uart_SendDWORD(*pCopyPtr,0);
//Uart_SendString("\n");
pCopyPtr += NAND_PAGE_SIZE_BYTES;
}
// Turn the LEDs on.
//
Led_Display(0x5);
#if MESSAGE_ON==1
boot_code = *(volatile DWORD *)LOAD_ADDRESS_PHYSICAL;
Uart_SendString("Bboot code : ");
Uart_SendDWORD(boot_code,1);
//-----------------------------
// Jump to the image...
//
Uart_SendString("Now Jump to ");
Uart_SendDWORD(LOAD_ADDRESS_PHYSICAL,1);
#endif
((PFN_IMAGE_LAUNCH)(LOAD_ADDRESS_PHYSICAL))();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -