0

我一直在尝试编写一个 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 的值是080hqemu 从硬盘启动。

4

0 回答 0