📄 main.c
字号:
}
if (g_DownloadImage) {
// Configure Ethernet controller.
OALMSG(OAL_FUNC, (TEXT("OEMPlatformInit: mac %x%x%x.\r\n"),
g_MyAddr.wMAC[0], g_MyAddr.wMAC[1], g_MyAddr.wMAC[2]));
if (!OEMEthHardwareInit(&g_MyAddr)) {
OALMSG(OAL_ERROR, (TEXT("ERROR: OEMPlatformInit: Failed to initialize Ethernet controller.\r\n")));
return FALSE;
}
}
else
memcpy(g_pBSPARGS->kitl.mac, g_MyAddr.wMAC, 6);
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: OEMPreDownload
//
// This function is used to determine if download is required and initialise
// the ethernet transport .
//
// Parameters:
// None.
//
// Returns:
// DWORD BL_JUMP - No download needed, jump directly to image
// DWORD BL_DOWNLOAD - download image through the ethernet transport
//
//------------------------------------------------------------------------------
DWORD OEMPreDownload (void)
{
BOOL fGotJumpImg = FALSE;
DWORD DHCPLeaseTime = 0, *pDHCPLeaseTime = &DHCPLeaseTime;
DWORD dwBootFlags = 0;
// Create device name based on Ethernet address
// (this is how Platform Builder identifies this device).
OALKitlCreateName(BSP_DEVICE_PREFIX, g_pBSPARGS->kitl.mac, g_pBSPARGS->deviceId);
OALMSG(OAL_INFO, (L"INFO: *** Device Name '%hs' ***\r\n", g_pBSPARGS->deviceId));
if ((pBootCfg->ConfigFlags & CONFIG_FLAGS_DHCP) == 0) {
// Static IP address.
g_pBSPARGS->kitl.ipAddress = pBootCfg->IPAddr;
g_pBSPARGS->kitl.ipMask = pBootCfg->SubnetMask;
g_pBSPARGS->kitl.flags &= ~OAL_KITL_FLAGS_DHCP;
OALMSG(OAL_FUNC, (TEXT("INFO: Subnet mask is: %s\r\n"), inet_ntoa(g_pBSPARGS->kitl.ipMask)));
OALMSG(OAL_FUNC, (TEXT("INFO: Static IP address: %s\r\n"), inet_ntoa(g_pBSPARGS->kitl.ipAddress)));
} else {
g_pBSPARGS->kitl.ipAddress = 0;
g_pBSPARGS->kitl.ipMask = 0;
g_pBSPARGS->kitl.flags |= OAL_KITL_FLAGS_DHCP;
}
// User wants to launch the image in flash
if (!g_DownloadImage) {
g_bWaitForConnect = FALSE;
fGotJumpImg = TRUE;
} else {
if ((pBootCfg->ConfigFlags & CONFIG_FLAGS_DHCP) == 0)
pDHCPLeaseTime = NULL; // the pDHCPLeaseTime parameter is overloaded.
// NULL indicates static IP
// Initialize the the TFTP transport.
g_MyAddr.dwIP = g_pBSPARGS->kitl.ipAddress;
g_MyAddr.wPort = 0;
if (!EbootInitEtherTransport(&g_MyAddr,
&g_pBSPARGS->kitl.ipMask,
&fGotJumpImg,
pDHCPLeaseTime,
EBOOT_VERSION_MAJOR,
EBOOT_VERSION_MINOR,
BSP_DEVICE_PREFIX,
g_pBSPARGS->deviceId,
EDBG_CPUID,
dwBootFlags))
{
OALMSG(OAL_ERROR, (TEXT("ERROR: OEMPreDownload: Failed to initialize Ethernet connection.\r\n")));
return BL_ERROR;
}
// If the user wanted a DHCP address, we presumably have it now - save it for the OS to use.
if (pBootCfg->ConfigFlags & CONFIG_FLAGS_DHCP) {
// DHCP address.
g_pBSPARGS->kitl.ipAddress = g_MyAddr.dwIP;
}
}
OALMSG(OAL_FUNC, (TEXT("OEMPreDownload: pBSPArgs->kitl.mac = 0x%x%x%x\r\n"),
g_pBSPARGS->kitl.mac[0], g_pBSPARGS->kitl.mac[1], g_pBSPARGS->kitl.mac[2]));
return fGotJumpImg ? BL_JUMP : BL_DOWNLOAD;
}
//------------------------------------------------------------------------------
//
// Function: OEMReadData
//
// This function is used to read data from the ethernet transport. Calls
// EbootEtherReadData from eboot.lib which in turn will call OEMEthGetFrame()
//
// Parameters:
// cbData
// [in] amount of data to be read
// pbData
// [out] pointer to the read buffer store
//
// Returns:
// FALSE on error during downloading
//
//------------------------------------------------------------------------------
BOOL OEMReadData (DWORD cbData, LPBYTE pbData)
{
return EbootEtherReadData(cbData,pbData);
}
//------------------------------------------------------------------------------
//
// Function: OEMShowProgress
//
// This function can be used to show the download progress.
//
// Parameters:
// dwPacketNum
// [in] Currently downloaded packet number
//
// Returns:
// None.
//
//------------------------------------------------------------------------------
void OEMShowProgress (DWORD dwPacketNum)
{
}
//------------------------------------------------------------------------------
//
// Function: OEMLaunch
//
// This function collects post-download connection information from Platform
// Builder and updates the global BSP_ARGS. It jumps to the newly downloaded
// image and should never return.
//
// Parameters:
// dwImageStart
// [in] start address of image to jump to
// dwImageLength
// [in] size of image
// dwLaunchAddr
// [in] launch address of image(virtual).
// pRomHdr
// [in] ptr to ROM HDR area of image
//
// Returns:
// None.
//
//------------------------------------------------------------------------------
void OEMLaunch (DWORD dwImageStart, DWORD dwImageLength,
DWORD dwLaunchAddr, const ROMHDR *pRomHdr)
{
EDBG_OS_CONFIG_DATA *pCfgData;
EDBG_ADDR EshellHostAddr;
EDBG_ADDR DeviceAddr;
DWORD dwPhysLaunchAddr;
BYTE *pMacBytes = (BYTE *) &DeviceAddr.wMAC;
if (g_bWaitForConnect) {
OALMSG(OAL_INFO, (TEXT ("Download successful! Jumping to image at %Xh...\r\n"), dwLaunchAddr));
if (g_DownloadImage && !OEMIsFlashAddr(dwImageStart)) {
memset(&EshellHostAddr, 0, sizeof(EDBG_ADDR));
DeviceAddr.dwIP = g_pBSPARGS->kitl.ipAddress;
memcpy(DeviceAddr.wMAC, g_pBSPARGS->kitl.mac, (3 * sizeof(UINT16)));
DeviceAddr.wPort = 0;
OALMSG(OAL_FUNC, (TEXT ("Calling EbootWaitForHostConnect IP = 0x%x, MAC = %x-%x-%x-%x-%x-%x...\r\n"),
DeviceAddr.dwIP, pMacBytes[0], pMacBytes[1], pMacBytes[2], pMacBytes[3], pMacBytes[4], pMacBytes[5]));
if (!(pCfgData = EbootWaitForHostConnect(&DeviceAddr, &EshellHostAddr))) {
OALMSG(OAL_ERROR, (TEXT("ERROR: OEMLaunch: EbootWaitForHostConnect failed.\r\n")));
SpinForever();
}
OALMSG(OAL_FUNC, (TEXT("Returned from EbootWaitForHostConnect...\r\n")));
// If the user selected "passive" KITL (i.e., don't connect to the target at boot time), set the
// flag in the args structure so the OS image can honor it when it boots.
if (pCfgData->KitlTransport & KTS_PASSIVE_MODE)
g_pBSPARGS->kitl.flags |= OAL_KITL_FLAGS_PASSIVE;
}
// We need to clear RAM if user download new image frm warm-boot
OALMSG(OAL_INFO, (TEXT("Clearing RAM\n\r")));
memset((void*)pRomHdr->ulRAMFree, 0, sizeof(DWORD)*3);
}
// Check whether the launch address is valid,
// if it's not, get last known good address.
if (!dwLaunchAddr)
dwLaunchAddr = pBootCfg->LaunchAddress;
else if (pBootCfg->LaunchAddress != dwLaunchAddr)
// Download address if different with previous one
pBootCfg->LaunchAddress = dwLaunchAddr;
#if NAND_BOOT_SUPPORT
// Write RAM image to NAND if required.
if ((g_DownloadImage == TRUE) && (pBootCfg->ConfigFlags & CONFIG_FLAGS_SAVETOFLASH)
&& (OEMIsFlashAddr(dwLaunchAddr) == FALSE) && (IsNandDevicePresent() == TRUE)) {
if (WriteRegionsToNand(pBootCfg))
OALMSG(OAL_INFO, (TEXT("INFO: OEMLaunch: Stored image to NAND.\r\n")));
else
OALMSG(OAL_ERROR, (TEXT("WARNING: OEMLaunch: Failed to store image to NAND.\r\n")));
}
else
OALMSG(OAL_FUNC, (TEXT("INFO: OEMLaunch: No need to store image to NAND.\r\n")));
DeinitPartitionMgr();
#endif
// Jump to downloaded image (use the physical address since
// we'll be turning the MMU off)...
dwPhysLaunchAddr = (DWORD)OALVAtoPA((void *)dwLaunchAddr);
OALMSG(OAL_INFO, (TEXT("INFO: OEMLaunch: Jumping to Virtual Address 0x%Xh...\r\n\r\n\r\n"), dwLaunchAddr));
Launch(dwPhysLaunchAddr);
// never reached
OALMSG(OAL_ERROR, (TEXT("ERROR: Fatal error in Ethernet Bootloader, halting...\n")));
SpinForever();
}
//------------------------------------------------------------------------------
//
// Function: SpinForever
//
// Light up the LED and halt the system.
//
// Parameters:
// None.
//
// Returns:
// None.
//
//------------------------------------------------------------------------------
void SpinForever(void)
{
OALMSG(OAL_ERROR, (TEXT("Halting system\r\n")));
while(1);
}
//------------------------------------------------------------------------------
//
// PRIVATE FUNCTIONS
//
//------------------------------------------------------------------------------
//
// Function: MainMenu
//
// Manages the bootloader main menu.
//
// Parameters:
// pBootCfg
// [in/out] ptr to bootloader configuration structure
//
// Returns:
// TRUE if image download is required and FALSE otherwise
//
//------------------------------------------------------------------------------
static BOOL MainMenu(BOOT_CFG *pBootCfg)
{
BYTE selection = 0;
BOOL bConfigChanged = FALSE;
BOOL bDownloadImage = FALSE;
while (TRUE) {
selection = 0;
// show menu
EdbgOutputDebugString( "\r\n\r\nEthernet Boot Loader Configuration:\r\n\r\n");
EdbgOutputDebugString( "0) MAC Address: %B:%B:%B:%B:%B:%B\r\n",
g_MyAddr.wMAC[0] & 0xFF, g_MyAddr.wMAC[0] >> 8,
g_MyAddr.wMAC[1] & 0xFF, g_MyAddr.wMAC[1] >> 8,
g_MyAddr.wMAC[2] & 0xFF, g_MyAddr.wMAC[2] >> 8);
EdbgOutputDebugString( "1) Static IP address: %s\r\n",inet_ntoa(pBootCfg->IPAddr));
EdbgOutputDebugString( "2) Static Subnet mask: %s\r\n", inet_ntoa(pBootCfg->SubnetMask));
EdbgOutputDebugString( "3) DHCP: %s\r\n", ((pBootCfg->ConfigFlags & CONFIG_FLAGS_DHCP)? "Enabled":"Disabled"));
EdbgOutputDebugString( "4) Reset to factory default configuration\r\n");
EdbgOutputDebugString( "5) Save current Eboot Configuration\r\n");
EdbgOutputDebugString( "6) AutoBoot: %s", ((pBootCfg->ConfigFlags & CONFIG_FLAGS_AUTOBOOT)? "Enabled":"Disabled\r\n"));
if ((pBootCfg->ConfigFlags & CONFIG_FLAGS_AUTOBOOT)) {
switch (pBootCfg->BootDevice) {
case CONFIG_AUTOBOOT_DEVICE_NOR:
EdbgOutputDebugString(" NOR\r\n");
break;
case CONFIG_AUTOBOOT_DEVICE_NAND:
EdbgOutputDebugString(" NAND\r\n");
break;
default:
EdbgOutputDebugString(" NOR\r\n");
pBootCfg->BootDevice = CONFIG_AUTOBOOT_DEVICE_NOR;
bConfigChanged = TRUE;
break;
}
}
#if NAND_BOOT_SUPPORT
EdbgOutputDebugString( "7) NAND Flash Menu\r\n");
#endif
EdbgOutputDebugString( "D) Download OS or new EBoot image now\r\n");
EdbgOutputDebugString( "L) Launch existing OS Image from NOR Flash\r\n");
EdbgOutputDebugString( "R) Launch existing OS image from RAM\r\n");
EdbgOutputDebugString( "\r\n\r\nEnter your selection: ");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -