This is my first time writing a PIO driver so Iam not really sure what I'm doing is correct. I have been following the link from OsDev to get 28 bit PIO working. (https://wiki.osdev.org/ATA_PIO_Mode#28_bit_PIO)
Here is the code snippet which tries to load the first sector using PIO reads.
Code: Select all
extern void ata_disk_wait();
extern void ata_drq_wait();
void read_sector(uint32_t sector)
{
ata_disk_wait(); // wait BSY to 0 and RDY to 1
outb(0x1F6, sector >> 24 | 0xE0);// Master drive
outb(0x1F2, 1); // Read one sector
outb(0x1F3, sector);
outb(0x1F4, sector >> 8);
outb(0x1F5, sector >> 16);
// Make a read call
outb(0x1F7, 0x20);
// transfere
}
void read_kernel(uint32_t address, uint32_t sector)
{
read_sector(sector);
ata_disk_wait();
ata_drq_wait();// wait DRQ to 1
// copy to address
// insw(0x1F0, (uint32_t)address, 512/2);
}
void
boot_main()
{
byte *address = (byte *)0x10000; // Save kernel at address
read_kernel((uint32_t)address, 1);
}
Code: Select all
mov sp, 07c00h
call boot_main
;; get data from port
mov dx, 01F0h
xor eax, eax
in al, dx
mov [010000h], al
Code: Select all
global ata_drq_wait
ata_drq_wait:
pusha
xor al, al
mov dx, 01F7h
.loop:
in al, dx
test al, 008h
jz .loop
.end:
popa
ret
global ata_disk_wait
ata_disk_wait:
pusha
xor ax, ax
mov dx, 01F7h
.loop:
in al, dx
and al, 0C0h
cmp al, 040h
jne .loop
.end:
popa
ret
I have checked the boot_disk value in my boot loader. and the value of dl is 080h so qemu does boot from hard disk.