Я пытался написать драйвер ATA PIO для загрузки файлов из защищенного режима, но может показаться, что все данные, которые я получаю из порта, являются мусором (0xffff
).
Это мойвпервые пишу драйвер PIO, поэтому я не совсем уверен, что я делаю правильно.Я перешел по ссылке от OsDev, чтобы заставить работать 28-битную PIO.(https://wiki.osdev.org/ATA_PIO_Mode#28_bit_PIO)
Вот фрагмент кода, который пытается загрузить первый сектор с использованием операций чтения PIO.
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);
}
, и из моего ассемблера я называю это так:
mov sp, 07c00h
call boot_main
;; get data from port
mov dx, 01F0h
xor eax, eax
in al, dx
mov [010000h], al
Вот функции disk_wait и drq_wait:
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
Но все данные, которые я получаю, кажутся 0xffff
.
Я проверил значение boot_disk в моей загрузкеloader. и значение dl 080h
, поэтому qemu загружается с жесткого диска.