📄 main.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Module Name:
main.c
Abstract:
Ethernet boot loader main module. This file contains the C main
for the boot loader. NOTE: The firmware "entry" point (the real
entry point is _EntryPoint in init assembler file.
The Windows CE boot loader is the code that is executed on a Windows CE
development system at power-on reset and loads the Windows CE
operating system. The boot loader also provides code that monitors
the behavior of a Windows CE platform between the time the boot loader
starts running and the time the full operating system debugger is
available. Windows CE OEMs are supplied with sample boot loader code
that runs on a particular development platform and CPU.
Functions:
Notes:
--*/
#include <windows.h>
#include <nkintr.h>
#include <bootarg.h>
#include <pc.h>
#include <ceddk.h>
#include <pehdr.h>
#include <romldr.h>
#include <blcommon.h>
#include "eboot.h"
#include <kitlprot.h>
#include "x86kitl.h"
#include <pci.h>
#define PLATFORM_STRING "CEPC"
#define BOOT_ARG_PTR_LOCATION_NP 0x001FFFFC
#define BOOT_ARG_LOCATION_NP 0x001FFF00
#define ETHDMA_BUFFER_BASE 0x00200000
#define ETHDMA_BUFFER_SIZE 0x00020000
// Can be used to turn on debug zones in eboot.lib and smc9000.lib functions
DWORD EdbgDebugZone;
// FLASH backup support
BOOL g_bDownloadImage = TRUE;
// Multi-XIP
#define FLASH_BIN_START 0 // FLASH Offset.
MultiBINInfo g_BINRegionInfo;
DWORD g_dwMinImageStart;
const OAL_KITL_ETH_DRIVER *g_pEdbgDriver;
USHORT wLocalMAC[3];
BOOL PrintPCIConfig();
// For NAND FLASH
#ifdef NAND_FLASH
#include <fmd.h>
BOOL FlashInit(BOOT_ARGS * pDriverGlobals);
BOOL ReadNANDStoredBootArgs(BOOT_ARGS *pBootArgs);
BOOL WriteNANDStoredBootArgs(BOOT_ARGS * pBootArgs);
BOOL ReadNANDFlash(DWORD dwStartAddr, LPBYTE pBuffer, DWORD dwLength);
BOOL WriteAndVerifyFlash (DWORD dwStartAddr, LPBYTE pData, DWORD dwLength);
BOOL CreateBINFSPartition(DWORD dwStart, DWORD dwLegnth);
BOOL CreateExtendedPartition();
BOOL OEMWriteFlash2 (DWORD dwStartAddr, LPBYTE pData, DWORD dwLength);
#endif
PVOID GetKernelExtPointer(DWORD dwRegionStart, DWORD dwRegionLength);
// file globals
static BOOT_ARGS *pBootArgs; // bootarg pointer
static EDBG_ADDR MyAddr; // CEPC address
static BOOL AskUser (EDBG_ADDR *pMyAddr, DWORD *pdwSubnetMask);
typedef void (*PFN_LAUNCH)();
extern PFN_OEMVERIFYMEMORY g_pOEMVerifyMemory;
DWORD g_dwStartAddr, g_dwLength, g_dwOffset;
void DrawProgress (int Percent, BOOL fBackground);
//
// stub variables to keep linker happy
//
BOOL g_fPostInit;
DWORD CurMSec;
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void
SpinForever(void)
{
KITLOutputDebugString("SpinForever...\r\n");
while(1);
}
//------------------------------------------------------------------------------
//
// Function Name: OEMVerifyMemory (DWORD dwStartAddr, DWORD dwLength)
//
// Description: This function verifies that the passed in memory range
// falls within a valid address. It also sets the global
// Start and Length values - this should be moved elsewhere.
//
//------------------------------------------------------------------------------
BOOL OEMVerifyMemory (DWORD dwStartAddr, DWORD dwLength)
{
BOOL rc; // return code
DWORD Addr1; // starting address
DWORD Addr2; // ending address
// Setup address range for comparison
Addr1 = dwStartAddr;
Addr2 = Addr1 + (dwLength - 1);
KITLOutputDebugString( "****** OEMVerifyMemory Checking Range [ 0x%x ==> 0x%x ]\r\n", Addr1, Addr2 );
// Validate each range
// since we don't have pTOC information yet and we don't know exactly how much memory is on the CEPC,
// We'll just skip the end address testing.
// if( (Addr1 >= RAM_START) && (Addr2 <= RAM_END) )
if (Addr1 >= RAM_START)
{
KITLOutputDebugString("****** RAM Address ****** \r\n\r\n");
rc = TRUE;
}
else
{
KITLOutputDebugString("****** OEMVerifyMemory FAILED - Invalid Memory Area ****** \r\n\r\n");
rc = FALSE;
}
// If the range is verified set the start and length globals
if( rc == TRUE )
{
// Update progress
DrawProgress (100, TRUE);
g_dwStartAddr = dwStartAddr;
g_dwLength = dwLength;
}
// Indicate status
return( rc );
}
BOOL OEMDebugInit (void)
{
// Initialize the monitor port (for development system)
// This should be done first since otherwise we can not
// print any message onto the monitor.
OEMInitDebugSerial();
// Set the pointer to our VerifyMemory routine
g_pOEMVerifyMemory = OEMVerifyMemory;
// Indicate success
return( TRUE );
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL OEMPlatformInit (void)
{
extern void BootUp (void);
PCKITL_NIC_INFO pNicInfo;
KITLOutputDebugString("Microsoft Windows CE Ethernet Bootloader %d.%d for CE/PC (%s)\n",
EBOOT_VERSION_MAJOR,EBOOT_VERSION_MINOR, __DATE__);
// init PCI config mechanism
PCIInitConfigMechanism (1);
//
// Get pointer to Boot Args...
//
pBootArgs = (BOOT_ARGS *) ((ULONG)(*(PBYTE *)BOOT_ARG_PTR_LOCATION_NP));
KITLOutputDebugString("Boot Args @ 0x%x and ucLoaderFlags is %x \r\n", pBootArgs,pBootArgs->ucLoaderFlags);
pBootArgs->dwEBootAddr = (DWORD) BootUp;
#ifdef NAND_FLASH
if (!FlashInit(pBootArgs)) // If we do not find NAND. ignore the backup flag.
pBootArgs->ucLoaderFlags &= ~LDRFL_FLASH_BACKUP;
if ((pBootArgs->ucLoaderFlags & LDRFL_USE_EDBG)==0 &&
(pBootArgs->ucLoaderFlags & LDRFL_FLASH_BACKUP)!=0 ) {
DWORD dwLaunchAddr;
UCHAR ucLoaderFlags=pBootArgs->ucLoaderFlags;
KITLOutputDebugString("No Ethernet Support. Boot From RAM (or Backup)!\r\n");
pBootArgs->ucLoaderFlags |= LDRFL_JUMPIMG;
if ((pBootArgs->ucLoaderFlags & LDRFL_FLASH_BACKUP)!=0 &&
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");
return(FALSE);
}
}
// No EDBG support on this condition.
pBootArgs->ucLoaderFlags &= ~LDRFL_USE_EDBG;
pBootArgs->KitlTransport = KTS_NONE;
KITLOutputDebugString("No Ethernet Support. Jump to %x !\r\n",pBootArgs->dwLaunchAddr);
dwLaunchAddr = pBootArgs->dwLaunchAddr;
((PFN_LAUNCH)(dwLaunchAddr))();
// never reached
SpinForever ();
return TRUE;
}
#endif
pBootArgs->ucLoaderFlags &= LDRFL_FLASH_BACKUP ;
//
// What PCI hardware is available?
//
PrintPCIConfig();
if (EDBG_ADAPTER_DEFAULT == pBootArgs->ucEdbgAdapterType) {
pBootArgs->ucEdbgAdapterType = EDBG_ADAPTER_NE2000;
}
pNicInfo = InitKitlNIC (pBootArgs->ucEdbgIRQ, pBootArgs->dwEdbgBaseAddr, pBootArgs->ucEdbgAdapterType);
if (!pNicInfo) {
KITLOutputDebugString ("Unable to find NIC card, spin forever\r\n");
return FALSE;
}
g_pEdbgDriver = pNicInfo->pDriver;
// update bootarg
pBootArgs->ucEdbgAdapterType = (UCHAR) pNicInfo->dwType;
pBootArgs->ucEdbgIRQ = (UCHAR) pNicInfo->dwIrq;
// special case for RNDIS -- set base to 0 to force USB to scan PCI
pBootArgs->dwEdbgBaseAddr = (EDBG_USB_RNDIS != pNicInfo->dwType)? pNicInfo->dwIoBase : 0;
//
// Initialize NIC DMA buffer, if required.
//
if (g_pEdbgDriver->pfnInitDmaBuffer
&& !g_pEdbgDriver->pfnInitDmaBuffer (ETHDMA_BUFFER_BASE, ETHDMA_BUFFER_SIZE)) {
KITLOutputDebugString("ERROR: Failed to initialize Ethernet controller DMA buffer.\r\n");
return FALSE;
}
// Call driver specific initialization.
//
if (!g_pEdbgDriver->pfnInit ((BYTE *) pBootArgs->dwEdbgBaseAddr, 1, MyAddr.wMAC)) {
KITLOutputDebugString("vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\r\n");
KITLOutputDebugString("---------------------------------------------\r\n");
KITLOutputDebugString(" Failed to initialize Ethernet board!\r\n");
KITLOutputDebugString(" Please check that the Ethernet card is\r\n");
KITLOutputDebugString(" properly installed and configured.\r\n");
KITLOutputDebugString("---------------------------------------------\r\n");
KITLOutputDebugString("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\r\n");
return FALSE;
}
// Specific for Net-Chip Card.
//
if (EDBG_USB_RNDIS == pNicInfo->dwType) { // update Interrupt IRQ info
RndisGetPCICard (&pBootArgs->dwEdbgBaseAddr, &pBootArgs->ucEdbgIRQ);
KITLOutputDebugString(" Rndis BaseAddr=%x,Interrupt = %d !\r\n",pBootArgs->dwEdbgBaseAddr,pBootArgs->ucEdbgIRQ);
}
// Display the MAC address returned by the EDBG driver init function.
//
KITLOutputDebugString("Returned MAC Address:%B:%B:%B:%B:%B:%B\r\n",
MyAddr.wMAC[0] & 0x00FF, MyAddr.wMAC[0] >> 8,
MyAddr.wMAC[1] & 0x00FF, MyAddr.wMAC[1] >> 8,
MyAddr.wMAC[2] & 0x00FF, MyAddr.wMAC[2] >> 8);
return(TRUE);
}
DWORD OEMPreDownload (void)
{
DWORD dwSubnetMask, dwBootFlags = 0;
DWORD DHCPLeaseTime = DEFAULT_DHCP_LEASE, *pDHCPLeaseTime = &DHCPLeaseTime;
char szDeviceName[EDBG_MAX_DEV_NAMELEN], szNameRoot[EDBG_MAX_DEV_NAMELEN];
BOOL fGotJumpImg = FALSE;
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -