Code: Select all
outb(0x1F3, (unsigned char)addr);
outb(0x1F4, (unsigned char)(addr >> 8));
outb(0x1F5, (unsigned char)(addr >> 16));
outb(0x1F6, 0xE0 | (drive << 4) | ((addr >> 24) & 0x0F)));
I assume addr is the LBA address, correct?
The main problem: the tutorial says to "Send the drive indicator, some magic bits, and highest 4 bits of the block address", which is the last line there.
What in the world is the drive indicator? I've searched around, but the only topic I found had the author "Figure it out" without telling how. Is it 0xA0/0xB0, or 0x1F6/0x176?
PS: You can actually read/write meaningful data to raw sectors, right? Just a bunch of 1s/0s would be good enough at this stage to save simple information.
EDIT: This is my current code, if it will help
Code: Select all
char* ata_read_sector(unsigned int sectors, unsigned int lba)
{
if(lbamode == 1)
{
//LBA28
outb(0x1F1, 0x00);
outb(0x1F2, 0x01);
outb(0x1F3, (unsigned char)lba);
outb(0x1F4, (unsigned char)(lba >> 8));
outb(0x1F5, (unsigned char)(lba >> 16));
outb(0x1F6, 0xE0 | (drive << 4) | ((lba >> 24) & 0x0F)));
outb(0x1F7, 0x20);
while(!(inb(0x1F7) & 0x08));
short tmpword = 0;
char *buffer = kmalloc(sizeof(char) * 128);
for(int idx = 0; idx < 256; idx++)
{
tmpword = inw(0x1F0);
buffer[idx * 2] = (unsigned char)tmpword;
buffer[idx * 2 + 1] = (unsigned char)(tmpword >> 8);
}
kprintf(buffer);
}
else if(lbamode == 2)
{
//LBA48
}
else
{
//CHS
}
}
void ata_write_sector(unsigned int sectors, unsigned int lba)
{
if(lbamode == 1)
{
//LBA28
outb(0x1F1, 0x00);
outb(0x1F2, 0x01);
outb(0x1F3, (unsigned char)lba);
outb(0x1F4, (unsigned char)(lba >> 8));
outb(0x1F5, (unsigned char)(lba >> 16));
outb(0x1F6, 0xE0 | (drive << 4) | ((lba >> 24) & 0x0F)));
outb(0x1F7, 0x30);
while(!(inb(0x1F7) & 0x08));
short tmpword = 0;
char *buffer = kmalloc(sizeof(char) * 128);
strcpy(buffer, "testing 111");
for(int i = 0; i < 256; i++)
{
tmpword = buffer[8 + i * 2] | (buffer[8 + i * 2 + 1] << 8);
outw(0x1F0, tmpword);
}
}
else if(lbamode == 2)
{
//LBA48
}
else
{
//CHS
}
}