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