📄 main.c
字号:
}
}
// If it's a backspace, back up.
//
else if (InChar == 8)
{
if (cwNumChars > 0)
{
cwNumChars--;
OEMWriteDebugByte((BYTE)InChar);
}
}
}
}
// If it's a carriage return with an empty string, don't change anything.
//
if (cwNumChars)
{
szCount[cwNumChars] = '\0';
pBootCfg->BootDelay = atoi(szCount);
if (pBootCfg->BootDelay > 255)
{
pBootCfg->BootDelay = 255;
}
else if (pBootCfg->BootDelay < 1)
{
pBootCfg->BootDelay = 1;
}
}
}
static ULONG mystrtoul(PUCHAR pStr, UCHAR nBase)
{
UCHAR nPos=0;
BYTE c;
ULONG nVal = 0;
UCHAR nCnt=0;
ULONG n=0;
// fulllibc doesn't implement isctype or iswctype, which are needed by
// strtoul, rather than including coredll code, here's our own simple strtoul.
if (pStr == NULL)
return(0);
for (nPos=0 ; nPos < strlen(pStr) ; nPos++)
{
c = tolower(*(pStr + strlen(pStr) - 1 - nPos));
if (c >= '0' && c <= '9')
c -= '0';
else if (c >= 'a' && c <= 'f')
{
c -= 'a';
c = (0xa + c);
}
for (nCnt = 0, n = 1 ; nCnt < nPos ; nCnt++)
{
n *= nBase;
}
nVal += (n * c);
}
return(nVal);
}
static void CvtMAC(USHORT MacAddr[3], char *pszDottedD )
{
DWORD cBytes;
char *pszLastNum;
int atoi (const char *s);
int i=0;
BYTE *p = (BYTE *)MacAddr;
// Replace the dots with NULL terminators
pszLastNum = pszDottedD;
for(cBytes = 0 ; cBytes < 6 ; cBytes++)
{
while(*pszDottedD != '.' && *pszDottedD != '\0')
{
pszDottedD++;
}
if (pszDottedD == '\0' && cBytes != 5)
{
// zero out the rest of MAC address
while(i++ < 6)
{
*p++ = 0;
}
break;
}
*pszDottedD = '\0';
*p++ = (BYTE)(mystrtoul(pszLastNum, 16) & 0xFF);
i++;
pszLastNum = ++pszDottedD;
}
}
static void SetCS8900MACAddress(PBOOT_CFG pBootCfg)
{
CHAR szDottedD[24];
USHORT cwNumChars = 0;
USHORT InChar = 0;
memset(szDottedD, '0', 24);
EdbgOutputDebugString ( "\r\nEnter new MAC address in hexadecimal (hh.hh.hh.hh.hh.hh): ");
while(!((InChar == 0x0d) || (InChar == 0x0a)))
{
InChar = OEMReadDebugByte();
InChar = tolower(InChar);
if (InChar != OEM_DEBUG_COM_ERROR && InChar != OEM_DEBUG_READ_NODATA)
{
// If it's a hex number or a period, add it to the string.
//
if (InChar == '.' || (InChar >= '0' && InChar <= '9') || (InChar >= 'a' && InChar <= 'f'))
{
if (cwNumChars < 17)
{
szDottedD[cwNumChars++] = (char)InChar;
OEMWriteDebugByte((BYTE)InChar);
}
}
else if (InChar == 8) // If it's a backspace, back up.
{
if (cwNumChars > 0)
{
cwNumChars--;
OEMWriteDebugByte((BYTE)InChar);
}
}
}
}
EdbgOutputDebugString ( "\r\n");
// If it's a carriage return with an empty string, don't change anything.
//
if (cwNumChars)
{
szDottedD[cwNumChars] = '\0';
CvtMAC(pBootCfg->CS8900MAC, szDottedD);
EdbgOutputDebugString("INFO: MAC address set to: %x:%x:%x:%x:%x:%x\r\n",
pBootCfg->CS8900MAC[0] & 0x00FF, pBootCfg->CS8900MAC[0] >> 8,
pBootCfg->CS8900MAC[1] & 0x00FF, pBootCfg->CS8900MAC[1] >> 8,
pBootCfg->CS8900MAC[2] & 0x00FF, pBootCfg->CS8900MAC[2] >> 8);
}
else
{
EdbgOutputDebugString("WARNING: SetCS8900MACAddress: Invalid MAC address.\r\n");
}
}
/*
@func BOOL | MainMenu | Manages the Samsung bootloader main menu.
@rdesc TRUE == Success and FALSE == Failure.
@comm
@xref
*/
static BOOL MainMenu(PBOOT_CFG pBootCfg)
{
BYTE KeySelect = 0;
BOOL bConfigChanged = FALSE;
while(TRUE)
{
KeySelect = 0;
EdbgOutputDebugString ( "\r\nEthernet Boot Loader Configuration:\r\n\r\n");
EdbgOutputDebugString ( "0) IP address: %s\r\n",inet_ntoa(pBootCfg->IPAddr));
EdbgOutputDebugString ( "1) Subnet mask: %s\r\n", inet_ntoa(pBootCfg->SubnetMask));
EdbgOutputDebugString ( "2) DHCP: %s\r\n", (pBootCfg->ConfigFlags & CONFIG_FLAGS_DHCP)?"Enabled":"Disabled");
EdbgOutputDebugString ( "3) Boot delay: %d seconds\r\n", pBootCfg->BootDelay);
EdbgOutputDebugString ( "4) Reset to factory default configuration\r\n");
EdbgOutputDebugString ( "5) Program disk image into SmartMedia card: %s\r\n", (pBootCfg->ConfigFlags & CONFIG_FLAGS_SAVETOFLASH)?"Enabled":"Disabled");
EdbgOutputDebugString ( "6) Program CS8900 MAC address\r\n");
EdbgOutputDebugString ( "7) Low-level format the Smart Media card\r\n");
EdbgOutputDebugString ( "D) Download image now\r\n");
EdbgOutputDebugString ( "\r\nEnter your selection: ");
while (! ( ( (KeySelect >= '0') && (KeySelect <= '7') ) ||
( (KeySelect == 'D') || (KeySelect == 'd') ) ))
{
KeySelect = OEMReadDebugByte();
}
EdbgOutputDebugString ( "%c\r\n", KeySelect);
switch(KeySelect)
{
case '0': // Change IP address.
SetIP(pBootCfg);
bConfigChanged = TRUE;
break;
case '1': // Change subnet mask.
SetMask(pBootCfg);
bConfigChanged = TRUE;
break;
case '2': // Toggle static/DHCP mode.
pBootCfg->ConfigFlags = (pBootCfg->ConfigFlags ^ CONFIG_FLAGS_DHCP);
bConfigChanged = TRUE;
break;
case '3': // Change autoboot delay.
SetDelay(pBootCfg);
bConfigChanged = TRUE;
break;
case '4': // Reset the bootloader configuration to defaults.
ResetBootConfig(pBootCfg);
bConfigChanged = TRUE;
break;
case '5': // Toggle image storage to Smart Media.
pBootCfg->ConfigFlags = (pBootCfg->ConfigFlags ^ CONFIG_FLAGS_SAVETOFLASH);
bConfigChanged = TRUE;
break;
case '6': // Configure Crystal CS8900 MAC address.
SetCS8900MACAddress(pBootCfg);
bConfigChanged = TRUE;
break;
case '7': // Format the Smart Media card.
if (g_bSmartMediaExist && !FormatSmartMedia())
{
RETAILMSG(1, (TEXT("ERROR: Failed to perform low-level format of SmartMedia card.\r\n")));
}
break;
case 'D': // Download? Yes.
case 'd':
goto MENU_DONE;
break;
default:
break;
}
}
MENU_DONE:
// If eboot settings were changed by user, save them to flash.
//
if (bConfigChanged && !WriteBootConfig(pBootCfg))
{
OALMSG(OAL_WARN, (TEXT("WARNING: MainMenu: Failed to store updated bootloader configuration to flash.\r\n")));
}
return(TRUE);
}
/*
@func BOOL | OEMPlatformInit | Initialize the Samsung SMD2410 platform hardware.
@rdesc TRUE = Success, FALSE = Failure.
@comm
@xref
*/
BOOL OEMPlatformInit(void)
{
UINT8 BootDelay;
UINT8 KeySelect;
UINT32 dwStartTime, dwPrevTime, dwCurrTime;
PCI_REG_INFO NANDInfo;
BOOLEAN bResult = FALSE;
OALMSG(OAL_FUNC, (TEXT("+OEMPlatformInit.\r\n")));
EdbgOutputDebugString("Microsoft Windows CE Bootloader for the Samsung SMDK2410 Version %d.%d Built %s\r\n\r\n",
EBOOT_VERSION_MAJOR, EBOOT_VERSION_MINOR, __DATE__);
// Initialize the display.
//
InitDisplay();
// Initialize the RealTimeClock
InitRealTimeClock();
// Initialize the BSP args structure.
//
memset(pBSPArgs, 0, sizeof(BSP_ARGS));
pBSPArgs->header.signature = OAL_ARGS_SIGNATURE;
pBSPArgs->header.oalVersion = OAL_ARGS_VERSION;
pBSPArgs->header.bspVersion = BSP_ARGS_VERSION;
pBSPArgs->kitl.flags = OAL_KITL_FLAGS_ENABLED | OAL_KITL_FLAGS_VMINI;
pBSPArgs->kitl.devLoc.IfcType = Internal;
pBSPArgs->kitl.devLoc.BusNumber = 0;
pBSPArgs->kitl.devLoc.LogicalLoc = BSP_BASE_REG_PA_CS8900A_IOBASE;
// Initialize the AMD AM29LV800 flash code.
//
if (!AM29LV800_Init((UINT32)AMD_FLASH_START))
{
OALMSG(OAL_ERROR, (TEXT("ERROR: OEMPlatformInit: Flash initialization failed.\r\n")));
goto CleanUp;
}
// Initialize the Smart Media flash driver (and partitioning code).
//
memset(&NANDInfo, 0, sizeof(PCI_REG_INFO));
NANDInfo.MemBase.Num = 1;
NANDInfo.MemBase.Reg[0] = (DWORD)OALPAtoVA(S3C2410X_BASE_REG_PA_NAND, FALSE);
if (!FMD_Init(NULL, &NANDInfo, NULL))
{
OALMSG(OAL_WARN, (TEXT("WARNING: OEMPlatformInit: Failed to initialize Smart Media.\r\n")));
g_bSmartMediaExist = FALSE;
}
else
{
g_bSmartMediaExist = TRUE;
}
// Retrieve eboot settings from AMD flash.
//
if (!ReadBootConfig(&g_BootConfig))
{
OALMSG(OAL_ERROR, (TEXT("ERROR: OEMPlatformInit: Failed to retrieve bootloader settings from flash.\r\n")));
goto CleanUp;
}
// Display boot message - user can halt the autoboot by pressing any key on the serial terminal emulator.
//
BootDelay = g_BootConfig.BootDelay;
EdbgOutputDebugString ( "Press [ENTER] to download now or [SPACE] to cancel.\r\n");
EdbgOutputDebugString ( "\r\nInitiating image download in %d seconds. ", BootDelay--);
dwStartTime = OEMEthGetSecs();
dwPrevTime = dwStartTime;
dwCurrTime = dwStartTime;
KeySelect = 0;
// Allow the user to break into the bootloader menu.
//
while((dwCurrTime - dwStartTime) < g_BootConfig.BootDelay)
{
KeySelect = OEMReadDebugByte();
if ((KeySelect == 0x20) || (KeySelect == 0x0d))
break;
dwCurrTime = OEMEthGetSecs();
if (dwCurrTime > dwPrevTime)
{
int i, j;
// 1 Second has elapsed - update the countdown timer.
dwPrevTime = dwCurrTime;
if (BootDelay < 9)
i = 11;
else if (BootDelay < 99)
i = 12;
else if (BootDelay < 999)
i = 13;
for(j = 0; j < i; j++)
OEMWriteDebugByte((BYTE)0x08); // print back space
EdbgOutputDebugString ( "%d seconds. ", BootDelay--);
}
}
EdbgOutputDebugString ( "\r\n");
// Boot or enter bootloader menu.
//
switch(KeySelect)
{
case 0x20: // Boot menu.
MainMenu(&g_BootConfig);
break;
case 0x00: // Fall through if no keys were pressed -or-
case 0x0d: // the user cancelled the countdown.
default:
EdbgOutputDebugString ( "\r\nStarting auto-download ... \r\n");
break;
}
// Configure Ethernet controller.
//
if (!InitEthDevice(&g_BootConfig))
{
OALMSG(OAL_ERROR, (TEXT("ERROR: OEMPlatformInit: Failed to initialize Ethernet controller.\r\n")));
goto CleanUp;
}
bResult = TRUE;
CleanUp:
OALMSG(OAL_FUNC, (TEXT("_OEMPlatformInit.\r\n")));
return(bResult);
}
/*
@func DWORD | OEMPreDownload | Complete pre-download tasks - get IP address, initialize TFTP, etc.
@rdesc BL_DOWNLOAD = Platform Builder is asking us to download an image, BL_JUMP = Platform Builder is requesting we jump to an existing image, BL_ERROR = Failure.
@comm
@xref
*/
DWORD OEMPreDownload(void)
{
BOOL bGotJump = FALSE;
DWORD dwDHCPLeaseTime = 0;
PDWORD pdwDHCPLeaseTime = &dwDHCPLeaseTime;
DWORD dwBootFlags = 0;
// Create device name based on Ethernet address (this is how Platform Builder identifies this device).
//
OALKitlCreateName(BSP_DEVICE_PREFIX, pBSPArgs->kitl.mac, pBSPArgs->deviceId);
OALMSG(TRUE, (L"INFO: *** Device Name '%hs' ***\r\n", pBSPArgs->deviceId));
// If the user wants to use a static IP address, don't request an address
// from a DHCP server. This is done by passing in a NULL for the DHCP
// lease time variable. If user specified a static IP address, use it (don't use DHCP).
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -