0

当我读取磁盘扇区时,我得到了一些意想不到的数据。

我试图在没有内核的情况下读取磁盘数据,但得到了奇怪的数据。我有一个文件fs.img并像使用它一样使用它qemu-system-i386 -drive file=fs.img,index=0,media=disk,format=raw,if=ide ......

hd fs.img
00000000  01 02 03 04 05 06 07 08  09 0a 0b 0c 0d 0e 0f 10  |................|
00000010  00 01 02 03 02 01 00 00  00 00 00 00 00 00 00 00  |................|
00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00a00010  00 00 00 00 00                                    |.....|
00a00015

我得到的数据:

Addr 0x0: 40 14 00 10 00 00 3f 00  00 00 4d 30 30 20 20 20 
Addr 0x10: 20 20 20 20 03 00 04 2e  2b 20 20 45 55 48 52 44
Addr 0x20: 53 20 20 20 20 20 20 20  20 20 20 20 20 20 20 10
Addr 0x30: 01 00 00 00 00 07 14 10  3f c0 00 10 01 00 07 07
Addr 0x40: 03 78 78 78 78 00 00 00  00 00 00 00 00 00 00 00
Addr 0x50: f0 16 21 00 00 21 00 00  3f 00 00 00 00 01 00 00
Addr 0x60: 00 00 00 00 01 00 00 00  00 00 00 00 00 00 00 00
Addr 0x70: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
Addr 0x80: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
Addr 0x90: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00

读取扇区的代码:

read_sector(0, 4, buffer);

#define ATA_BASE 0x1f0
void read_sector(uint addr, uint count, uchar *buffer) {
    // FIXME: assert count <= 255

    // TODO: wait for ready

    uchar data;
    // how many sector
    data = count;
    outb(ATA_BASE + 2, data);

    // set addr
    data = addr & 0xff;
    outb(ATA_BASE + 3, data);
    data = addr >> 8 & 0xff;
    outb(ATA_BASE + 4, data);
    data = addr >> 16 & 0xff;
    outb(ATA_BASE + 5, data);
    data = (addr >> 24 & 0x0f) | 0xe0;
    outb(ATA_BASE + 6, data);

    // read command
    data = 0x20;
    outb(ATA_BASE + 7, data);

    // pool
    data = inb(ATA_BASE + 7);
    while ((data & 0x88) != 0x08) {
        data = inb(ATA_BASE + 7);
    }

    // read data
    int loop = count * 512;
    ushort d;
    int p = 0;
    while (loop--) {
        d = inw(ATA_BASE);
        printf("%xs ", d);
        buffer[p] = d;
        p += 1;
    }
    printf("\n");
}

如果我更改要读取的地址,我会得到与以前相同的输出。如果我使用文本文件作为磁盘映像,我会得到如下输出:

Addr 0x0: 40 02 00 10 00 00 3f 00  00 00 4d 30 30 20 20 20 
Addr 0x10: 20 20 20 20 03 00 04 2e  2b 20 20 45 55 48 52 44
Addr 0x20: 53 20 20 20 20 20 20 20  20 20 20 20 20 20 20 10
Addr 0x30: 01 00 00 00 00 07 02 10  3f e0 00 10 01 00 07 07
Addr 0x40: 03 78 78 78 78 00 00 00  00 00 00 00 00 00 00 00
Addr 0x50: f0 16 21 00 00 21 00 00  3f 00 00 00 00 01 00 00
Addr 0x60: 00 00 00 00 01 00 00 00  00 00 00 00 00 00 00 00

只有 0x01 和 0x37 已从 0x14 更改为 0x02。

4

1 回答 1

1

在读取扇区之前,我已经发送了一个 IDENTIFY 命令。它返回意外的数据。

如果我删除 IDENTIFY 命令的调用,数据是正确的。

更多信息: https ://wiki.osdev.org/ATA_PIO_Mode#IDENTIFY_command

于 2021-08-09T13:13:22.067 回答