Sorry for reviving this topic, however got the same problem.
I tested a lot of things, but none of them seem to work.
My ATA identify structure (taken from MSDN) looks like this:
Code:
struct ata_identify {
struct {
uint16_t reserved1 : 1;
uint16_t obsolete1 : 1;
uint16_t response_incomplete : 1;
uint16_t obsolete2 : 3;
uint16_t fixed_device : 1;
uint16_t removable_media : 1;
uint16_t obsolete3 : 7;
uint16_t atapi : 1;
} general_info;
uint16_t num_cylinders;
uint16_t specific_configuration;
uint16_t num_heads;
uint16_t retired1[2];
uint16_t num_sectors_per_track;
uint16_t vendor_unique1[3];
char serialnumber[20];
uint16_t deprecated[2];
uint16_t obsolete1;
char firmware_revision[8];
char model_number[40];
char maximum_block_transfer;
char vendor_unique2;
} __pack;
I have looked into specification of ATA, it should be correct.
The polling and data code:
Code:
bool drq = false, err = false;
status = ata_read_status(dev);
klogf("polling ata status: %d", status);
while (!(err = (status & ATA_STATUS_ERR) != 0) &&
!(drq = (status & ATA_STATUS_DRQ) != 0)) {
klogf("polling ata status: %d", status);
if (inb(dev->pio_base + ATA_REG_LBA_MID) ||
inb(dev->pio_base + ATA_REG_LBA_HI)) {
klogf("device is not ata");
kfree(data, 256 * sizeof(uint16_t));
return NULL;
}
status = ata_read_status(dev);
}
klogf("finished polling ata status: %d (err=%d drq=%d)", status, err, drq);
if (err) {
klogf("error reading ata device: err=%d drq=%d", err, drq);
return NULL;
}
for (int i = 0; i < 256; i++)
*(uint16_t *)(data + i) = inw(dev->pio_base + ATA_REG_DATA);
Te data from this code is not meaningful. The model & serial number are incorrect and consist of junk characters. Number of cylinders and heads also seems way too big (screenshot).
The emulator I'm using is QEMU, and I've attached the drives using the following snippet
Code:
QEMU=qemu-system-i386
QEMU_ARGS="-M pc-i440fx-2.8 -m 4G -monitor none -serial stdio"
BOOT_ISO=myiso.iso
$QEMU $QEMU_ARGS \
-drive id=boot,file=$BOOT_ISO,format=raw,if=none,unit=0 \
-drive id=disk1,file=mydisk.img,format=raw,if=none,unit=1 \
-device ide-hd,drive=boot,bus=ide.0,serial=hello,model=world -device ide-hd,drive=disk1,bus=ide.0
Thanks in advance.