我一直在尝试编写一个 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);
}
从我的 asm 我这样称呼它:
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 值。并且 dl 的值是080h
qemu 从硬盘启动。