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

📄 id2_hd.c

📁 小型操作系统,以VC为开发环境,需要boachs调试
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************
**     File name   : id2_hd.c
**     Author      : x.cheng
**     Create date :
**
**	   Comment:
**			This is the low-level hd interrupt support.
**
**     Revisions: 
**     $Log: id2_hd.c,v $
**     Revision 1.7  2005/08/19 14:57:31  x.cheng
**     bug fix, real harddisk parameter fetch.
**
**     Revision 1.6  2005/08/11 14:41:14  x.cheng
**     ide channel 1 supurted
**
**     Revision 1.5  2005/08/09 16:10:50  x.cheng
**     when irq, call a read and write funcion in this file
**
**     Revision 1.4  2005/08/05 15:03:36  x.cheng
**     new funciton pstId2GetPartitonInfo() added
**
**     Revision 1.3  2005/08/02 15:37:02  x.cheng
**     更改了硬盘命令处理方法,增加了一个setup函数,给fs用的
**
**     Revision 1.2  2005/07/27 15:59:56  x.cheng
**     hard diskp request handle function added
**
**     Revision 1.1.1.1  2005/07/27 06:53:15  x.cheng
**     add into repositories
**
**
***************************************************************************/

#include "const.h"
#include "type.h"
#include "stdarg.h"

#define __IDE_HD_SRC__ 
#include "..\..\Inc\i386\io.h"
#include "..\..\Inc\i386\system.h"
#include "..\..\Inc\i386\x86.h"
#include "..\..\Inc\i386\page.h"
#include "..\..\Inc\tui.h"
#include "..\..\Inc\ide.h"
#include "..\..\Inc\delay.h"
#include "..\..\Inc\debug.h"

#include "..\inc\def_hd.h"
#include "..\inc\def_ata.h"
#include "..\inc\def_ide.h"

/* debug preprocessor instrument
	#ifdef _DEBUG__
	#ifdef _DEBUG_IDE__
				
	#endif
	#endif	
***************************/

/*************global variable******************/
	//-------------------------------------------
	// The request-struct contains all necessary data
	// to load a nr of sectors into memory
extern ts_IdeRequest g_astRequest[MAX_REQUEST_NR];
	//-------------------------------------------
	// used to wait on when there are no free requests
extern ts_Task* g_pstWaitForRequest;
	//-------------------------------------------
extern ts_IdeDevice g_astDevice[IDE_DEVICE_NR];

/*************取setup.asm设置的硬盘数据**************/
#define HARDDISK_INFO (ts_HardDiskInfo *)PHYSICAL(0x90080)

/*************global variable******************/
ts_HardDiskInfo g_stHardDiskInfo;		/* 记录硬盘信息得全局变量,目前只支持一个硬盘*/
ts_PartitionInfo g_astPartitionInfo[5];	/*记录硬盘分区信息的全局变量,
								目前最多支持4分区, 第一个存放的是硬盘信息*/
static unsigned char g_ucCurrentPartition=1;			/*  see ? up? */

struct PartitionType_Struct{
	unsigned char ucType;
	char *pszName;
}g_astPartitionType[8] = {
	{0x01, "DOS 12-bit FAT"},
	{0x04, "DOS 16-bit FAT <32M"},		/* Primary DOS with 16-bit FAT */
	{0x06, "DOS 16-bit FAT >=32M"},
    {0x0b, "Microsoft Windows FAT32"},
    {0x0c, "Windows FAT32 (lba)"},

	{0x0d, "Windows FAT16(lba)"},
	{0x83, "Linux native:Ext2 Fs"},
	{0x0, "Unknown Partition"}
};

/************local function prototype**************/
static char *szId2PartitionInfo(unsigned char ucType);
static void LBAtoCHS(unsigned long ulBlock, unsigned short* puiCylinder, unsigned char* pucHead, unsigned char* pucStartSector);
static void Id2SendCmdLBA(unsigned char ucCmd, unsigned long ulLSN, 
							 unsigned char ucRWSectors, unsigned char *pucBuffer);
static void Id2SendCmd(unsigned char ucCmd, unsigned short uiCylinder, unsigned char ucHead, unsigned char ucStartSector,
						unsigned char ucSectors);

int iFuck=0;
/************************************************************
*************************************************************
**      Function Name:			vDoHdRequest
**      Author:                 x.cheng
**
**      Comment:
**			每次ide控制器(硬盘)中断会调用这个函数,由IdeAddRequest()
**		 第一次调用激活处理流程。
**
**      List of parameters:
**			no
**
**      Return value:   
**          no
**
**      Revisions:
**
*************************************************************
*************************************************************/
void vDoHdRequest(void)
{
	ts_IdeRequest* pstCurrent;

	if ( !(pstCurrent=g_astDevice[IDE_DEVICE_HD].pstCurrentRequest) ) {
#ifdef _DEBUG__
#ifdef _DEBUG_IDE__
		kprintf("\n%s:%s:%d line, no request...\n", __FILE__,__FUNCTION__,__LINE__);
#endif
#endif
		return;
	}
			
	if (pstCurrent->ucCmd == IDE_READ_BLK) {
#ifdef _DEBUG__
#ifdef _DEBUG_IDE__
		POSITION1("handle a read request....\n");
#endif
#endif
		//由IdeAddRequest()调用
		Id2SendCmdLBA(WIN_READ, pstCurrent->ulStartOfSector, pstCurrent->ulNumOfSectors, pstCurrent->pucBuffer);
		//may wait a moment...
		DELAY400NS();
//		while ( iId5WaitIdeStatus(IDE_CHANNEL_0, BUSY_STATUS, 0) ) ;
//		Delay(DELAY*100);
//		kprintf("begin request read....\n");
//		iFuck = 1;
//		iId2ReadHdData(pstCurrent);
//		kprintf("end request read....\n");
//		POSITION();
//		HexDump(pstCurrent->pucBuffer+500, 12);
//		for(;;);
	} else if (pstCurrent->ucCmd == IDE_WRITE_BLK){
#ifdef _DEBUG__
#ifdef _DEBUG_IDE__
		kprintf("handle a write request....\n");
#endif
#endif
		//由IdeAddRequest()调用
		Id2SendCmdLBA(WIN_WRITE, pstCurrent->ulStartOfSector, pstCurrent->ulNumOfSectors, pstCurrent->pucBuffer);
		while ( iId5WaitIdeStatus(IDE_CHANNEL_0, BUSY_STATUS, 0) ) ;
	} else {
#ifdef _DEBUG__
#ifdef _DEBUG_IDE__
		kprintf("unexpected request....\n");
#endif
#endif
	}

	return;
}

/************************************************************
*************************************************************
**      Function Name:			iId2ReadHdData
**      Author:                 x.cheng
**
**      Comment:
**			
**
**      List of parameters:
**			pstRequest - 
**
**      Return value:   
**          no
**
**      Revisions:
**
*************************************************************
*************************************************************/
int iId2ReadHdData(ts_IdeRequest* pstRequest)
{
	//由中断调用,注意,一次中断只有一个扇区的数据(512bytes)
	ReadPortString(ATA_PRIMARY_DATA, pstRequest->pucBuffer, SECTOR_SIZE); 

	if ( iFuck == 1)
		HexDump(&pstRequest->pucBuffer[500], 12);
	pstRequest->ucError = 0;
	pstRequest->ulStartOfSector ++;
	pstRequest->pucBuffer += SECTOR_SIZE;
	if (-- pstRequest->ulNumOfSectors) {
#ifdef _DEBUG__
#ifdef _DEBUG_IDE__
		POSITION1("go on for read request\n");
#endif
#endif
		return 0;
	}

	return (-1);
}

/************************************************************
*************************************************************
**      Function Name:			Id2HardDiskSetup
**      Author:                 x.cheng
**
**      Comment:
**			设置硬盘的分区信息以及其他配置信息,
**
**      List of parameters:
**			no
**
**      Return value:   
**          no
**
**      Revisions:
**
*************************************************************
*************************************************************/
void Id2HardDiskSetup(void)
{
	unsigned long ulSectors;
	unsigned long ulSize;
	ts_BufferBlock *pstBlock;
	unsigned char* pucBuffer;
	int i;

//#ifndef _BOCH_EMU__
#if(0)
	g_stHardDiskInfo.uiCylinders	= *(unsigned short *)HARDDISK_INFO;
	g_stHardDiskInfo.ucHeads		= *(unsigned char *)(HARDDISK_INFO+2);
	g_stHardDiskInfo.uiCompensatePreWrites	= *(unsigned short *)(HARDDISK_INFO+5);
	g_stHardDiskInfo.ucCtrlByte		= *(unsigned short *)(HARDDISK_INFO+8);
	g_stHardDiskInfo.uiZones		= *(unsigned short *)(HARDDISK_INFO+12);
	g_stHardDiskInfo.ucSectorsPerTrack		= *(unsigned char *)(HARDDISK_INFO+14);
#else
	pucBuffer = (unsigned char*)pvVmmKeMalloc(512, GFP_KERNEL);
	ucId5SendCommand(IDENTIFIER_DRIVE, pucBuffer);
	g_stHardDiskInfo.uiCylinders	= *( (unsigned short *)pucBuffer+1);
	g_stHardDiskInfo.ucHeads		= *( (unsigned short *)pucBuffer+3);
	g_stHardDiskInfo.ucSectorsPerTrack = *( (unsigned short *)pucBuffer+6);
	vVmmKeFree(pucBuffer);
#endif
	ulSectors	= g_stHardDiskInfo.ucHeads * g_stHardDiskInfo.ucSectorsPerTrack * g_stHardDiskInfo.uiCylinders;
	ulSize		= ulSectors / 2048;
#ifdef _DEBUG__
#ifdef _DEBUG_IDE__
	kprintf("Harddisk Information:\n");
	kprintf("\tTotal Space:%i MB\n\tCylinders:%i Heads:%i SectorsPerTrack:%i  \n\n", 
		ulSize, g_stHardDiskInfo.uiCylinders, g_stHardDiskInfo.ucHeads, g_stHardDiskInfo.ucSectorsPerTrack );
	WaitKeyPressed("Please check the harddisk infomation\n");
	kprintf("Check the hd's partitions...");
#endif
#endif

	if ( !(pstBlock = pstId1BufferRead(IDE_DEVICE_HD,0)) ) {
		PANIC1("Unable to read partition table of harddisk");
	}
//	HexDump(pstBlock->pucBlock, 512);
//	PANIC();

	if ( pstBlock->pucBlock[510] != 0x55 || (unsigned char)pstBlock->pucBlock[511] != 0xAA){
		PANIC1("Bad partition table of harddisk");
	}
	
	pucBuffer = pstBlock->pucBlock;
	for ( i=1; i<4; i++) {
		if ( 0 == pucBuffer[0x1be + (i-1)*0x10] )
			continue;	//this partition slot is free.
		g_astPartitionInfo[i].ucName = 0x42 + i;	// 'B'+i 
		g_astPartitionInfo[i].ucBootIndecator	= pucBuffer[0x1be + (i-1)*0x10];
		g_astPartitionInfo[i].ucStartHead		= pucBuffer[0x1be + (i-1)*0x10 + 1];
		g_astPartitionInfo[i].ucStartSector		= (pucBuffer[0x1be + (i-1)*0x10 + 2]) & 0x3f;
		g_astPartitionInfo[i].ucStartCylinder	= (((pucBuffer[0x1be + (i-1)*0x10 + 2]) & 0xC0) << 2) + (pucBuffer[0x1be + (i-1)*0x10 + 3]);
		g_astPartitionInfo[i].ucSysIndecator	= pucBuffer[0x1be + (i-1)*0x10 + 4];
		g_astPartitionInfo[i].ucEndHead			= pucBuffer[0x1be + (i-1)*0x10 + 5];
		g_astPartitionInfo[i].ucEndSector		= pucBuffer[0x1be + (i-1)*0x10 + 6] & 0x3f;
		g_astPartitionInfo[i].ucEndCylinder		= (((pucBuffer[0x1be + (i-1)*0x10 + 6]) & 0xC0) << 2) + (pucBuffer[0x1be + (i-1)*0x10 + 7]);
		g_astPartitionInfo[i].ulPhyStartSector	= *(unsigned long *) &pucBuffer[0x1be + (i-1)*0x10 + 8];   /*本分区开始前有多少个扇区*/
		g_astPartitionInfo[i].ulSectors			= *(unsigned long *)&pucBuffer[0x1be + (i-1)*0x10 + 12];

#ifdef _DEBUG__
#ifdef _DEBUG_IDE__
		kprintf("Partition[ %c]:\n\t status[ %x]- from[ %d]- size[ %dmb]- type[ %d(%s)]",
				g_astPartitionInfo[i].ucName, g_astPartitionInfo[i].ucBootIndecator,
				g_astPartitionInfo[i].ulPhyStartSector,
				g_astPartitionInfo[i].ulSectors/2048,
				g_astPartitionInfo[i].ucSysIndecator, szId2PartitionInfo(g_astPartitionInfo[i].ucSysIndecator) );
#endif

⌨️ 快捷键说明

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