ATA PIO LBA48 - by Wiki
Posted: Wed Dec 09, 2009 4:13 pm
Hi. I read Wiki chapter about ATA PIO. It has explained how to read/write hdd via chs, lba24 and lba48. Actualy CHS is not interesting to me, LBA24 I have already implemented. But the problem whas that If I want to read sector with number > 0x1000000 I get nothing because 0xFFFFFF - it is high level of 24bit value. But I need to load sectors of HDD at such addresses as tenth and hundreds of GB. For this I have to use LBA48. So:
when I tried to do reading via LBA24:
this is code for LBA24 and it works.
when I try to read via LBA48:
in this case I get 0xFFFF. If I know right - byte value 0xFF (or word 0xFFFF, dword 0xFFFFFFFF) are kinda indicators of result.
what is wrong to read_48()?
Thanks for any help, Daniel.
when I tried to do reading via LBA24:
Code: Select all
void read_24()
{
uint32_t LBA = 0x3F; //let's say I need to read this sector.
uint8_t slavebit = 0; //I'm using master drive.
uint8_t count = 1;
outb(0x1F6, 0xE0 | (slavebit << 4) | ((LBA >> 24) & 0x0F));
outb(0x1F1, 0x00) ;
outb(0x1F2, (unsigned char) count);
outb(0x1F3, (unsigned char) LBA));
outb(0x1F4, (unsigned char)(LBA >> 8));
outb(0x1F5, (unsigned char)(LBA >> 16));
outb(0x1F7, 0x20);
_asm { //it is pool... I used it from my driver because it is written in ASM, but used by C.
mov edx, 0x1F7
hddwait:
in al,dx
test al,128
jnz hddwait
}
uint16_t v = inportw(0x1F0); //to check reading enough to read one value.
printf("0x%h", v); //and right value is displayed (according to my hex-redactor
}
when I try to read via LBA48:
Code: Select all
void read_48()
{
uint8_t slavebit = 0; //I'm using master drive.
outb(0x1F6, 0x40 | (slavebit << 4));
outb (0x1F2, 0x00); //this is count high value, as I'm reading 1 sector - high value is 0.
outb (0x1F3, 0x00); //i'm reading sector 0x3F, that's why LBA2, LBA3, LBA4, LBA5, LBA6 - are zeros.
outb (0x1F4, 0x00);
outb (0x1F5, 0x00);
outb (0x1F2, 0x01);
outb (0x1F3, 0x3F); //LBA1
outb (0x1F4, 0x00);
outb (0x1F5, 0x00);
outb(0x1F7, 0x24);
_asm { //it is pool... I used it from my driver because it is written in ASM, but used by C.
mov edx, 0x1F7
hddwait:
in al,dx
test al,128
jnz hddwait
}
uint16_t v = inportw(0x1F0); //to check reading enough to read one value.
printf("0x%h", v); //and right value is displayed (according to my hex-redactor
}
what is wrong to read_48()?
Thanks for any help, Daniel.