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

📄 id2_hd.c

📁 小型操作系统,以VC为开发环境,需要boachs调试
💻 C
📖 第 1 页 / 共 2 页
字号:
#endif
	}
	Id1BufferRelease( pstBlock );
//	PANIC();
}

/************************************************************
*************************************************************
**      Function Name:			pstId2GetPartitonInfo
**      Author:                 x.cheng
**
**      Comment:
**			返回指定分区结构体指针。
**
**      List of parameters:
**			ucPartition - 0 current, 1 first, 2 second, etc...
**
**      Return value:   
**          no
**
**      Revisions:
**
*************************************************************
*************************************************************/
ts_PartitionInfo* pstId2GetPartitonInfo( unsigned char ucPartition)
{
	if ( ucPartition >= 5 ) {
		POSITION1("wrong partition nb, think it current.");
		ucPartition = 0;
	}
	if ( ucPartition == CURRENT_PARTITION )
		return ( &g_astPartitionInfo[g_ucCurrentPartition]);
	else
		return ( &g_astPartitionInfo[ucPartition]);

}
/************************************************************
*************************************************************
**      Function Name:			ulId2GetPartitonStartSector
**      Author:                 x.cheng
**
**      Comment:
**			返回指定分区的起始物理扇区号。
**
**      List of parameters:
**			ucPartition - 0 current, 1 first, 2 second, etc...
**
**      Return value:   
**          no
**
**      Revisions:
**
*************************************************************
*************************************************************/
unsigned long ulId2GetPartitonStartSector(unsigned char ucPartition)
{
	if ( ucPartition >= 5 ) {
		POSITION1("wrong partition nb, think it current.");
		ucPartition = 0;
	}
	if ( ucPartition == CURRENT_PARTITION )
		return ( g_astPartitionInfo[g_ucCurrentPartition].ulPhyStartSector );
	else
		return ( g_astPartitionInfo[ucPartition].ulPhyStartSector );
}

/************************************************************
*************************************************************
**      Function Name:			Id2SetCurrentPartiton
**      Author:                 x.cheng
**
**      Comment:
**			设定当前操作硬盘分区。
**
**      List of parameters:
**			ucPartition - 0 default, 1 first, 2 second, etc...
**
**      Return value:   
**          no
**
**      Revisions:
**
*************************************************************
*************************************************************/
void Id2SetCurrentPartiton(unsigned char ucPartition)
{
	if ( ucPartition >= 5 ) {
		POSITION1("wrong partition nb, think it default.");
		ucPartition = 0;
	}
	g_ucCurrentPartition = ucPartition;
}




//----------------------------------------------------------------------------------
//==============================local function======================================
//----------------------------------------------------------------------------------



/************************************************************
*************************************************************
**      Function Name:			szId2PartitionInfo
**      Author:                 x.cheng
**
**      Comment:
**			读取硬盘类型信息
**
**      List of parameters:
**			ucType - 
**
**      Return value:   
**          char * - 
**
**      Revisions:
**
*************************************************************
*************************************************************/
static char *szId2PartitionInfo(unsigned char ucType)
{
	int i;
	for (i=0; i<8; i++)
		if ( g_astPartitionType[i].ucType == ucType )
			break;

	return ( g_astPartitionType[i].pszName);
}

/************************************************************
*************************************************************
**      Function Name:			LBAtoCHS
**      Author:                 x.cheng
**
**      Comment:
**			把LBA 格式转换为CHS格式-called only by ucHdSendCmdLBA
**     cylinder =   4 = ( 1202 / ( 5 * 50 )
**         temp = 202 = ( 1202 % ( 5 * 50 ) )
**         head =   4 = ( 202 / 50 )
**       sector =   3 = ( 202 % 50 ) + 1
** another translation method:
**     cylinder =   (lba/spt)%head
**         head =   (lba/spt)/head
**       sector =   (lba%spt)+1
**
**      List of parameters:
**			ulBlock - physical sectors nr of cmd
**
**      Return value:   
**          unsigned char - current request nr
**
**      Revisions:
**
*************************************************************
*************************************************************/
static void LBAtoCHS(unsigned long ulBlock, unsigned short* puiCylinder, unsigned char* pucHead, unsigned char* pucStartSector)
{
#ifndef _BOCH_EMU__  
	unsigned short uiTemp;
	*puiCylinder = ulBlock / (g_stHardDiskInfo.ucHeads*g_stHardDiskInfo.ucSectorsPerTrack);
	uiTemp		 = ulBlock % (g_stHardDiskInfo.ucHeads*g_stHardDiskInfo.ucSectorsPerTrack);
	*pucHead	 = uiTemp / (g_stHardDiskInfo.ucSectorsPerTrack+1);
	*pucStartSector = uiTemp % (g_stHardDiskInfo.ucSectorsPerTrack+1);
#else
/*because disk image is flat model, and
In flat mode, all sectors of the harddisk are stored in one flat file, in lba order.*/
	*pucStartSector	= ulBlock &0xff;
	*puiCylinder	= (ulBlock &0xffff00)>>8;
	*pucHead		= (ulBlock &0xf000000)>>24;

#endif
}

/************************************************************
*************************************************************
**      Function Name:			Id2SendCmdLBA
**      Author:                 x.cheng
**
**      Comment:
**			向硬盘发送命令, 按lba模式读写扇区
**
**      List of parameters:
**			ppucBuffer - 写命令要改写
**
**      Return value:   
**          unsigned char - current request nr
**
**      Revisions:
**
*************************************************************
*************************************************************/
static void Id2SendCmdLBA(unsigned char ucCmd, unsigned long ulLSN, 
							 unsigned char ucRWSectors, unsigned char *pucBuffer)
{
	unsigned char ucHead, ucStartSector;
	unsigned short uiCylinder;

/*
	// convert ulLSN to CHS 
	if ( (ulLSN ==0) || (ulLSN == 1) )  //boot secter read || fat sector read
		//首先,应该把本分区的开始扇区+上去
	ulLSN += g_astPartitionInfo[gucCurPartition].ulPhyStartSector;
*/
		/*再转换                            */
	LBAtoCHS(ulLSN, &uiCylinder, &ucHead, &ucStartSector);
#ifdef _DEBUG__
#ifdef _DEBUG_IDE__
	kprintf("\tlba cmd-%x, lsn=%ld nsectors=%d, chs cyl-%d, h-%d, s-%d\n", ucCmd, ulLSN, ucRWSectors, uiCylinder, ucHead, ucStartSector);
#endif
#endif

	Id2SendCmd(ucCmd, uiCylinder, ucHead, ucStartSector, ucRWSectors);
	Delay(DELAY);

	if ( (ucCmd == WIN_WRITE) && (ucId5CmdResult(IDE_CHANNEL_0) == DRQ_STAT) ) {
		//当发送了写数据命令后,如果硬盘控制器处理正确,其处于等待接受数据的状态
		//要在状态正确的情况下写一个扇区的数据后才有中断产生.
#ifdef _DEBUG__
#ifdef _DEBUG_IDE__
		kprintf("\tWrite one sector to hd port...\n");
#endif
#endif
		//WritePortString(HD_DATA, pucBuffer, SECTOR_SIZE/2);	//turn to io.h for comment
		WritePortString(HD_DATA, pucBuffer, SECTOR_SIZE);

	}

	/* if cmd send err, return err?, not implement, yet! :-) *
	 *** return SEND_CMD_ERR;
    */

	return;
}

/************************************************************
*************************************************************
**      Function Name:			Id2SendCmd
**      Author:                 x.cheng
**
**      Comment:
**			向硬盘控制器端口发送命令
**
**      List of parameters:
**			no
**
**      Return value:   
**          no
**
**      Revisions:
**
*************************************************************
*************************************************************/
static void Id2SendCmd(unsigned char ucCmd, unsigned short uiCylinder, unsigned char ucHead, unsigned char ucStartSector,
						unsigned char ucSectors) 
{
	if (ucHead > 15)
		panic("\n%s:%s:%d line, error parameters...\n", __FILE__,__FUNCTION__,__LINE__);
/*
	if ( !iId5ControllerReady(IDE_CHANNEL_0) )
		panic("\n%s:%s:%d line, HD controller is too busy...\n", __FILE__,__FUNCTION__,__LINE__);

	vCLI();

	vOutPortDelay(ATA_PRIMARY_CURRENT, ATA_DEVICE0);
	if ( !iId5ControllerReady(IDE_CHANNEL_0) )
		PANIC1("device 0 isn't ready\n");
*/
	if ( iId5WaitIdeStatus(IDE_CHANNEL_0, BUSY_STATUS, 0) )
		PANIC1("ide channel 0 is too busy...\n");

	vOutPortDelay(ATA_PRIMARY_CURRENT, ATA_DEVICE0);
	Delay(DELAY);

	if ( iId5WaitIdeStatus(IDE_CHANNEL_0, BUSY_STATUS, 0) )
		PANIC1("device 0 isn't ready\n");

	vOutPortDelay(ATA_PRIMARY_CMD, 0 );	// use interrupt.
	vOutPortDelay(ATA_PRIMARY_PRECOMP, 0);
/*
#ifndef _BOCH_EMU__
	vOutPortDelay(ATA_PRIMARY_PRECOMP, g_stHardDiskInfo.uiCompensatePreWrites);
#else
	vOutPortDelay(ATA_PRIMARY_PRECOMP, 0);
#endif
*/
	vOutPortDelay(ATA_PRIMARY_NSECTOR, ucSectors);			/* 读写的扇区数 */
	vOutPortDelay(ATA_PRIMARY_SECTOR, ucStartSector);		/*开始扇区=0 */
	vOutPortDelay(ATA_PRIMARY_LCYL, uiCylinder&0xFF);		/*开始柱面低字节 = 0 */
	vOutPortDelay(ATA_PRIMARY_HCYL, uiCylinder>>8);			/*开始柱面高字节 = 0 */
									/*目前仅支持一个硬盘*/
	vOutPortDelay(ATA_PRIMARY_CURRENT, 0xE0|(0<<4)|(ucHead&0xf));	
									/*device 0, lba mode = 0xE0|(0<<4)|(head) */
									//1110 0000|		
	vOutPortDelay(ATA_PRIMARY_COMMAND, ucCmd);				/*发送命令*/

	vSTI();
//	Delay(DELAY);
//	if ( iId5WaitIdeStatus( IDE_CHANNEL_0, BUSY_STATUS, BUSY_STATUS) )
//		kprintf("device not accept command...\n");
//	ucId5CmdResult(IDE_CHANNEL_0);
}

⌨️ 快捷键说明

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