OSDev.org
https://forum.osdev.org/

ATA can't find any disk
https://forum.osdev.org/viewtopic.php?f=1&t=33516
Page 1 of 1

Author:  tommasop [ Sun Feb 17, 2019 1:05 pm ]
Post subject:  ATA can't find any disk

Hi, i was following the IDE controller tutorial and i encountered a problem. When i read the value of ATA_REG_STATUS i get 0xff and from what i understand that means that there is no hdd in that bus.
I tried with both QEMU and bochs but no hdd is never found. Can someone tell me which option do i have to use to add an hdd to the IDE bus?

To be sure i also add all the devices and the addresses of the channels:
Code:
Device: 0
Vendor ID: 8086
Device ID: 1237
Class ID: 6
SubClass ID: 0
Prog if: 0
Device: 1
Vendor ID: 8086
Device ID: 7000
Class ID: 6
SubClass ID: 1
Prog if: 0
Device: 2
Vendor ID: 8086
Device ID: 7010
Class ID: 1
SubClass ID: 1
Prog if: 80
Device: 3
Vendor ID: 8086
Device ID: 7020
Class ID: c
SubClass ID: 3
Prog if: 0
Device: 4
Vendor ID: 8086
Device ID: 7113
Class ID: 6
SubClass ID: 80
Prog if: 0
PRIMARY_ATA:
    BASE: f0
    CONTROL: f6
SECONDARY_ATA:
    BASE: 70
    CONTROL: 76

This is how i get the addresses:
Code:
void getChannelData(struct PCIDevice dev){
    channels[ATA_PRIMARY  ].base  = (dev.BAR[0] & 0xFFFFFFFC) + 0x1F0 * !(dev.BAR[0]);
    channels[ATA_PRIMARY  ].control  = (dev.BAR[1] & 0xFFFFFFFC) + 0x3F6 * !(dev.BAR[1]);
    channels[ATA_SECONDARY].base  = (dev.BAR[2] & 0xFFFFFFFC) + 0x170 * !(dev.BAR[2]);
    channels[ATA_SECONDARY].control  = (dev.BAR[3] & 0xFFFFFFFC) + 0x376 * !(dev.BAR[3]);
    channels[ATA_PRIMARY  ].busmaster = (dev.BAR[4] & 0xFFFFFFFC) + 0; // Bus Master IDE
    channels[ATA_SECONDARY].busmaster = (dev.BAR[4] & 0xFFFFFFFC) + 8; // Bus Master IDE
}


and this is how i read:
Code:
uint8_t read(unsigned char channel, unsigned char reg) {
   unsigned char result;
   if (reg > 0x07 && reg < 0x0C)
      write(channel, ATA_REG_CONTROL, 0x80 | channels[channel].nInt);
   if (reg < 0x08)
      result = inb(channels[channel].base + reg - 0x00);
   else if (reg < 0x0C)
      result = inb(channels[channel].base  + reg - 0x06);
   else if (reg < 0x0E)
      result = inb(channels[channel].control  + reg - 0x0A);
   else if (reg < 0x16)
      result = inb(channels[channel].busmaster + reg - 0x0E);
   if (reg > 0x07 && reg < 0x0C)
      write(channel, ATA_REG_CONTROL, channels[channel].nInt);
   return result;
}



Most of this code is from the tutorial on the wiki, if there is something wrong please tell me.
Thanks to everyone and sorry for my english.

Author:  BenLunt [ Sun Feb 17, 2019 3:58 pm ]
Post subject:  Re: ATA can't find any disk

tommasop wrote:
Hi, i was following the IDE controller tutorial and i encountered a problem. When i read the value of ATA_REG_STATUS i get 0xff and from what i understand that means that there is no hdd in that bus.
I tried with both QEMU and bochs but no hdd is never found. Can someone tell me which option do i have to use to add an hdd to the IDE bus?

Correct, if you are reading 0xFF from a byte port I/O register, you most likely have nothing attached to that port.

For QEMU, it is as simple as:
Code:
-drive file=hd.img,format=raw,if=ide,media=disk,index=0

tommasop wrote:
To be sure i also add all the devices and the addresses of the channels:
Code:
Device: 4
Vendor ID: 8086
Device ID: 7113
Class ID: 6
SubClass ID: 80
Prog if: 0
PRIMARY_ATA:
    BASE: f0
    CONTROL: f6
SECONDARY_ATA:
    BASE: 70
    CONTROL: 76

Where did you get this info? Did you print it yourself? You are missing the high order byte of the BASE and CONTROL values.

tommasop wrote:
This is how i get the addresses:
Code:
    channels[ATA_PRIMARY  ].base  = (dev.BAR[0] & 0xFFFFFFFC) + 0x1F0 * !(dev.BAR[0]);

That is a strange way of defaulting to 0x1F0. However, it only works if dev.BAR[0] is guaranteed to be zero if defaulting to 0x1F0. The bottom bits of dev.BAR[0] might still be hard-wired to PORT I/O. If so, and most likely they are, you are getting:
Code:
    channels[ATA_PRIMARY  ].base  = (0x00000001 & 0xFFFFFFFC) + 0x1F0 * !(0x00000001);

which now gives you a base address of
Code:
    channels[ATA_PRIMARY  ].base  = 0 + 0x1F0 * 0;

which is a base address of zero. Probably not what you are anticipating.

tommasop wrote:
and this is how i read:
Code:
uint8_t read(unsigned char channel, unsigned char reg) {
   unsigned char result;
   if (reg > 0x07 && reg < 0x0C)
      write(channel, ATA_REG_CONTROL, 0x80 | channels[channel].nInt);
   if (reg < 0x08)
      result = inb(channels[channel].base + reg - 0x00);
   else if (reg < 0x0C)
      result = inb(channels[channel].base  + reg - 0x06);
   else if (reg < 0x0E)
      result = inb(channels[channel].control  + reg - 0x0A);
   else if (reg < 0x16)
      result = inb(channels[channel].busmaster + reg - 0x0E);
   if (reg > 0x07 && reg < 0x0C)
      write(channel, ATA_REG_CONTROL, channels[channel].nInt);
   return result;
}

Without more content, all of that just looks real funny to me.

tommasop wrote:
Most of this code is from the tutorial on the wiki, if there is something wrong please tell me.
Thanks to everyone and sorry for my english.

What tutorial are you quoting here? Will you please specify?

- Ben
http://www.fysnet.net/osdesign_book_series.htm

Author:  qookie [ Sun Feb 17, 2019 8:17 pm ]
Post subject:  Re: ATA can't find any disk

BenLunt: If I'm not mistaken, he's following PCI IDE Controller, which has both the I/O port calculation formulas that look really similar, and a read function that's almost exactly the same, minus the function name

Author:  BenLunt [ Sun Feb 17, 2019 9:24 pm ]
Post subject:  Re: ATA can't find any disk

qookie wrote:
BenLunt: If I'm not mistaken, he's following PCI IDE Controller, which has both the I/O port calculation formulas that look really similar, and a read function that's almost exactly the same, minus the function name

Thank you. There are numerous errors on that page and this page shows some of them.

tommasop, I think you need to not rely upon that page's code. The documentation, though I did not read through it thoroughly, seems to be good, but I would suggest you try your own code. In fact, I think I am going to back up to my previous question and ask why you don't simply use the BIOS to read your kernel from the disk? The kernel, then itself, can have an ATA driver that can then read from the disk via this Port I/O technique, which we are willing to help you with.

- Ben
http://www.fysnet.net/osdesign_book_series.htm

Author:  tommasop [ Mon Feb 18, 2019 3:31 am ]
Post subject:  Re: ATA can't find any disk

Thanks to everyone, the base and control i wrote are the ones that gets calculated with the function getChannelData, i have to rewrite that function. Anyway i'm trying to write my own driver without the bios for learning purpose. I pratically copy-pasted the code from the IDE Controller tutorial because my own code was giving the same result. Now i'm going to try with QEMU and see if it can detect the drive. As for the missing char in the address is an error i've made with the print function :p.

Author:  tommasop [ Mon Feb 18, 2019 3:45 am ]
Post subject:  Re: ATA can't find any disk

Thanks BenLunt! I tried with the QEMU option you gave and it didn't work but then i checked why the addresses were missing a char and i noticed i declared base and control with unsigned char insted of unsigned short! Now i'm going to rewrite evrything using the hints you gave me, thanks!

Page 1 of 1 All times are UTC - 6 hours
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/