无法从C中的磁盘读取扇区

时间:2020-06-21 19:52:55

标签: gcc x86-16 inline-assembly disk bios

我正在使用i686-elf-gcc交叉编译器来生成以实模式运行的代码。

我正在尝试从内核中读取一个扇区。我知道这是我的内核所在的位置,在第二个扇区中,第0个驱动器,第0个磁道。它构建良好,但是在我调用read之后,扇区读取仍为0。

u8 status;
u8 sectors_read;
read(1, 0, 1, 0, 0, status, sectors_read);
kprint("STATUS: ");
hex_to_ascii(status, num_str_buffer);
kprint(num_str_buffer);
kprint("\nSECTORS READ: ");
num_str_buffer[0] = '\0';
hex_to_ascii(sectors_read, num_str_buffer);
kprint(num_str_buffer);
void read(u8 sector_size, u8 track, u8 sector, u8 head, u8 drive, u8 status, u8 sectors_read)
{
    asm volatile("mov $2, %AH");
    asm volatile("mov %0, %%AL" : : "r"(sector_size) : );
    asm volatile("mov %0, %%CH" : : "r"(track) : );
    asm volatile("mov %0, %%CL" : : "r"(sector) : );
    asm volatile("mov %0, %%DH" : : "r"(head));
    asm volatile("mov %0, %%DL" : : "r"(drive));
    asm volatile("int $0x13");
    asm volatile("mov %%AH, %0":"=r"(status) : );
    asm volatile("mov %%AL, %0":"=r"(sectors_read) : );
}

1 个答案:

答案 0 :(得分:2)

read函数存在很多问题。由于您尚未发布可复制的示例,甚至没有足够的详细信息来了解您要针对哪种工具链进行编程,因此我无法就您的问题给出确切的答案。这是很多错误的地方:

  • 在C语言中,所有函数参数均按值传递。在status中分配给sectors_readread不会影响您在被叫方中传递的参数。而是传递一个指针。
  • 您不会告诉编译器您破坏axcxdx或这些寄存器的内容很重要。因此,编译器可能将它们用于任何其喜欢的目的,从而干扰您想要的语义。要解决此问题,请使用寄存器约束而不是mov指令将参数放入正确的寄存器中。
  • 您似乎没有将es:bx设置为要读取数据的缓冲区的地址。因此,BIOS会将数据读到es:bx指向的任何地址中,实际上将覆盖随机存储器。

这是一个示例,您可以如何在read函数中解决这些问题。请注意,根据您的情况,可能还需要进行其他更改。

typedef unsigned char u8;
typedef unsigned short u16;

void read(u8 sector_size, u8 track, u8 sector, u8 head, u8 drive,
    u8 *buffer, u8 *status, u8 *sectors_read)
{
    u16 result;

    asm volatile("push %%cs; pop %%es; int $0x13"
        : "=a"(result)
        : "a"(0x200|sector_size), "b"(buffer),
          "c"(track<<8|sector), "d"(head<<8|drive)
        : "es", "memory");

    *status = result >> 8;
    *sectors_read = result >> 0;
}

上面的代码假定使用ia16-gcc。对于i686-gcc,请使用

    asm volatile("int $0x13"
        : "=a"(result)
        : "a"(0x200|sector_size), "b"(buffer),
          "c"(track<<8|sector), "d"(head<<8|drive)
        : "memory");

相反。

请理解,没有您的合作和对别人在您的问题下发表的评论的回应,将无法提供比这更好的帮助。