📄 main.c
字号:
//
if (!(g_BootConfig.ConfigFlags & CONFIG_FLAGS_DHCP))
{
// Static IP address.
pBSPArgs->kitl.ipAddress = g_BootConfig.IPAddr;
pBSPArgs->kitl.ipMask = g_BootConfig.SubnetMask;
pBSPArgs->kitl.flags &= ~OAL_KITL_FLAGS_DHCP;
pdwDHCPLeaseTime = NULL;
OALMSG(TRUE, (TEXT("INFO: Using static IP address %s.\r\n"), inet_ntoa(pBSPArgs->kitl.ipAddress)));
OALMSG(TRUE, (TEXT("INFO: Using subnet mask %s.\r\n"), inet_ntoa(pBSPArgs->kitl.ipMask)));
}
else
{
pBSPArgs->kitl.ipAddress = 0;
pBSPArgs->kitl.ipMask = 0;
}
// Initialize the the TFTP transport.
//
g_DeviceAddr.dwIP = pBSPArgs->kitl.ipAddress;
memcpy(g_DeviceAddr.wMAC, pBSPArgs->kitl.mac, (3 * sizeof(UINT16)));
g_DeviceAddr.wPort = 0;
if (!EbootInitEtherTransport(&g_DeviceAddr,
&pBSPArgs->kitl.ipMask,
&bGotJump,
pdwDHCPLeaseTime,
EBOOT_VERSION_MAJOR,
EBOOT_VERSION_MINOR,
BSP_DEVICE_PREFIX,
pBSPArgs->deviceId,
EDBG_CPU_ARM720,
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 (g_BootConfig.ConfigFlags & CONFIG_FLAGS_DHCP)
{
// DHCP address.
pBSPArgs->kitl.ipAddress = g_DeviceAddr.dwIP;
pBSPArgs->kitl.flags |= OAL_KITL_FLAGS_DHCP;
}
return(bGotJump ? BL_JUMP : BL_DOWNLOAD);
}
/*
@func BOOL | OEMReadData | Generically read download data (abstracts actual transport read call).
@rdesc TRUE = Success, FALSE = Failure.
@comm
@xref
*/
BOOL OEMReadData(DWORD dwData, PUCHAR pData)
{
return(EbootEtherReadData(dwData, pData));
}
/*
@func void | OEMShowProgress | Displays download progress for the user.
@rdesc N/A.
@comm
@xref
*/
void OEMShowProgress(DWORD dwPacketNum)
{
}
/*
@func void | OEMLaunch | Executes the stored/downloaded image.
@rdesc N/A.
@comm
@xref
*/
void OEMLaunch( DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr, const ROMHDR *pRomHdr )
{
DWORD dwPhysLaunchAddr;
EDBG_OS_CONFIG_DATA *pCfgData;
EDBG_ADDR EshellHostAddr;
EDBG_ADDR DeviceAddr;
// If the user requested that a disk image (stored in RAM now) be written to the SmartMedia card, so it now.
//
if (g_BootConfig.ConfigFlags & CONFIG_FLAGS_SAVETOFLASH)
{
// Since this platform only supports RAM images, the image cache address is the same as the image RAM address.
//
if (!WriteDiskImageToSmartMedia(dwImageStart, dwImageLength, &g_BootConfig))
{
OALMSG(OAL_ERROR, (TEXT("ERROR: OEMLaunch: Failed to store image to Smart Media.\r\n")));
goto CleanUp;
}
// Store the bootloader settings to flash.
//
// TODO: minimize flash writes.
//
if (!WriteBootConfig(&g_BootConfig))
{
OALMSG(OAL_ERROR, (TEXT("ERROR: OEMLaunch: Failed to store bootloader settings to flash.\r\n")));
goto CleanUp;
}
OALMSG(TRUE, (TEXT("INFO: Disk image stored to Smart Media. Please Reboot. Halting...\r\n")));
while(1)
{
// Wait...
}
}
// Wait for Platform Builder to connect after the download and send us IP and port settings for service
// connections - also sends us KITL flags. This information is used later by the OS (KITL).
//
if (g_bWaitForConnect)
{
memset(&EshellHostAddr, 0, sizeof(EDBG_ADDR));
DeviceAddr.dwIP = pBSPArgs->kitl.ipAddress;
memcpy(DeviceAddr.wMAC, pBSPArgs->kitl.mac, (3 * sizeof(UINT16)));
DeviceAddr.wPort = 0;
if (!(pCfgData = EbootWaitForHostConnect(&DeviceAddr, &EshellHostAddr)))
{
OALMSG(OAL_ERROR, (TEXT("ERROR: OEMLaunch: EbootWaitForHostConnect failed.\r\n")));
goto CleanUp;
}
// 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)
{
pBSPArgs->kitl.flags |= OAL_KITL_FLAGS_PASSIVE;
}
}
// If a launch address was provided, we must have downloaded the image, save the address in case we
// want to jump to this image next time. If no launch address was provided, retrieve the last one.
//
if (dwLaunchAddr)
{
g_BootConfig.LaunchAddress = dwLaunchAddr;
}
else
{
dwLaunchAddr = g_BootConfig.LaunchAddress;
}
// Save bootloader settings in flash.
//
// TODO: minimize flash writes.
//
if (!WriteBootConfig(&g_BootConfig))
{
OALMSG(OAL_ERROR, (TEXT("ERROR: OEMLaunch: Failed to store bootloader settings in flash.\r\n")));
goto CleanUp;
}
// Jump to downloaded image (use the physical address since we'll be turning the MMU off)...
//
dwPhysLaunchAddr = (DWORD)OALVAtoPA((void *)dwLaunchAddr);
OALMSG(TRUE, (TEXT("INFO: OEMLaunch: Jumping to Physical Address 0x%Xh (Virtual Address 0x%Xh)...\r\n\r\n\r\n"), dwPhysLaunchAddr, dwLaunchAddr));
// Jump...
//
Launch(dwPhysLaunchAddr);
CleanUp:
OALMSG(TRUE, (TEXT("ERROR: OEMLaunch: Halting...\r\n")));
SpinForever();
}
//------------------------------------------------------------------------------
//
// Function Name: OEMVerifyMemory( DWORD dwStartAddr, DWORD dwLength )
// Description..: This function verifies the passed address range lies
// within a valid region of memory. Additionally this function
// sets the g_ImageType if the image is a boot loader.
// Inputs.......: DWORD Memory start address
// DWORD Memory length
// Outputs......: BOOL - true if verified, false otherwise
//
//------------------------------------------------------------------------------
BOOL OEMVerifyMemory( DWORD dwStartAddr, DWORD dwLength )
{
BOOL rc; // return code
DWORD Addr1; // starting address
DWORD Addr2; // ending address
// Convert address to a cached address.
//
dwStartAddr &= ~CACHED_TO_UNCACHED_OFFSET;
// Setup address range for comparison
//
Addr1 = dwStartAddr;
Addr2 = Addr1 + (dwLength - 1);
EdbgOutputDebugString( "****** OEMVerifyMemory Checking Range [ 0x%x ==> 0x%x ]\r\n", Addr1, Addr2 );
// Validate the bootloader range to set the g_ImageType. The bootloader address
// range is a subset of the whole flash range. This is required as the original
// function set the image type based on this. Therefore this check is done before
// the whole FLASH range is checked.
if( (Addr1 >= FLASH_EBOOT_START) && (Addr2 <= FLASH_EBOOT_END) )
{
EdbgOutputDebugString("****** bootloader address ****** \r\n\r\n");
// Set the image type
g_ImageType = IMAGE_LOADER;
rc = TRUE;
}
else if( (Addr1 >= FLASH_START) && (Addr1 <= FLASH_END) )
{
EdbgOutputDebugString("****** FLASH address ****** \r\n\r\n");
rc = TRUE;
}
else if( (Addr1 >= RAM_START) && (Addr2 <= RAM_END ) )
{
EdbgOutputDebugString("****** RAM address ****** \r\n\r\n");
rc = TRUE;
}
else
{
EdbgOutputDebugString("****** OEMVerifyMemory FAILED - Invalid Memory Area ****** \r\n\r\n");
rc = FALSE;
}
// Indicate status
return( rc );
}
/////////////////////// START - Stubbed functions - START //////////////////////////////
/*
@func void | SC_WriteDebugLED | Write to debug LED.
@rdesc N/A.
@comm
@xref
*/
void SC_WriteDebugLED(USHORT wIndex, ULONG dwPattern)
{
// Stub - needed by NE2000 EDBG driver...
//
}
ULONG HalSetBusDataByOffset(IN BUS_DATA_TYPE BusDataType,
IN ULONG BusNumber,
IN ULONG SlotNumber,
IN PVOID Buffer,
IN ULONG Offset,
IN ULONG Length)
{
return(0);
}
ULONG
HalGetBusDataByOffset(IN BUS_DATA_TYPE BusDataType,
IN ULONG BusNumber,
IN ULONG SlotNumber,
IN PVOID Buffer,
IN ULONG Offset,
IN ULONG Length)
{
return(0);
}
BOOLEAN HalTranslateBusAddress(IN INTERFACE_TYPE InterfaceType,
IN ULONG BusNumber,
IN PHYSICAL_ADDRESS BusAddress,
IN OUT PULONG AddressSpace,
OUT PPHYSICAL_ADDRESS TranslatedAddress)
{
// All accesses on this platform are memory accesses...
//
if (AddressSpace)
*AddressSpace = 0;
// 1:1 mapping...
//
if (TranslatedAddress)
{
*TranslatedAddress = BusAddress;
return(TRUE);
}
return(FALSE);
}
PVOID MmMapIoSpace(IN PHYSICAL_ADDRESS PhysicalAddress,
IN ULONG NumberOfBytes,
IN BOOLEAN CacheEnable)
{
DWORD dwAddr = PhysicalAddress.LowPart;
if (CacheEnable)
dwAddr &= ~CACHED_TO_UNCACHED_OFFSET;
else
dwAddr |= CACHED_TO_UNCACHED_OFFSET;
return((PVOID)dwAddr);
}
VOID MmUnmapIoSpace(IN PVOID BaseAddress,
IN ULONG NumberOfBytes)
{
}
VOID WINAPI SetLastError(DWORD dwErrCode)
{
}
/////////////////////// END - Stubbed functions - END //////////////////////////////
/*
@func void | OEMDownloadFileNotify | Receives/processes download file manifest.
@rdesc None.
@comm
@xref
*/
void OEMDownloadFileNotify(PDownloadManifest pInfo)
{
DWORD dwCount;
DWORD dwNumNB0Files = 0;
if (!pInfo) return;
EdbgOutputDebugString("\r\nDownload file information:\r\n");
EdbgOutputDebugString("-------------------------------------------------------------------------------\r\n");
for (dwCount = 0 ; dwCount < pInfo->dwNumRegions ; dwCount++)
{
EdbgOutputDebugString("[%d]: Address=0x%x Length=0x%x Name=%s\r\n", dwCount,
pInfo->Region[dwCount].dwRegionStart,
pInfo->Region[dwCount].dwRegionLength,
pInfo->Region[dwCount].szFileName);
// .nb0 files will have a start address of 0 because Platform Builder
// won't know where to place them. We'll support only one .nb0 file
// download (this is an Image Update disk image). If we need to
// support more than one .nb0 file download in the future, we'll need
// to differentiate them by filename.
//
if (pInfo->Region[dwCount].dwRegionStart == 0)
{
// We only support one raw binary file (disk image).
if (dwNumNB0Files++)
{
EdbgOutputDebugString("ERROR: This bootloader doesn't support downloading a second .nb0 binary image.\r\n");
SpinForever();
}
// The disk image .nb0 file should be placed immediately after the
// bootloader image in flash.
pInfo->Region[dwCount].dwRegionStart = 0x80001000;
EdbgOutputDebugString("INFO: Changed start address for %s to 0x%x.\r\n", pInfo->Region[dwCount].szFileName,
pInfo->Region[dwCount].dwRegionStart);
}
}
EdbgOutputDebugString("\r\n");
return;
}
/*
@func BOOL | OEMDebugInit | Initializes the serial port for debug output message.
@rdesc TRUE == Success and FALSE == Failure.
@comm
@xref
*/
BOOL OEMDebugInit(void)
{
// Set up function callbacks used by blcommon.
//
g_pOEMVerifyMemory = OEMVerifyMemory; // Verify RAM.
g_pOEMMultiBINNotify = OEMDownloadFileNotify;
// Call serial initialization routine (shared with the OAL).
//
OEMInitDebugSerial();
return(TRUE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -