📄 main.c
字号:
// set bootloader capability
//
// support passive-kitl
KITLOutputDebugString("OEMPreDownload ucLoaderFlags is %x \r\n",pBootArgs->ucLoaderFlags);
dwBootFlags = EDBG_CAPS_PASSIVEKITL;
// check if this is a cold boot. Force download if so.
if (BOOTARG_SIG != pBootArgs->dwEBootFlag) {
dwBootFlags |= EDBG_BOOTFLAG_FORCE_DOWNLOAD;
}
// Create device name based on Ethernet address
// If a custom device name was specified on the loadcepc command line,
// use it.
//
if ((pBootArgs->dwVersionSig == BOOT_ARG_VERSION_SIG) &&
(pBootArgs->szDeviceNameRoot[0] != '\0'))
{
strncpy(szNameRoot, pBootArgs->szDeviceNameRoot, (sizeof szNameRoot)/(sizeof szNameRoot[0]));
// Ensure that the string is null terminated
szNameRoot[((sizeof szNameRoot)/(sizeof szNameRoot[0])) - 1] = '\0';
}
else
{
strcpy(szNameRoot, PLATFORM_STRING);
if (pBootArgs->dwVersionSig == BOOT_ARG_VERSION_SIG)
strncpy(pBootArgs->szDeviceNameRoot, PLATFORM_STRING, EDBG_MAX_DEV_NAMELEN);
}
x86KitlCreateName (szNameRoot, MyAddr.wMAC, szDeviceName);
KITLOutputDebugString("Using device name: %s\n", szDeviceName);
// Assign a default subnet mask.
dwSubnetMask = ntohl(0xffff0000);
// IP address may have been passed in on loadcepc cmd line
// give user a chance to enter IP address if not
if (!pBootArgs->EdbgAddr.dwIP && AskUser (&MyAddr, &dwSubnetMask)) {
// user entered static IP
pBootArgs->EdbgAddr.dwIP = MyAddr.dwIP;
}
// use the static IP address if we have one
if (pBootArgs->EdbgAddr.dwIP) {
KITLOutputDebugString("Using static IP address: %X\r\n",pBootArgs->EdbgAddr.dwIP);
MyAddr.dwIP = pBootArgs->EdbgAddr.dwIP;
pDHCPLeaseTime = NULL; // Skip DHCP
pBootArgs->EdbgFlags |= EDBG_FLAGS_STATIC_IP;
}
// initialize TFTP transport
if (!EbootInitEtherTransport (&MyAddr, &dwSubnetMask, &fGotJumpImg, pDHCPLeaseTime,
EBOOT_VERSION_MAJOR, EBOOT_VERSION_MINOR, PLATFORM_STRING, szDeviceName, EDBG_CPU_i486, dwBootFlags)) {
return BL_ERROR;
}
// update BOOTARG with the info we got so far
memcpy(&pBootArgs->EdbgAddr,&MyAddr,sizeof(MyAddr));
pBootArgs->ucLoaderFlags |= LDRFL_USE_EDBG | LDRFL_ADDR_VALID | LDRFL_JUMPIMG;
pBootArgs->DHCPLeaseTime = DHCPLeaseTime;
g_bDownloadImage=(fGotJumpImg?FALSE:TRUE);
return fGotJumpImg? BL_JUMP : BL_DOWNLOAD;
}
void OEMLaunch (DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr, const ROMHDR *pRomHdr)
{
EDBG_OS_CONFIG_DATA *pCfgData;
EDBG_ADDR EshellHostAddr;
KITLOutputDebugString("OEMLaunch ucLoaderFlags is %x \r\n",pBootArgs->ucLoaderFlags);
//
if(pBootArgs->ucEdbgAdapterType == EDBG_ADAPTER_DP83815)
{
DP83815Disable(); // we have to turn off the DP83815 free-running state machines before jumping to new image.
}
// Pretend we're 100% done with download
DrawProgress (100, FALSE);
memset (&EshellHostAddr, 0, sizeof (EshellHostAddr));
if (!dwLaunchAddr) {
dwLaunchAddr = pBootArgs->dwLaunchAddr;
} else {
pBootArgs->dwLaunchAddr = dwLaunchAddr;
}
// wait for the jump command from eshell unless user specify jump directly
KITLOutputDebugString ("Download successful! Jumping to image at %Xh...\r\n", dwLaunchAddr);
if (!(pCfgData = EbootWaitForHostConnect (&MyAddr, &EshellHostAddr))) {
KITLOutputDebugString ("EbootWaitForHostConenct failed, spin forever\r\n");
SpinForever();
return;
}
// update service information
if (pCfgData->Flags & EDBG_FL_DBGMSG) {
KITLOutputDebugString("Enabling debug messages over Ethernet, IP: %s, port:%u\n",
inet_ntoa(pCfgData->DbgMsgIPAddr),ntohs(pCfgData->DbgMsgPort));
memcpy(&pBootArgs->DbgHostAddr.wMAC,&EshellHostAddr.wMAC,6);
pBootArgs->DbgHostAddr.dwIP = pCfgData->DbgMsgIPAddr;
pBootArgs->DbgHostAddr.wPort = pCfgData->DbgMsgPort;
}
if (pCfgData->Flags & EDBG_FL_PPSH) {
KITLOutputDebugString("Enabling CESH over Ethernet, IP: %s, port:%u\n",
inet_ntoa(pCfgData->PpshIPAddr),ntohs(pCfgData->PpshPort));
memcpy(&pBootArgs->CeshHostAddr.wMAC,&EshellHostAddr.wMAC,6);
pBootArgs->CeshHostAddr.dwIP = pCfgData->PpshIPAddr;
pBootArgs->CeshHostAddr.wPort = pCfgData->PpshPort;
}
if (pCfgData->Flags & EDBG_FL_KDBG) {
KITLOutputDebugString("Enabling KDBG over Ethernet, IP: %s, port:%u\n",
inet_ntoa(pCfgData->KdbgIPAddr),ntohs(pCfgData->KdbgPort));
memcpy(&pBootArgs->KdbgHostAddr.wMAC,&EshellHostAddr.wMAC,6);
pBootArgs->KdbgHostAddr.dwIP = pCfgData->KdbgIPAddr;
pBootArgs->KdbgHostAddr.wPort = pCfgData->KdbgPort;
}
pBootArgs->ucEshellFlags = pCfgData->Flags;
pBootArgs->dwEBootFlag = BOOTARG_SIG;
pBootArgs->KitlTransport = pCfgData->KitlTransport;
memcpy (&pBootArgs->EshellHostAddr, &EshellHostAddr, sizeof(EDBG_ADDR));
#ifdef NAND_FLASH
// If the user requested a RAM image be stored in flash, do so now. For multiple RAM BIN files, we need to map
// its RAM address to a flash address - the image base address offset in RAM is maintained in flash.
//
KITLOutputDebugString("NAND_FLASH with g_bDownloadImage=%d , pBootArgs->ucLoaderFlags=%x \r\n",
g_bDownloadImage,pBootArgs->ucLoaderFlags);
if (g_bDownloadImage && ((pBootArgs->ucLoaderFlags & LDRFL_FLASH_BACKUP)!=0))
{
BYTE nCount;
DWORD dwFlashAddress;
DWORD dwNumExts;
PXIPCHAIN_SUMMARY pChainInfo = NULL;
EXTENSION *pExt = NULL;
DWORD dwImgStoreAddr=0;
DWORD dwFormatLength = 0;
KITLOutputDebugString("NAND_FLASH do image backup\r\n");
// Look in the kernel regions extension area for a multi-BIN extension descriptor. This region, if found, details the number, start, and size of each XIP region.
for (nCount = 0, dwNumExts = 0 ; (nCount < g_BINRegionInfo.dwNumRegions) && !pChainInfo ; nCount++)
{
// Does this region contain nk.exe and an extension pointer?
if ((pExt = (EXTENSION *)GetKernelExtPointer(g_BINRegionInfo.Region[nCount].dwRegionStart, g_BINRegionInfo.Region[nCount].dwRegionLength)) != NULL)
{
// If there is an extension pointer region, walk it until the end.
while (pExt)
{
DWORD dwBaseAddr = g_BINRegionInfo.Region[nCount].dwRegionStart;
pExt = (EXTENSION *)OEMMapMemAddr(dwBaseAddr, (DWORD)pExt);
if ((pExt->type == 0) && !strcmp(pExt->name, "chain information"))
{
pChainInfo = (PXIPCHAIN_SUMMARY) OEMMapMemAddr(dwBaseAddr, (DWORD)pExt->pdata);
dwNumExts = (pExt->length / sizeof(XIPCHAIN_SUMMARY));
KITLOutputDebugString("Found chain information (pChainInfo=0x%x Extensions=0x%x).\r\n", (DWORD)pChainInfo, dwNumExts);
break;
}
pExt = (EXTENSION *)pExt->pNextExt;
}
}
}
// If we're downloading all the files in a multi-region image, first format the flash and write out logical sector numbers.
if (pChainInfo && dwNumExts == g_BINRegionInfo.dwNumRegions)
{
// Skip the first entry - this is the chain file.
for (nCount = 0, dwFormatLength = 0 ; nCount < dwNumExts ; nCount++)
{
// Handle both cases where the image is built for flash or for RAM.
dwFormatLength += (pChainInfo + nCount)->dwMaxLength;
}
}
else if (dwLaunchAddr) // If we're downloading a single image that contains the kernel (signified by the fact that blcommon gave us a launch address)
{ // then format the flash and write logical sector numbers. Note that we don't want to format flash when downloading a single image of a multi-image build.
dwFormatLength = dwImageLength;
}
if (dwFormatLength)
{
KITLOutputDebugString("Create Partition flash blocks [0x%x through 0x%x] - this is the maximum size of all BIN regions.\r\n",g_dwMinImageStart, g_dwMinImageStart+dwFormatLength);
if (!CreateBINFSPartition(g_dwMinImageStart, dwFormatLength))
{
KITLOutputDebugString("Flash Create Partition failed!\r\n");
return;
}
}
// Are there multiple BIN files in RAM (we may just be updating one in a multi-BIN solution)?
if (g_BINRegionInfo.dwNumRegions)
{
for (nCount = 0 ; nCount < g_BINRegionInfo.dwNumRegions ; nCount++)
{
DWORD dwRegionStart = g_BINRegionInfo.Region[nCount].dwRegionStart;
DWORD dwRegionLength = g_BINRegionInfo.Region[nCount].dwRegionLength;
dwFlashAddress = (dwRegionStart ) + FLASH_BIN_START;
// Remember the kernel's storage address.
if (dwRegionStart == dwImageStart)
dwImgStoreAddr = dwFlashAddress;
if (!OEMWriteFlash2(dwFlashAddress, (UCHAR*)dwRegionStart, dwRegionLength)) {
KITLOutputDebugString("ERROR: failed to store RAM image in flash. Continuing...\r\n");
break;
}
}
}
else if (!OEMWriteFlash2(FLASH_BIN_START, (UCHAR*)dwImageStart, dwImageLength))
{
KITLOutputDebugString("ERROR: failed to store RAM image in flash. Continuing...\r\n");
}
pBootArgs->dwImgStoreAddr=dwImgStoreAddr;
pBootArgs->dwImgLoadAddr=dwImageStart;
pBootArgs->dwImgLength=dwImageLength;
KITLOutputDebugString("StoredBootArgs in NAND. dwImgStoreAddr=%x, dwImageStart=%x, dwImageLength=%x, Continuing...\r\n",
dwImgStoreAddr,dwImageStart,dwImageLength);
if (!WriteNANDStoredBootArgs(pBootArgs)) {
KITLOutputDebugString("ERROR: failed to store StoredBootArgs in NAND. Continuing...\r\n");
}
// Create an extended partition to use rest of flash to mount a filesystem.
if (!CreateExtendedPartition()) {
KITLOutputDebugString("ERROR: failed to create extended partition. Continuing...\r\n");
}
}
else
if ((pBootArgs->ucLoaderFlags & LDRFL_FLASH_BACKUP)!=0 ) {
KITLOutputDebugString("NAND_FLASH do image restore\r\n");
if (ReadNANDStoredBootArgs(pBootArgs)) {
KITLOutputDebugString("Loading (Flash=0x%x RAM=0x%x Length=0x%x) (please wait).", pBootArgs->dwImgStoreAddr, pBootArgs->dwImgLoadAddr, pBootArgs->dwImgLength);
if (!ReadNANDFlash(pBootArgs->dwImgStoreAddr, (LPBYTE)pBootArgs->dwImgLoadAddr, pBootArgs->dwImgLength))
{
KITLOutputDebugString("ERROR: Reading RAM image from flash failed.\r\n");
SpinForever ();
}
dwLaunchAddr=pBootArgs->dwLaunchAddr;
}
else {
KITLOutputDebugString("ERROR: Read StoredBootArgs from NAND.\r\n");
SpinForever ();
}
}
#endif // NAND_FLASH.
KITLOutputDebugString("Lauch Windows CE from address 0x%x\r\n",dwLaunchAddr);
((PFN_LAUNCH)(dwLaunchAddr))();
// never reached
SpinForever ();
}
void
DrawProgress (int Percent, BOOL fBackground)
{
#if DRAW_PROGRESS_BAR
int i, j;
int iWidth = Percent*(pBootArgs->cyDisplayScreen/100);
PWORD pwData;
PDWORD pdwData;
if ((pBootArgs->pvFlatFrameBuffer)) {
// 20 rows high
for (i=0; i < 20; i++) {
switch (pBootArgs->bppScreen) {
case 8 :
memset ((PBYTE)pBootArgs->pvFlatFrameBuffer + pBootArgs->cbScanLineLength*(i+20), fBackground ? 3 : 15,
iWidth);
break;
case 16 :
pwData = (PWORD)(pBootArgs->pvFlatFrameBuffer + pBootArgs->cbScanLineLength*(i+20));
for (j=0; j < iWidth; j++) {
*pwData++ = fBackground ? 0x001f : 0xFFFF;
}
break;
case 32 :
pdwData = (PDWORD)(pBootArgs->pvFlatFrameBuffer + pBootArgs->cbScanLineLength*(i+20));
for (j=0; j < iWidth; j++) {
*pdwData++ = fBackground ? 0x000000FF : 0xFFFFFFFF;
}
break;
default :
// Unsupported format, ignore
break;
}
}
}
#endif // DRAW_PROGRESS_BAR.
}
// callback to receive data from transport
BOOL OEMReadData (DWORD cbData, LPBYTE pbData)
{
BOOL fRetVal;
int cPercent;
if (fRetVal = EbootEtherReadData (cbData, pbData)) {
g_dwOffset += cbData;
if (g_dwLength) {
cPercent = g_dwOffset*100/g_dwLength;
DrawProgress (cPercent, FALSE);
}
}
return fRetVal;
}
//
// Memory mapping related functions
//
LPBYTE OEMMapMemAddr (DWORD dwImageStart, DWORD dwAddr)
{
// map address into physical address
return (LPBYTE) (dwAddr & ~0x80000000);
}
//
// CEPC doesn't have FLASH, LED, stub the related functions
//
void OEMShowProgress (DWORD dwPacketNum)
{
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -