📄 main.c
字号:
//
// Copyright (c) Special Computing. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//------------------------------------------------------------------------------
//
// File: main.c
//
// This file implements main bootloader functions called from blcommon
// library.
//
// For BIN DIO download we are using workaround which allows flash image
// larger than avaiable RAM memory. It depends on exact behavior of
// BLCOMMON library.
//
// Workaround depends on following sequence of call for each BIN record:
// 1 - OEMMapMemAddr, 2 - OEMReadData, 3 - OEMContinueEraseFlash.
// First two calls store BIN record logical address and size. OEMMapMemAddr
// returns each time same buffer address. OEMContinueEraseFlash then write
// received BIN record to flash memory.
//
// Flashing in OEMStartEraseFlash and OEMContinueEraseFlash expect all
// BIN records are sector aligned. This is case for current version of
// image update tools.
//
#include <eboot.h>
#include <kitl_cfg.h>
#include <bsp_nand_cfg.h>
#include <boot_cfg.h>
#include "kerneli2c.h"
#include "bsp.h"
//------------------------------------------------------------------------------
//
// Global: EdbgDebugZone
//
// This variable specifies level of debug ouptup from BLCommon library.
//
ULONG EdbgDebugZone = 0;
//------------------------------------------------------------------------------
//
// Global: g_bootCfg
//
// This global variable is used to save boot configuration. It is read from
// flash memory or initialized to default values if flash memory doesn't
// contain a valid structure. It can be modified by user in bootloader
// configuration menu invoked by BLMenu.
//
BOOT_CFG g_bootCfg;
//------------------------------------------------------------------------------
//
// Global: g_eboot
//
// This global variable is used to save information about downloaded regions.
//
EBOOT_CONTEXT g_eboot;
//------------------------------------------------------------------------------
//
// Global: g_mac
//
// This global variable is used to save information about debug board MAC address.
//
UINT16 g_mac[3];
//------------------------------------------------------------------------------
//
// Global: g_dwBytesRead,g_dwTotalBytes
//
// These global variables are used for download progress update.
//
DWORD g_dwBytesRead = 0;
DWORD g_dwTotalBytes = 0;
//------------------------------------------------------------------------------
//
// Static: g_pTimerRegs
//
OMAP3_GPTIMER_REGS *g_pTimerRegs;
OMAP3_CM_WKUP_REGS *g_pCMRegs;
//------------------------------------------------------------------------------
// External Functions
VOID JumpTo(UINT32 address);
VOID OEMDebugDeinit();
extern BOOL SerialReadData(DWORD size, LPBYTE pData);
extern DWORD SerialWaitForJump(VOID);
extern OAL_ADDRESS_TABLE g_oalAddressTable[];
//------------------------------------------------------------------------------
//
// Function: OEMPlatformInit
//
// This function provide platform initialization functions. It is called
// from boot loader after OEMDebugInit is called. Note that boot loader
// BootloaderMain is called from s/init.s code which is run after reset.
//
BOOL OEMPlatformInit(void)
{
OALMSG(OAL_INFO, (
L"Microsoft Windows CE EBOOT %d.%d for OMAP3 BeagleBoard. "
L"Built %S at %S\r\n",
EBOOT_VERSION_MAJOR, EBOOT_VERSION_MINOR, __DATE__, __TIME__
));
//----------------------------------------------------------------------
// Initialize GP Timer
//----------------------------------------------------------------------
g_pTimerRegs = OALPAtoUA(OMAP3_GPTIMER12_REGS_PA);
g_pCMRegs = OALPAtoUA(OMAP3_CM_WKUP_REGS_PA);
// Soft reset timer module
OUTREG32(&g_pTimerRegs->ulTIOCP, TIOCP_RESET);
// wait
while ((INREG32(&g_pTimerRegs->ulTISTAT) & TISTAT_RESETDONE) == 0);
// Enable global wakeup feature and smart idle
// Set clock activity - FCLK can be switched off, L4 interface clock is maintained during wkup.
SETREG32(&g_pTimerRegs->ulTIOCP, 0x00000214);
// Enable overflow wakeup
SETREG32(&g_pTimerRegs->ulTWER, TWER_OVERFLOW);
// Enabled overflow interrupt
SETREG32(&g_pTimerRegs->ulTISR, TISR_OVERFLOW);
// Set the load register value.(Timer Count is for 37 hours)
OUTREG32(&g_pTimerRegs->ulTLDR, 0);//((32768 * TIMER_PERIOD)/1000)) ); // ~ 4 seconds
// Trigger a counter reload by writing
OUTREG32(&g_pTimerRegs->ulTTGR, 0xFFFFFFFF);
// Start the timer. Also set for auto reload
SETREG32(&g_pTimerRegs->ulTCLR, TLCR_AR | TLCR_ST);
// Enable the interface clocks for the GPT.
SETREG32(&g_pCMRegs->ulICLKEN, CM_WKUP_ICLKEN_EN_GPT12);
OALLog(L"INFO: Platform Init**\r\n");
KERNELI2C_OEMInit();
// Done
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: OEMPreDownload
//
// This function is called before downloading an image. There is place
// where user can be asked about device setup.
//
ULONG OEMPreDownload()
{
ULONG rc = BL_ERROR;
OALLog(L"INFO: Predownload....\r\n");
// We need to support multi bin notify
g_pOEMMultiBINNotify = OEMMultiBinNotify;
g_pOEMVerifyMemory = OEMVerifyMemory;
// Read saved configration
if (
BLReadBootCfg(&g_bootCfg) &&
g_bootCfg.signature == BOOT_CFG_SIGNATURE &&
g_bootCfg.version == BOOT_CFG_VERSION
) {
OALLog(L"INFO: Boot configuration found\r\n");
} else {
OALLog(L"WARN: Boot config wasn't found, using defaults\r\n");
memset(&g_bootCfg, 0, sizeof(g_bootCfg));
g_bootCfg.signature = BOOT_CFG_SIGNATURE;
g_bootCfg.version = BOOT_CFG_VERSION;
g_bootCfg.bootDevLoc.IfcType = Internal;
g_bootCfg.bootDevLoc.BusNumber = 0;
g_bootCfg.bootDevLoc.LogicalLoc = KITL_UART_REGS_PA;
g_bootCfg.kitlDevLoc.IfcType = Internal;
g_bootCfg.kitlDevLoc.BusNumber = 0;
g_bootCfg.kitlDevLoc.LogicalLoc = KITL_UART_REGS_PA;
g_bootCfg.kitlFlags = OAL_KITL_FLAGS_ENABLED|OAL_KITL_FLAGS_POLL;
g_bootCfg.ipAddress = 0;
g_bootCfg.ipMask = 0;
g_bootCfg.ipRoute = 0;
g_bootCfg.cleanhive=1;
}
if (BLReadMAC(&g_bootCfg, &g_mac[0])) {
OALLog(L"INFO: MAC found\r\n");
} else {
OALLog(L"WARN: MAC wasn't found, using defaults\r\n");
g_mac[0]=0x5000;
g_mac[1]=0x27c2;
g_mac[2]=0x421d;
}
// Call configuration menu
BLMenu();
// Image download depend on protocol
g_eboot.bootDeviceType = OALKitlDeviceType(
&g_bootCfg.bootDevLoc, g_bootDevices
);
switch (g_eboot.bootDeviceType) {
case OAL_KITL_TYPE_ETH:
rc = BLEthDownload(&g_bootCfg, g_kitlDevices, g_mac);
break;
case OAL_KITL_TYPE_SERIAL:
rc = BLSerDownload(&g_bootCfg, g_kitlDevices);
break;
case OAL_KITL_TYPE_FLASH:
rc = BLFlashDownload(&g_bootCfg, g_kitlDevices);
break;
}
return rc;
}
//------------------------------------------------------------------------------
//
// Function: OEMLaunch
//
// This function is the last one called by the boot framework and it is
// responsible for to launching the image.
//
VOID OEMLaunch(
ULONG start, ULONG size, ULONG launch, const ROMHDR *pRomHeader
) {
BSP_ARGS *pArgs = OALPAtoCA(IMAGE_SHARE_ARGS_PA);
// Map the LCD pointer to DSS module here.
OALMSG(OAL_FUNC, (
L"+OEMLaunch(0x%08x, 0x%08x, 0x%08x, 0x%08x - %d/%d)\r\n", start, size,
launch, pRomHeader, g_eboot.bootDeviceType, g_eboot.type
));
// Initialize ARGS structure
if (
pArgs->header.signature != OAL_ARGS_SIGNATURE ||
pArgs->header.oalVersion != OAL_ARGS_VERSION ||
pArgs->header.bspVersion != BSP_ARGS_VERSION
) {
memset(pArgs, 0, IMAGE_SHARE_ARGS_SIZE);
pArgs->header.signature = OAL_ARGS_SIGNATURE;
pArgs->header.oalVersion = OAL_ARGS_VERSION;
pArgs->header.bspVersion = BSP_ARGS_VERSION;
pArgs->kitl.flags = g_bootCfg.kitlFlags;
pArgs->kitl.devLoc = g_bootCfg.kitlDevLoc;
pArgs->kitl.ipAddress = g_bootCfg.ipAddress;
pArgs->kitl.ipMask = g_bootCfg.ipMask;
pArgs->kitl.ipRoute = g_bootCfg.ipRoute;
pArgs->kitl.mac[0] = g_mac[0];
pArgs->kitl.mac[1] = g_mac[1];
pArgs->kitl.mac[2] = g_mac[2];
pArgs->imageLaunch = (UINT32)INVALID_HANDLE_VALUE;
pArgs->cleanhive=g_bootCfg.cleanhive;
}
// Depending on protocol there can be some action required
switch (g_eboot.bootDeviceType) {
case OAL_KITL_TYPE_ETH:
BLEthConfig(pArgs);
switch (g_eboot.type) {
case DOWNLOAD_TYPE_BINDIO:
case DOWNLOAD_TYPE_FLASHRAM:
if (BLFlashDownload(&g_bootCfg, g_kitlDevices) != BL_JUMP) {
OALMSG(OAL_ERROR, (L"ERROR: OEMLaunch: "
L"Image load from flash memory failed\r\n"
));
goto cleanUp;
}
launch = g_eboot.launchAddress;
break;
case DOWNLOAD_TYPE_EBOOT:
case DOWNLOAD_TYPE_XLDR:
case DOWNLOAD_TYPE_IPL:
OALMSG(OAL_INFO, (L"INFO: "
L"XLDR/EBOOT/IPL downloaded, spin forever\r\n"
));
while (TRUE);
break;
case DOWNLOAD_TYPE_UNKNOWN:
launch = pArgs->imageLaunch;
break;
default:
launch = (UINT32)OEMMapMemAddr(start, launch);
}
break;
case OAL_KITL_TYPE_SERIAL:
pArgs->kitl.baudRate = CBR_115200;
pArgs->kitl.dataBits = DATABITS_8;
pArgs->kitl.stopBits = ONESTOPBIT;
pArgs->kitl.parity = NOPARITY;
switch (g_eboot.type) {
case DOWNLOAD_TYPE_BINDIO:
case DOWNLOAD_TYPE_FLASHRAM:
if (BLFlashDownload(&g_bootCfg, g_kitlDevices) != BL_JUMP) {
OALMSG(OAL_ERROR, (L"ERROR: OEMLaunch: "
L"Image load from flash memory failed\r\n"
));
goto cleanUp;
}
launch = g_eboot.launchAddress;
break;
case DOWNLOAD_TYPE_EBOOT:
case DOWNLOAD_TYPE_XLDR:
case DOWNLOAD_TYPE_IPL:
OALMSG(OAL_INFO, (L"INFO: "
L"XLDR/EBOOT/IPL downloaded, spin forever\r\n"
));
while (TRUE);
break;
case DOWNLOAD_TYPE_UNKNOWN:
launch = pArgs->imageLaunch;
break;
case DOWNLOAD_TYPE_RAM:
// Wait indefinately for a jump request.
// SerialWaitForJump() returns the debug transport requested by PB.
// Not used.
SerialWaitForJump();
launch = (UINT32)OEMMapMemAddr(start, launch);
break;
default:
launch = (UINT32)OEMMapMemAddr(start, launch);
}
break;
default:
launch = g_eboot.launchAddress;
}
// Check if we get launch address
if (launch == (UINT32)INVALID_HANDLE_VALUE) {
OALMSG(OAL_ERROR, (L"ERROR: OEMLaunch: "
L"Unknown image launch address, spin forever\r\n"
));
while (TRUE);
}
// Save launch address to arguments for reboot
pArgs->imageLaunch = launch;
// Print message, flush caches and jump to image
OALLog(L"INFO: Launch Windows CE by jumping to 0x%08x...\r\n", launch);
OEMDebugDeinit();
JumpTo(launch);
cleanUp:
return;
}
//------------------------------------------------------------------------------
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -