Page 1 of 1

Read Sector(s) command in ATA PIO mode

Posted: Fri Sep 01, 2023 2:43 pm
by OsEnthusiast
I wrote a ATA disk driver that uses ATA PIO mode as part of my OS, according to tutorials on this site, and official ATA specification I found.
While reading works, I noticed an inconsistency in register setup before executing read command (0x20). The register setup I see on this website doesn't match what I've read in ATA interface specification.

Namely, tutorial on this website says: "select a target drive by sending 0xA0 for the master drive, or 0xB0 for the slave, to the "drive select" IO port" [https://wiki.osdev.org/ATA_PIO_Mode]
While the the specification says that: bit 7 of device register is obsolete. bit 6 of device register should be set to 1 if it's in LBA mode (0 if CHS), bit 5 is obsolete. bit 4 (DEV) should select either master or slave (1 or 0), bits 3-0 should be bits of LBA(27-24).
I checked ATA6, ATA7 and ATA8 specifications and they all repeat the same thing for this command.

0xA0 written as binary is: 0b10100000
The binary value I get by following specification is: 0b01010000

The former works, the latter doesn't. Why? Could it be that QEMU is virtualizing an older ATA hardware?
If it means anything, I am running my OS using QEMU, and passing the disk image to it by '-hda my_disk.img' parameter.

Here are links to specifications:
http://users.utcluj.ro/~baruch/media/si ... erface.pdf
https://tc.gts3.org/cs3210/2016/spring/ ... A8-ACS.pdf
https://hddguru.com/download/documentat ... TAPI-6.pdf

Re: Read Sector(s) command in ATA PIO mode

Posted: Mon Sep 11, 2023 11:49 pm
by Octocontrabass
OsEnthusiast wrote:bit 4 (DEV) should select either master or slave (1 or 0)
That's backwards. The primary device is selected when bit 4 = 0, not when bit 4 = 1.

The wiki uses 0xA0 to select the primary device (bit 4 = 0) in CHS mode (bit 6 = 0). The two obsolete bits should always be set. If you want to select the primary device in LBA mode, you'd use 0xE0 (bit 6 = 1). Ancient drives that don't support LBA will misbehave if you set bit 6, so you might want to check first.