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