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

📄 cfdisk.c

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

    CFDisk.c

Abstract:
	Implements routines to access a file from an MS-DOS partition.

*/

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

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

volatile PBYTE pATA;

#define	mAtaNormalTimeout			0xFFFFF
#define	mAtaLongTimeout				0xFFFFFFF
#define mCardReadyTimeout			0xFFFFF
#define mCardReadyValidTimeout10us  0x1FFFF

// bit definitions for logicalBlockNumber[3] field
#define mAtaLBAMask				0x0F
#define mAtaDriveSelectMask		(1 << 4)
#define mAtaRequiredBitsMask	(1 << 7) | (1 << 5)
#define mAtaEnableLBAModeMask	(1 << 6)

//

BOOL CFAtaDiskDownload(UINT AtaDiskCmdAddress)
{
	AtaStatus status;
		
	pATA = (volatile PBYTE)AtaDiskCmdAddress;
		
	//EdbgOutputDebugString("pATA[ATA_REG_SECT_CNT]= 0x%X[0x%X] \r\n", pATA, ATA_REG_SECT_CNT);
	//EdbgOutputDebugString("pATA[ATA_REG_SECT_NUM]= 0x%X[0x%X] \r\n", pATA, ATA_REG_SECT_NUM);
	//EdbgOutputDebugString("pATA[ATA_REG_CYL_LOW] = 0x%X[0x%X] \r\n", pATA, ATA_REG_CYL_LOW);
	//EdbgOutputDebugString("pATA[ATA_REG_CYL_HIGH]= 0x%X[0x%X] \r\n", pATA, ATA_REG_CYL_HIGH);
	//EdbgOutputDebugString("pATA[ATA_REG_DRV_HEAD]= 0x%X[0x%X] \r\n", pATA, ATA_REG_DRV_HEAD);
	//EdbgOutputDebugString("pATA[ATA_REG_COMMAND] = 0x%X[0x%X] \r\n", pATA, ATA_REG_COMMAND);

	status = CFWaitForAtaDisk(mAtaWaitForReady, mAtaLongTimeout);
	
	if (status != mAtaOk) 
	{
		EdbgOutputDebugString("Media not present!\r\n");
		return FALSE;
	}
		
	if (!findBootPartition())
    {
    	EdbgOutputDebugString("Partition type is not supported!\r\n");
    	return FALSE;
    }

    if (!processBootRecord())
    {
    	EdbgOutputDebugString("FAT too large!\r\n");
		return FALSE;
	}
	
	
	EdbgOutputDebugString("CFDISK: ATA disk ready\r\n");
	
	if(!CFLoadFile())
	{
		EdbgOutputDebugString("Load from CF ATA Disk failed\r\n");
		return FALSE;
	}
	
	return TRUE;
}



// ATA disk access services
//

static AtaStatus CFWaitForAtaDisk(AtaWaitType type, ULONG timeout)
{
	BYTE status;

//	DumpATARegisters();

	while (timeout > 0)
	{
		status = pATA[ATA_REG_STATUS];
		// EdbgOutputDebugString("CFWaitForAtaDisk: status= %x\r\n", status);

		if (status & ATA_STATUS_BUSY)
		{
			if (type == mAtaWaitForBusy)
				return mAtaOk;
		}
		else
		{
			if (type == mAtaWaitForNotBusy)
				return mAtaOk;
			else
			{
				if (type == mAtaWaitForDataReadyIgnoreErr)
					if (status & ATA_STATUS_DATA_REQ)
						return mAtaOk;

				if (status & ATA_STATUS_ERROR)
					return mAtaIoErr;

				if (type == mAtaWaitForReady)
					if (status & ATA_STATUS_READY)
						return mAtaOk;

				if (type == mAtaWaitForDataReady)
					if (status & ATA_STATUS_DATA_REQ)
						return mAtaOk;
			}
		}

		timeout--;
	}

	return mAtaTimeout;
}


BOOL CFReadSector(int sector, PBYTE ramAddress)
{
	AtaStatus status;

	//EdbgOutputDebugString("CFReadSector: sector %d to %x\r\n", sector, ramAddress);
	
	// abandon when there is no card present
	//
	// Here can insert a verification of card insertion
	
	status = CFReadAtaSector(sector, ramAddress);
	
	if (status != mAtaOk)
	{
		EdbgOutputDebugString("CFReadSector: CFReadATASector error (%x)=%d!\r\n", &status, status);
		return FALSE;
	}
	return TRUE;
}

static 
AtaStatus CFReadAtaSector(DWORD sector, PUCHAR pSectorData)
{
	AtaStatus status;
#if 1  // 16 bits ata data access
	LPWORD pSectorBuffer = (LPWORD) pSectorData;
	LPWORD pATA_DataReg = (LPWORD)pATA;
	DWORD SectorLength = mBytesPerSector/2;
#else // 8 bits ata data access
	LPBYTE pSectorBuffer = (LPBYTE) pSectorData;
	LPBYTE pATA_DataReg = (LPBYTE)pATA;
	DWORD SectorLength = mBytesPerSector;
#endif
	DWORD i;

	// wait for ATA disk to be ready to accept a command
	status = CFWaitForAtaDisk(mAtaWaitForNotBusy, mAtaNormalTimeout);
	if (status != mAtaOk)
		return status;

	// send the read command to read one sector
	pATA[ATA_REG_SECT_CNT] = 1;
	pATA[ATA_REG_SECT_NUM] = (BYTE) (sector        & 0xFF);
	pATA[ATA_REG_CYL_LOW]  = (BYTE)((sector >> 8)  & 0xFF);
	pATA[ATA_REG_CYL_HIGH] = (BYTE)((sector >> 16) & 0xFF);
	pATA[ATA_REG_DRV_HEAD] = (BYTE)((sector >> 24) & 0xFF) | ATA_HEAD_DRIVE_1 | ATA_HEAD_LBA_MODE;
	pATA[ATA_REG_COMMAND] = ATA_CMD_READ;

	// wait for ATA disk to have data ready
	status = CFWaitForAtaDisk(mAtaWaitForDataReady, mAtaNormalTimeout);
	if (status != mAtaOk)
		return status;

	// copy the data
	for (i = 0; i < SectorLength; i++)
	{
		*pSectorBuffer = *pATA_DataReg;
       	//EdbgOutputDebugString("%x ", *pSectorData);
		pSectorBuffer++; 
	}
		//EdbgOutputDebugString("\r\n ");
	return status;
}

//
// 
//
BOOL
CFDisk_Open(PBYTE filename, PBYTE extention)
{
	BYTE fileNameData[mBootfileNameLength + 1];
	BYTE fileExtData[mBootfileExtLength + 1];
	
    FormatDosName(fileNameData, filename, mBootfileNameLength); 
    FormatDosName(fileExtData, extention, mBootfileExtLength); 

	EdbgOutputDebugString("fileNameData = %s!\r\n", fileNameData);
	EdbgOutputDebugString("fileExtData = %s!\r\n", fileExtData);

	if (findBootFile(fileNameData, fileExtData))
		return TRUE;
	return FALSE;
}

void
CFDisk_Read(PBYTE fileAddr, ULONG bytesToRead, PULONG bytesRead)
{
	readBootFile(fileAddr, bytesToRead, bytesRead);
}


// copies s into d, padding it with spaces until d has size characters in total
static void FormatDosName(PBYTE d, PBYTE s, DWORD size)
{
    DWORD i;

    // copy string
    for (i = 0; *s && (i < size); i++)
        d[i] = *s++;

    // append with spaces
    while (i < size)
        d[i++] = ' ';

    // add terminator
    d[i] = 0;
}


static void DumpATARegisters(void)
{
#if 1

	EdbgOutputDebugString("ATA @ %x\n", pATA);
	EdbgOutputDebugString("ATA_REG_DATA     = %x\n", pATA[ATA_REG_DATA]);
	EdbgOutputDebugString("ATA_REG_FEATURE  = %x\n", pATA[ATA_REG_FEATURE]);
	EdbgOutputDebugString("ATA_REG_ERROR    = %x\n", pATA[ATA_REG_ERROR]);
	EdbgOutputDebugString("ATA_REG_SECT_CNT = %x\n", pATA[ATA_REG_SECT_CNT]);
	EdbgOutputDebugString("ATA_REG_SECT_NUM = %x\n", pATA[ATA_REG_SECT_NUM]);
	EdbgOutputDebugString("ATA_REG_CYL_LOW  = %x\n", pATA[ATA_REG_CYL_LOW]);
	EdbgOutputDebugString("ATA_REG_CYL_HIGH = %x\n", pATA[ATA_REG_CYL_HIGH]);
	EdbgOutputDebugString("ATA_REG_DRV_HEAD = %x\n", pATA[ATA_REG_DRV_HEAD]);
	EdbgOutputDebugString("ATA_REG_COMMAND  = %x\n", pATA[ATA_REG_COMMAND]);
#endif

}




⌨️ 快捷键说明

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