【问题标题】:Strange data when read disk sector with ATA/IDE PIO使用 ATA/IDE PIO 读取磁盘扇区时出现奇怪的数据
【发布时间】:2021-09-05 22:47:17
【问题描述】:

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

我试图在没有内核的情况下读取磁盘数据,但得到了奇怪的数据。 我有一个文件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。

【问题讨论】:

    标签: assembly drive osdev ata


    【解决方案1】:

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

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

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

    【讨论】:

      猜你喜欢
      • 2015-07-18
      • 2018-02-21
      • 2010-12-17
      • 2016-03-16
      • 2023-03-23
      • 2020-02-03
      • 2020-10-11
      • 2019-12-05
      • 2013-11-20
      相关资源
      最近更新 更多