OSDev.org

The Place to Start for Operating System Developers
It is currently Tue Apr 23, 2024 7:45 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 6 posts ] 
Author Message
 Post subject: [solved] I have a problem reading Hard Disk.
PostPosted: Mon Mar 21, 2011 6:17 am 
Offline
Member
Member
User avatar

Joined: Wed Feb 09, 2011 2:21 am
Posts: 87
Location: Raipur, India
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.

Code:
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;
}


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.

_________________
Always give a difficult task to a lazy person. He will find an easy way to do it.


Last edited by trinopoty on Mon Mar 21, 2011 8:51 am, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: I have a problen reading Hard Disk in Protected Mode.
PostPosted: Mon Mar 21, 2011 7:07 am 
Offline
Member
Member
User avatar

Joined: Thu Nov 16, 2006 12:01 pm
Posts: 7614
Location: Germany
Machete Debugging, a.k.a. "reduce the problem".

Don't look at this function as an atomic entity.

Trace what calls to this function are being made, and their parameters

Then take a notebook and a pencil, step through your function, and note down what your function does with the parameters, and what calls it should make. Does it look as it should work, or did you already find a problem?

Put traces in the inPort() and outPort() functions. Do the actual calls match expectations? Does the result of those calls match expectations? (Perhaps it's not ReadDisk() that is broken, but other code.)

Do the same for the inline ASM code: Do actual traces meet expectations?

Reduce. Isolate. Identify. Looking at two screenful of code and trying to hypnotize the error seldom works. Posting two screenful of code usually gives generic debugging answers, like this one, since we cannot reproduce your problem to put those traces and do that reducing ourselves. ;-)

_________________
Every good solution is obvious once you've found it.


Top
 Profile  
 
 Post subject: Re: I have a problen reading Hard Disk in Protected Mode.
PostPosted: Mon Mar 21, 2011 7:24 am 
Offline
Member
Member
User avatar

Joined: Wed Feb 09, 2011 2:21 am
Posts: 87
Location: Raipur, India
Well it works the first time it is used, that means there is no problem with the existing code. And I am calling the code with the right paramaters. The inPort() and outPort() works as expected, I have tested them. I tried calling the function ReadDisk() with known data in known sectors, but still the same result ie. it works the first time.

Is there some other command(s) I need to send to some port between two reads.


Top
 Profile  
 
 Post subject: Re: I have a problen reading Hard Disk in Protected Mode.
PostPosted: Mon Mar 21, 2011 7:36 am 
Offline
Member
Member
User avatar

Joined: Wed Feb 07, 2007 1:45 pm
Posts: 1401
Location: Eugene, OR, US
I assume that you are doing this on real hardware, and not in an emulator?

After you read each sector, try putting in some extra IO port reads, to make more of a delay. 4 nop's may not delay anything at all.


Top
 Profile  
 
 Post subject: Re: I have a problen reading Hard Disk in Protected Mode.
PostPosted: Mon Mar 21, 2011 7:51 am 
Offline
Member
Member
User avatar

Joined: Wed Feb 09, 2011 2:21 am
Posts: 87
Location: Raipur, India
Quote:
I assume that you are doing this on real hardware, and not in an emulator?

After you read each sector, try putting in some extra IO port reads, to make more of a delay. 4 nop's may not delay anything at all.



I am testing this on VmWare Workstation v6.0.
Also I usually read 1 sector at a time and call many functions between two reads which takes more than 400 ns.


Top
 Profile  
 
 Post subject: Re: [solved] I have a problem reading Hard Disk.
PostPosted: Tue Mar 22, 2011 3:35 am 
Offline
Member
Member
User avatar

Joined: Sat Dec 27, 2008 2:34 pm
Posts: 548
Location: Belgium
I've actually had the same problem for quite some time. With me it wasn't just the second read that would fail, it would be all "even" reads (i.e. the first read succeeds, second read fails, third read succeeds, fourth read fails, etc.). I'm not even sure if I fixed the problem either. It occurred on real hardware as wel as on QEMU, but not on Bochs.

But it's been quite some time since I've been busy with my OS, so I may be wrong about some details. The point I wanted to make is that I also had no idea how to solve the problem and everything seemed to be correct. I had read through different implementations of others (tried things I seemed to have forgotten) and found nothing that fixed it.

_________________
When the chance of succeeding is 99%, there is still a 50% chance of that success happening.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: DotBot [Bot] and 120 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group