⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cfload.c

📁 这个是嵌入式arm系列的一个bootloader程序。对需要编写bootloader的很有参考价值
💻 C
字号:

/*



Module Name:

    CFLoad.c

Abstract:
	Implements the Compact Flash Card Load routine.
	

*/

#include <windows.h>
#include <halether.h>

#include "CFDisk.h"
#include "CFLoad.h"
#include "msdos.h"

#define OUTPUT_CFLOAD_MSGS		0
#define OUTPUT_CFLOAD_VERBOSE_MSGS	0
#define OUTPUT_CFLOAD_VERBOSE_DATA_MSGS	0

// name of file we'll load from the external media (in 8.3 DOS format)
#define CFCardFileNameBase	 "NK "
#define CFCardFileNameExt	 "BIN"

#define BIN_FILE_TYPE 1
#define NB0_FILE_TYPE 2
#define BOOTLOADER		4
#define NKBIN			8
#define FLASHTARGET		16

extern DWORD dwLaunchAddr;
extern DWORD fWriteToFlash;
extern DWORD dwPhysStart;	// image physical starting address
extern DWORD dwPhysLen;	// image physical length
extern DWORD fileType;
extern DWORD dwEBOOT_OFFSET;

static ULONG  BlockChecksum(ULONG BlockStart, ULONG BlockLength);

BYTE	BinSig[7];		// Binary header signature
BYTE	BinStart[4];		// Binary header start
BYTE	BinLength[4];		// Binary header length

/*****************************************************************************
 * 
 *	Procedure: LoadFromCF
 *
 *	Description: Loads a binary (BIN) file from the CF Memory card.
 *
 *	Inputs: None.
 *
 *	Outputs: BOOL.
 *
 *	Notes:
 *			
 *
 *
 *       
 ******************************************************************************/

BOOL CFLoadFile(void)
{
	ULONG	bytesRead;

	if (!CFDisk_Open(CFCardFileNameBase, CFCardFileNameExt))
	{
		EdbgOutputDebugString("File Not Found\r\n");
		return FALSE;
	}

    // Display welcome message
   	EdbgOutputDebugString("Update Start..\r\n");

// Recognize the image type
	CFDisk_Read(BinSig, 7, &bytesRead);
#if (OUTPUT_CFLOAD_MSGS == 1)
	EdbgOutputDebugString("bytesRead = 0x%x\r\n", bytesRead);
#if (OUTPUT_CFLOAD_VERBOSE_MSGS == 1)
	BootGetMemory(((ULONG) BinSig), 7, sizeof(BYTE));
#endif
#endif
	
	if (!(compare(BinSig, "B000FF\x0A",7)))
	{
		EdbgOutputDebugString("Error Kernel Image File.\r\n");	
		return FALSE;
	}
// Recognize the image type

// Read Image start address
	CFDisk_Read(BinStart, 4, &bytesRead);
#if (OUTPUT_CFLOAD_MSGS == 1)
	EdbgOutputDebugString("bytesRead = 0x%x\r\n", bytesRead);
#if (OUTPUT_CFLOAD_VERBOSE_MSGS == 1)
	BootGetMemory(((ULONG) BinStart), 4, sizeof(BYTE));
#endif
#endif

	dwPhysStart = bytesToNum(BinStart, 4);
// Read Image start address
	
// Read Image Length
	CFDisk_Read(BinLength, 4, &bytesRead);
#if (OUTPUT_CFLOAD_MSGS == 1)
	EdbgOutputDebugString("bytesRead = 0x%x\r\n", bytesRead);
#if (OUTPUT_CFLOAD_VERBOSE_MSGS == 1)
	BootGetMemory(((ULONG) BinLength), 4, sizeof(BYTE));
#endif
#endif

	dwPhysLen = bytesToNum(BinLength, 4);
// Read Image Length

	EdbgOutputDebugString("\r\nImage start 0x%X length 0x%X\r\n", dwPhysStart, dwPhysLen );

//	
// Start Download Image
//
{
	
	static DWORD dwRecordAddr;	// starting address of the record
	ULONG	RecStartAddr;
	ULONG	RecLength;
	ULONG	RecChecksum;
	BYTE    RecordInfo[12];
	ULONG 	TotalLength = 0;
	ULONG   RecCount = 0;

	EdbgOutputDebugString("Download RAM Image\r\n");

	// Start to download RAM Image or update flash image.
	if ((dwPhysStart & 0x90000000) == 0x90000000)
	{
		EdbgOutputDebugString("\r\nDownloading NK.BIN for flash target.\r\n");
#if defined ( ORGEBOOT_FLAG )		
		dwPhysStart -= 0x182f3000; // (0x98380000 - 0x8008D000) offset from flash address to SDRAM address
#else
		dwPhysStart -= 0x182c0000; // (0x98380000 - 0x800C0000) offset from flash address to SDRAM address
#endif
		fWriteToFlash = 1;
	}
	
	dwPhysStart |= 0x20000000;
	
	while(1)
	{	
		CFDisk_Read(RecordInfo, 12, &bytesRead);
	  	RecStartAddr = *((ULONG *) RecordInfo);
	  	RecLength = *(((ULONG *) RecordInfo) + 1);
	  	RecChecksum = *(((ULONG *) RecordInfo) + 2);

#if (OUTPUT_CFLOAD_VERBOSE_MSGS == 1)
	  	EdbgOutputDebugString("BodyStartAddr = 0x%x = %d\r\n", RecStartAddr, RecStartAddr);
	  	EdbgOutputDebugString("BodyOffset = 0x%x = %d\r\n", RecLength, RecLength);
	  	EdbgOutputDebugString("BodyChecksum = 0x%x = %d\r\n", RecChecksum, RecChecksum);
#endif

	  	if((RecStartAddr == 0) && (RecChecksum == 0))
	  	{
	  		dwLaunchAddr = (DWORD)RecLength;	// Launch Address
	  		EdbgOutputDebugString("Launch Address = 0x%x\r\n", dwLaunchAddr );
	  		EdbgOutputDebugString("Image Length = 0x%x : Record Counts = 0x%x\r\n", TotalLength,RecCount );
			break;
		}

	  	TotalLength += RecLength;
	  	RecCount++;

	  	if(fWriteToFlash)
	  	{	
#if defined ( ORGEBOOT_FLAG )		
		RecStartAddr -= 0x182f3000; // (0x98380000 - 0x8008D000) offset from flash address to SDRAM address
#else
		RecStartAddr -= 0x182c0000; // (0x98380000 - 0x800C0000) offset from flash address to SDRAM address
#endif
	  	}
	  
	  	RecStartAddr |= 0x20000000;
	  
	  	EdbgOutputDebugString("Record Start = %x , Length = %x\r\n", RecStartAddr , RecLength);
	  	
	  	CFDisk_Read(((PBYTE) RecStartAddr), RecLength, &bytesRead);

#if (OUTPUT_CFLOAD_VERBOSE_MSGS == 1)
	  	BootGetMemory((RecStartAddr), RecLength, sizeof(BYTE));
#endif

	  	if((BlockChecksum(RecStartAddr, RecLength)) != RecChecksum) 
	  	{
			EdbgOutputDebugString("Checksum error\r\n");
			return FALSE;
      	}
   	}
}
//	
// While loop
//
	fileType |= BIN_FILE_TYPE;
	if(fWriteToFlash)
	{
		dwEBOOT_OFFSET = 0x00080000;
		fileType |= FLASHTARGET ;			// File Type
	}
	
	return TRUE;
}

static ULONG
BlockChecksum(ULONG BlockStart, ULONG BlockLength)
{
	ULONG index;
	ULONG theChecksum =0;
	PBYTE pChecksum;

	// Accumulate the Checksum Value
	pChecksum = (PBYTE) BlockStart;
	for (index = 0; index < BlockLength; index++)
	{
		theChecksum += *pChecksum++;
	}
	return theChecksum;
}

//#if (OUTPUT_CFLOAD_VERBOSE_MSG | DBG_READFILE_MSG)
/*****************************************************************************
 * 
 *	Procedure: BootGetMemory
 *
 *	Description: Bootloader Display Memory
 *
 *	Inputs: XXX.
 *
 *	Outputs: BOOL Result - TRUE if passed, FALSE if error.
 *
 *	Notes:
 *
 *	PDL:
 *
 *
 *		Return True.
 *       
 ******************************************************************************/
CHAR
IsPrintable(BYTE dataByte)
{
	return (dataByte < 0x20 || dataByte > 0x7F) ? '.' : (CHAR)dataByte;
}


BOOL
BootGetMemory(ULONG startAddr, ULONG length, BYTE dataSize)
{
	BOOL status = TRUE;
	ULONG dataAddr;
	ULONG index;
	ULONG dataLength;
	CHAR dataString[0x100];
	PCHAR stringPtr;
	
//	EdbgOutputDebugString("BootGetMemory!\r\n");

	dataAddr = startAddr & ~0x0F;
	dataLength = length + startAddr - dataAddr;

	stringPtr = &dataString[0];
	
	//EdbgOutputDebugString("Start Address = 0x%X, length = 0x%x size = %d:\r\n\r\n", startAddr, length, dataSize );

	for (index = 0; index < dataLength; index++)
	{
		if (!(dataAddr & 0x0F))
		{
			EdbgOutputDebugString("0x%X:", dataAddr);
		}
		
		
		switch (dataSize)
		{
			case sizeof(BYTE):
				if (dataAddr < startAddr)
				{
					EdbgOutputDebugString("   ");
					*stringPtr++ = ' ';
				}
				else
				{
					EdbgOutputDebugString(" %B", *((PBYTE) dataAddr));
					*stringPtr++ = IsPrintable(*((PBYTE) dataAddr));
				}
				break;
			case sizeof(WORD):
				if (dataAddr < startAddr)
				{
					EdbgOutputDebugString("     ");
					*stringPtr++ = ' ';
					*stringPtr++ = ' ';
				}
				else
				{
					EdbgOutputDebugString(" %H", *((PWORD) dataAddr));
					*stringPtr++ = IsPrintable(*((PBYTE) dataAddr));
					*stringPtr++ = IsPrintable(*((PBYTE) (dataAddr + 1)));
				}
				break;
			case sizeof(DWORD):
				if (dataAddr < startAddr)
				{
					EdbgOutputDebugString("         ");
					*stringPtr++ = ' ';
					*stringPtr++ = ' ';
					*stringPtr++ = ' ';
					*stringPtr++ = ' ';
				}
				else
				{
					EdbgOutputDebugString(" %X", *((PDWORD) dataAddr));
					*stringPtr++ = IsPrintable(*((PBYTE) dataAddr));
					*stringPtr++ = IsPrintable(*((PBYTE) (dataAddr + 1)));
					*stringPtr++ = IsPrintable(*((PBYTE) (dataAddr + 2)));
					*stringPtr++ = IsPrintable(*((PBYTE) (dataAddr + 3)));
				}
				break;
			default:
				break;
		}

		dataAddr += dataSize;

		if (!(dataAddr & 0x0F))
		{
			*stringPtr = (CHAR)NULL;
			EdbgOutputDebugString(" %s\r\n", dataString);
			stringPtr = &dataString[0];
			
	
		}

	}

	if ((dataAddr & 0x0F))
	{
		*stringPtr = (CHAR)NULL;
		EdbgOutputDebugString(" %s\r\n", dataString);
	}

	return status;
}

BOOL
BootSetMemory(ULONG startAddr, ULONG dataValue, ULONG length, BYTE dataSize)
{
	BOOL status = TRUE;
	ULONG dataAddr = startAddr;
	ULONG index;

	//EdbgOutputDebugString("BootSetMemory!\r\n");
	//EdbgOutputDebugString("Start Address = 0x%X, Value = 0x%x, length = 0x%x, size = %d:\r\n\r\n", startAddr, dataValue, length, dataSize );
	for (index = 0; index < length; index++)
	{
		switch (dataSize)
		{
			case sizeof(BYTE):
				*((PBYTE) dataAddr) = (BYTE) dataValue;
				break;

			case sizeof(WORD):
				*((PWORD) dataAddr) = (WORD) dataValue;
				break;

			case sizeof(DWORD):
				*((PDWORD) dataAddr) = (DWORD) dataValue;
				break;

			default:
				break;
		}

		dataAddr += dataSize;
	}

	return status;
}

//#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -