📄 id2_hd.c
字号:
#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 + -