Reading hdd with ATA PIO Mode

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
raz0r
Posts: 19
Joined: Sat Apr 30, 2011 6:02 pm

Reading hdd with ATA PIO Mode

Post by raz0r »

Hi,

Im trying to make a driver in ATA PIO Mode in 32bits mode

Code: Select all

static inline void insw(unsigned short port, void *addr, unsigned char cnt)
{
   __asm volatile("rep; insw"
       : "+D" (addr), "+c" (cnt)
       : "d" (port)
       : "memory");
}

static inline void outsw(unsigned short port, const void *addr, unsigned char cnt){
   __asm volatile("rep; outsw" : "+S" (addr), "+c" (cnt) : "d" (port));
}

int read_sector(int LBA) {
   int count = 1;      //number of sectors to read     
   char slavebit =0;   //0 for master device 1 for slave   sets bit 5 in 1f6
   int stat;

   outb(0x3f6, 0x02);   //disable interrupts

   outb(0x1F6, (0xE0 | (slavebit <<  4) | (LBA >> 24 & 0x0F)));

   //waste some time
   outb(0x1f1, 0x00);

   //set the sector count
   outb(0x1f2, (unsigned char)count);
   sleep(1);
   stat = ide_polling(0, 0);
      if(stat != 0)
         return stat;
   //send the low 8 bits of lbs to 1f3
   outb(0x1f3, (unsigned char)LBA);
   sleep(1);
   stat = ide_polling(0, 0);
      if(stat != 0)
         return stat;
   //send the middle 8 bits to 1f4
   outb(0x1f4, (unsigned char)(LBA >> 8));
   sleep(1);
   stat = ide_polling(0, 0);
      if(stat != 0)
         return stat;
   //send the high 8 to 1f5
   outb(0x1f5, (unsigned char)(LBA >> 16));
   sleep(1);
   stat = ide_polling(0, 0);
   if(stat != 0)
      return stat;

   //issue a read sectors command
   outb(0x20, 0x1f7);
   sleep(1);
   stat = ide_polling(0, 0);
      if(stat != 0)
         return stat;

   //eat 256 words form the buffer
   unsigned char ide_buff[256];
   printf("DATA BEFORE: %s\n", ide_buff);

   insw(0x1f0, ide_buff, 512);
   
   ide_polling(0,0);
   
   printf("DATA AFTER: %s", ide_buff);

}
When I send the DATA Port 0x1F0, for read 512bytes, ide_buff have the same values before and after (trash).
Whats the error? Im trying to recover the information of harddisk of that sector (or put the address of buffer obtained from disk).
User avatar
bewing
Member
Member
Posts: 1401
Joined: Wed Feb 07, 2007 1:45 pm
Location: Eugene, OR, US

Re: Reading hdd with ATA PIO Mode

Post by bewing »

Is this being tested on real hardware, or on an emulator?

The obvious problem I see is that you allocate ide_buff as 256 bytes, then you read 1Kb of information into that buffer (512 words). I don't know exactly why it's giving you the error that you see, though.
raz0r
Posts: 19
Joined: Sat Apr 30, 2011 6:02 pm

Re: Reading hdd with ATA PIO Mode

Post by raz0r »

bewing wrote:Is this being tested on real hardware, or on an emulator?

The obvious problem I see is that you allocate ide_buff as 256 bytes, then you read 1Kb of information into that buffer (512 words). I don't know exactly why it's giving you the error that you see, though.
Im testing in bochs - emulator.
The problem maybe is that I need IDENTIFY or RESET with any ports before send new information. I think that the hardware is not receiving the information of ports... Do you know the port/byte for reset / identify ? or step list (outb ports) that I need for read a word?
Post Reply