[solved] I have a problem reading Hard Disk.
Posted: Mon Mar 21, 2011 6:17 am
Hello,
This is my first post, so please pardon me for any mistakes.
I am writing a basic function to read hard disk for my kernel. Below is the code.
The function works fine the first time but then reads either all 0x00 or all 0xFF after the first time.
Can anyone tell me the problem in the code.
if 'drive' is 0 or 1 it means IDE 0:0 or IDE 0:1 respectively, if 'drive' is 2 or 3 it means IDE 1:0 or IDE 1:1 respectively.
This is my first post, so please pardon me for any mistakes.
I am writing a basic function to read hard disk for my kernel. Below is the code.
Code: Select all
extern void outPort(unsigned short port, unsigned char data);
extern unsigned char inPort(unsigned short port);
bool HardDisk::ReadDisk(unsigned char *buffer, unsigned short NoOfSectors, unsigned __int32 LBA, unsigned char drive)
{
unsigned short base_port = 0;
if(drive > 1)
{
base_port = 0x0170;
drive-=2;
}
else
base_port = 0x01F0;
LBA = LBA & 0x0FFFFFFF;
unsigned char status = inPort(base_port+6);
// I dont want to declare another variable to hold the drive/head register data.
status = status | (drive << 4);
outPort(base_port + 6, status);
status = inPort(base_port + 7); // delay
status = inPort(base_port + 7); // delay
status = inPort(base_port + 7); // delay
status = inPort(base_port + 7); // delay
outPort(base_port+7, 0x08); // reset disk
while(true)
{
if((status & IDE_READY) == IDE_READY)
break;
if(((status & IDE_ERROR) == IDE_ERROR) || ((status & IDE_DRIVEFAULT) == IDE_DRIVEFAULT))
outPort(base_port+7, 0x08);
}
while(NoOfSectors > 0)
{
status = inPort(base_port + 6);
status = status | 0x40 | (unsigned char)(LBA >> 24);
outPort(base_port + 6, status);
outPort(base_port + 2, 0x01);
outPort(base_port + 3, (unsigned char)LBA);
outPort(base_port + 4, (unsigned char)(LBA >> 8));
outPort(base_port + 5, (unsigned char)(LBA >> 16));
outPort(base_port + 7, 0x20);
while(true)
{
status = inPort(base_port + 7);
if(((status & IDE_READY) == IDE_READY) && ((status & IDE_BUSY) == 0) && ((status & IDE_DATAREADY) == IDE_DATAREADY))
break;
if(((status & IDE_ERROR) == IDE_ERROR) || ((status & IDE_DRIVEFAULT) == IDE_DRIVEFAULT))
outPort(base_port+7, 0x08);
}
__asm
{
mov edi, dword ptr [buffer]
mov dx, word ptr [base_port]
mov ecx, 0x100
cld
rep insw
}
NoOfSectors -= 1;
buffer += 0x200;
LBA += 1;
__asm
{
nop
nop
nop
nop
nop
}
}
return true;
}
Can anyone tell me the problem in the code.
if 'drive' is 0 or 1 it means IDE 0:0 or IDE 0:1 respectively, if 'drive' is 2 or 3 it means IDE 1:0 or IDE 1:1 respectively.