OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Apr 25, 2024 2:14 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 8 posts ] 
Author Message
 Post subject: ATA driver help
PostPosted: Tue May 10, 2005 3:49 pm 
I have been reading the specs at this website on programming for the ATA controllers.
http://www.nondot.org/sabre/os/files/Disk/IDE-tech.html

and i have read taht one of the first things i need to do is issue the Identify Drive command. so i assume by looking at those specs, i need to do something similar to:

Code:
oubportb(0x1f6, 0xb0); // selects drive 0
outportb(0x1f7, 0xec); //identify drive command


from here it says it will set BUSY, store the required info into the sector buffer (?), set DRQ, and generate an interrupt. Then i am supposed to read the info from the sector buffer.
my question is...1. i assume i need to have the IDE irq interrupt handlers read from the sector buffer whenever the irq is triggered. but where do i read the data from. where is this 'sector buffer' that the document speaks of.

i do see the Read buffer command (0xe4), so i assume i need to use that? it says that also will set BUSY, then set up the sector buffer for a read, set DRQ, clear BUSY, and generate an interrupt.

So i would have 2 interrupts generated in order to read the info from the Identify Drive command? and even after executing the read buffer command...i still don't know where i read in the data in the sector buffer. all the read buffer command says is that i can read up to 512bytes from the sector buffer? i am sorry if this is a bit of a ramble. thanks for any help in advance. :)


Top
  
 
 Post subject: Re:ATA driver help
PostPosted: Wed May 11, 2005 12:28 am 
Hi,

Quote:
my question is...1. i assume i need to have the IDE irq interrupt handlers read from the sector buffer whenever the irq is triggered. but where do i read the data from. where is this 'sector buffer' that the document speaks of.

When you do those commands, the IDE controller calls either IRQ 14 or IRQ 15, depends what controller you used. (IRQ 14 is the primary, 15 is the secondary)

So you have to put on IRQ 14 the handler who reads the bytes.
You can read from it by using:

Code:
mov  dx,1f0h  ;base of IDE controller
in  ax,dx    ;read 16 bit (2 bytes) of the harddisk, whether it's the identify command or just a sector


It's just an example, but it should you give an idea :)
(Yes, the Identify command also triggers this IRQ and then you can read the 512 bytes, just like you read a sector)


HTH,

DennisCGc.

PS. When you read a sector or use the ID command, the IDE controller just triggers ONE IRQ.


Top
  
 
 Post subject: Re:ATA driver help
PostPosted: Wed May 11, 2005 12:59 am 
ok, thanks. so when i read in from the drive, i read in 2 bytes at a time, do i just loops the inportw() to read 256 times in a row to read the whole sector?


Top
  
 
 Post subject: Re:ATA driver help
PostPosted: Wed May 11, 2005 1:27 am 
you can also you DMA. I don't know how. Try reading an official document about the controller. The tutorial that you are reading is very confusing


Top
  
 
 Post subject: Re:ATA driver help
PostPosted: Wed May 11, 2005 2:12 am 
ugh...just typed a huge thing and the browser messed up when posting. so here we go one more time...

i created a struct to hold all the info returned from the identify drive command. here is some code i whipped up really quick to test that the command was working.

Code:
ataidentify_t *ata_id; //struct to hold returned info
unsigned char ata_id_data[512]; //512byte buffer to read data into;
unsigned short *data = &ata_id_data[0]; //pointer to data buffer

outportb(0x1f6, 0xb0); //select drive 0
while((inportb(0x1f7) & 0x80)); //BUSY clear
while(!(inportb(0x1f7) & 0x40)); //DRDY set

outportb(0x1f7, 0xec); //indetify drive command
while((inportb(0x1f7) & 0x80)); //BUSY clear
while(!(inportb(0x1f7) & 0x40)); //DRDY set

for(i = 0; i<256; i++)
{
     *data = inportw(0x1f0); // read in 2bytes into buffer
     data++;
}
ata_id = &ata_id_data[0];
k_printf("ata model: %s\n", ata_id->model;


unfortunantly i seem to not be getting data when i read or something. as anything i try to print out from the struct is just blank. i even tried printing the entire 512byte buffer as ascii, and it still prints nothing.

i take it i'm not doing this correctly?

also, for future setup, i decided to make sure that it was firing the IRQ's, so i unmask irq's 14 and 15, but my ISR never gets triggered? which i find very odd. i know that my IDT and ISR's are working though because my keyboard driver and PIT works just fine. thanks for any help.


Top
  
 
 Post subject: Re:ATA driver help
PostPosted: Wed May 11, 2005 11:28 am 
Hi,

Anthony wrote:
Code:
ataidentify_t *ata_id; //struct to hold returned info
unsigned char ata_id_data[512]; //512byte buffer to read data into;
unsigned short *data = &ata_id_data[0]; //pointer to data buffer

outportb(0x1f6, 0xb0); //select drive 0
while((inportb(0x1f7) & 0x80)); //BUSY clear
while(!(inportb(0x1f7) & 0x40)); //DRDY set

outportb(0x1f7, 0xec); //indetify drive command
while((inportb(0x1f7) & 0x80)); //BUSY clear
while(!(inportb(0x1f7) & 0x40)); //DRDY set

for(i = 0; i<256; i++)
{
     *data = inportw(0x1f0); // read in 2bytes into buffer
     data++;
}
ata_id = &ata_id_data[0];
k_printf("ata model: %s\n", ata_id->model;


There's something wrong with your code.
IIRC if you read from the status flag WHILE an interrupt is called/is going to be called the interrupt might have been died.
To avoid this, use 0x3f6.

Quote:
also, for future setup, i decided to make sure that it was firing the IRQ's, so i unmask irq's 14 and 15, but my ISR never gets triggered? which i find very odd. i know that my IDT and ISR's are working though because my keyboard driver and PIT works just fine. thanks for any help.

This is weird, maybe because of the mentioned problem ? Please try the first solution.

HTH,

DennisCGc.


Top
  
 
 Post subject: Re:ATA driver help
PostPosted: Fri May 13, 2005 3:37 pm 
ok, i read my status from 0x3f6 now. so it shouldn't clear the interrupt. and also, the nEIN bit has been set. but...still no interrupt. and i still can't get any actualy data returned from the Identify Drive command, from either bochs or vmware.
and that is my main concern.


Top
  
 
 Post subject: Re:ATA driver help
PostPosted: Sat May 14, 2005 3:49 am 
Hi,

Anthony wrote:
ok, i read my status from 0x3f6 now. so it shouldn't clear the interrupt. and also, the nEIN bit has been set. but...still no interrupt. and i still can't get any actualy data returned from the Identify Drive command, from either bochs or vmware.
and that is my main concern.


What is your BOCHS' configuration file then ? You actually do define a harddrive ? And I looked some information up, you want to identify the SECOND drive (Slave) of the primary controller. Maybe you wanted to do this. If so, add this:
Code:
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
ata0-slave: type=disk, path="yourhdimage", cylinders=totcylinder, heads=tothead, spt=totsectorpertrack


If you didn't intend to do, I suggest you clear the 3th bit (0000b instead of 1000b) and then add:
Code:
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
ata0-master: type=disk, path="yourhdimage", cylinders=totcylinder, heads=tothead, spt=totsectorpertrack
if you didn't have that.

Btw, what happens if you're running this on real hardware ?

HTH,

DennisCGc.


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

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], Majestic-12 [Bot] and 216 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