Hey Leute
Hab mal wieder ein Problem, welches ich einfach nicht lösen kann.
Momentan versuche ich mithilfe eines SATA devices und AHCI den Inhalt meines ISO images zu lesen.
Die ISO ist als CD/DVD in VirtualBox im Port 0 des SATA controllers, swowohl das Laufwerk als auch die HDD werden von meinem OS erkannt.
Ich habe alles probiert, hier ist ein Link zu einem Tutorial was ich dazu gefunden habe:
1:
http://wiki.osdev.org/IDE#Reading_from_an_ATAPI_Drive2:
http://wiki.osdev.org/ATAPIIch habe beide gelesen und denke auch verstanden, leider bekomme ich als Antwort auf mein 0xA0 Packet immer nur status=0 und error=0 zurück
Hier mein code:
#define ATA_DRIVE_MASTER 0xA0
#define ATA_DRIVE_SLAVE 0xB0
#define ATA_DATA(x)(x)
#define ATA_FEATURES(x)(x+1)
#define ATA_SECTOR_COUNT(x) (x+2)
#define ATA_ADDRESS1(x)(x+3)
#define ATA_ADDRESS2(x)(x+4)
#define ATA_ADDRESS3(x)(x+5)
#define ATA_DRIVE_SELECT(x)(x+6)
#define ATA_COMMAND(x)(x+7)
#define ATA_CONTROL(x)(x+0xC)
#define ATA_DCR(x)(x+0x206)
#define ATA_SELECT_DELAY(bus) \
{inb(ATA_DCR(bus));inb(ATA_DCR(bus));inb(ATA_DCR(bus));inb(ATA_DCR(bus));}
int atapi_drive_read_sector(uint32_t bus, uint32_t drive, uint8_t is_slave, uint32_t lba, uint8_t *buffer)
{
uint8_t status;
int size;
//0xA8 is "READ SECTORS" command byte.
uint8_t read_cmd[12] = { 0xA8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
read_cmd[9] = 1; //Sector count
read_cmd[2] = (lba >> 24) & 0xFF; //Address to read from
read_cmd[3] = (lba >> 16) & 0xFF;
read_cmd[4] = (lba >> 8) & 0xFF;
read_cmd[5] = (lba >> 0) & 0xFF;
//Enable IRQs
outb(ATA_CONTROL(bus), 0);
//Select drive (4th bit set means select slave)
outb(ATA_DRIVE_SELECT(bus), drive | (is_slave << 4));
//400ns delay
ATA_SELECT_DELAY(bus);
//PIO-Mode
outb(ATA_FEATURES(bus), 0x00);
//Max Size (2048 bytes)
outb(ATA_ADDRESS2(bus), ATAPI_SECTOR_SIZE & 0xFF);
outb(ATA_ADDRESS3(bus), ATAPI_SECTOR_SIZE >> 8);
//ATA-Packet
outb(ATA_COMMAND(bus), 0xA0);
//Is Busy?
while ((status = inb(ATA_COMMAND(bus))) & 0x80)
asm volatile ("pause");
printf("status: %X | Error: %X\n", status, inb(bus + 0x1));
//No Device
if(status == 0)
return 0;
printf("2\n");
//Data request ready? No error?
while (!((status = inb(ATA_COMMAND(bus))) & 0x8) && !(status & 0x1))
asm volatile ("pause");
printf("3\n");
}
...
uint32_t primary_base = (pci_info.address0 & 0xFFFFFFFC) + 0x1F0 * (!pci_info.address0);
uint32_t secondary_base = (pci_info.address2 & 0xFFFFFFFC) + 0x170 * (!pci_info.address2);
int j, k, m;
for(j = 0; j < 2; j++)
{
for(k = 0; k < 3; k++)
{
for(m = 0; m < 2; m++)
{
uint32_t base = primary_base;
if(m == 1)
base = secondary_base;
if(k == 0)
atapi_drive_read_sector(base, ATA_DRIVE_MASTER, j, 0, buff);
else if(k == 1)
atapi_drive_read_sector(base, ATA_DRIVE_SLAVE, j, 0, buff);
else
atapi_drive_read_sector(base, 0, j, 0, buff);
}
}
}
pci_info.address0 und pci_info.address2 sind nicht 0 sondern Adressen im I/O Raum. (Bit-0 ist gesetzt)
Ich hoffe mir kann Jemand helfen
Vielen Dank im Vorraus!