【问题标题】:Reading data from HDD without BIOS interrupts DRQ bit not setting在没有 BIOS 中断的情况下从 HDD 读取数据 DRQ 位未设置
【发布时间】:2018-12-26 12:55:28
【问题描述】:

重要提示:此代码将在不格式化或恢复的情况下使媒体无法使用。使用未使用的、空的或不需要的介质。

复制 BIOS 中断函数的行为应该很简单,但有关它的在线信息在现实生活中的使用场景中乏善可陈。所以我编写了代码来读取 2.5" 硬盘驱动器标识信息,这是 int 13h 的函数。我在检查 0x1f7 状态寄存器的 DRQ(数据准备好查询?)位的阶段遇到了问题。当我评论在 check-DRQ 循环中代码继续执行,但数据全为 0,可能是因为它没有被读取。我尝试过改变从属和主位,以及主/辅助总线......辅助总线通过 DRQ 检查但数据似乎全为 1。重要的是,int 13h 在同一驱动器和同一台机器上工作正常。有谁知道是否有办法: a) 知道正在引导的硬盘的 ide 位置(主/从,主/从),然后 b)在不读取它的情况下测试它的存在,并且 c) 弄清楚如何让 DRQ 位变为绿色?错误寄存器在 DRQ 出来之前是否有意义?

有趣的是,BIOS 显示除了 USB、DVD 和 LAN 条目之外的 3 个 HDD,但我只有两个用于硬盘驱动器的插槽。而且我永远无法插入我的 HDD,使其成为 HDD1。奇怪。这有关系吗?

这是我的可引导代码,用于使用控制寄存器从 ATA HDD 主主机读取并将其几个字节作为二进制数打印在屏幕上:

[bits 16]
[org 0x7c00]
xor ax, ax
cli
mov dx, 0x1f7
m1:
in al, dx
test al, 010000000b
jnz m1
mov dx, 0x1f6
mov al, 0xE0       ; LBA mode - not needed for this?
out dx,al
mov dx, 0x1f7
m2:
in al, dx
test al, 010000000b     ; wait for BSY to be 0
jnz m2
test al, 001000000b     ; wait for DRDY to be 1
jz m2
mov dx, 0x1f7
mov al, 0xEC          ; identify drive command
out dx, al
mov dx, 0x1f7
m3:
in al, dx
test al, 010000000b
jnz m3
mov dx, 0x1f7
m4:
in al, dx
test al, 000001000b    ; this test for DRQ never turns 1
jz m4
mov ax, 0
mov es, ax
mov di, 0x7e00       ;save the identification to 0x7e00
mov dx, 0x1f0
mov cx, 256
rep insw
mov ax, 0xb800     ; display in table of binary bytes
mov es, ax
mov di, 0
mov ax, 0
mov ds, ax
mov si, 0x7e00     ;starting RAM address to read
mov cx, 0
mov dl, 20      ;how many lines to print
morelines:
mov bh, 7      ;how many bytes per line
morebytes:      
mov ah, [ds:si]
mov bl, 8       ;counter for bits of each byte to print
morebits:
shl ah, 1
mov al, 48
jnc zero
mov al, 49
zero:
mov [es:di], al
inc di
inc di
dec bl
jnz morebits
mov al, 32
mov [es:di], al
inc di
inc di
inc si
dec bh
jnz morebytes
add cx, 80*2
mov di, cx
dec dl
jnz morelines
times 510 - ($ - $$) db 0
dw 0xaa55

【问题讨论】:

  • @rcgldr 有没有人在线反汇编过他们的 INT 0x13 BIOS 代码?
  • "而且我永远无法插入我的 HDD,使其成为 HDD1"。在我的系统上,BIOS 对驱动器进行编号,如果只有一个驱动器,它将是驱动器 0,无论它连接到哪个插槽。我的 BIOS 允许我查看插入哪个插槽的内容,这可能会有所帮助在这个情况下。我删除了我之前的 cmets。
  • 这不是一个答案,它只是我制作的一个引导加载程序,它试图获取可能对这个问题有用的扩展磁盘驱动器信息。你能告诉我们这个引导加载程序显示的驱动器、主/从值、IOport、控制端口和 IRQ 将它添加到你的问题吗? capp-sysware.com/misc/osdev/eddinfo/boot.asm

标签: assembly x86 bootloader real-mode ata


【解决方案1】:

复制 BIOS 中断函数的行为应该很简单,但网上有关它的信息在现实生活中的使用场景中乏善可陈。

不,绝对不是。

例如,要重新创建(由于历史限制和“当 CPU 可以做更好的事情时浪费 CPU 时间轮询 IO 完成”设计白痴)int 0x13 接口,您将需要以下代码:

  • 旧版/ISA 软盘控制器、软盘驱动器、磁带驱动器
  • 传统/ISA“并行 ATA”控制器、ATA 磁盘驱动器和 ATAPI CD-ROM
  • 大约 50 种不同的传统/ISA“并行 ATA”RAID 控制器
  • 80 种不同的传统/ISA SCSI 控制器
  • 3 种不同的 USB 控制器、USB 软盘驱动器、USB 大容量存储设备
  • SATA/AHCI
  • 大约 20 种不同的 PCI SCSI 控制器
  • 大约 30 种不同的 PCI(SATA、SAS)RAID 控制器
  • NVMe
  • 一堆设备枚举代码(例如扫描 PCI 总线并找出存在哪些设备等)
  • 以上所有内容都取决于(例如内存管理、IRQ 处理等)

这加起来的代码超出了 512 字节引导加载程序的容量,这就引出了一个问题:“如果您可以使用 BIOS 加载处理设备所需的代码,为什么不能使用 BIOS 加载代码?需要启动不糟糕的内核和普通设备驱动程序吗?”。

请注意,在大多数情况下(例如所有 SCSI、所有 RAID),BIOS 仅使用设备制造商提供并包含在其 ISA/PCI 卡中的 ROM,因此 BIOS 本身没有任何代码拥有设备。

【讨论】:

  • 如果您在过去几天阅读他之前的问题,他不相信他可以信任 BIOS,而且普京和 Russkis 可能已经利用了他的系统。他甚至不信任 CALL,因为它在幕后操纵 CS:IP 哈哈 ;-)
  • @MichaelPetch:听起来 OP 应该检查一下en.wikipedia.org/wiki/Librebooten.wikipedia.org/wiki/Coreboot,它们旨在用开源固件完全替换 BIOS。正如您所说,让 BIOS 加载您的代码并然后不信任它是没有意义的。
  • 这一切都是因为他发现了一个带有 Int 0x13/ah=3(和 ah=43)的错误(我也可以在 Intel BIOS 上复制):stackoverflow.com/questions/53870314/…
  • 一台机器上只有 1 或 2 个控制器。人们不应该有自我教育的障碍。特别是关于他们拥有和/或委托他们的幸福或全心全意的东西。不是俄罗斯制造英特尔并强制将完全访问、封闭、无法访问的 MINIX 操作系统芯片放入您的 CPU 中,从而不受限制地访问 RAM、TCP/IP 堆栈和设备。
  • @user145453:你在一台机器上有几个控制器(对于现代机器来说,AHCI/SCSI、NVMe、xHCI 和 USB 大容量存储比软盘、SCSI 和 RAID 更有可能),但是当你想要一个操作系统在多台机器上工作(尤其是在“一般公共下载和安装”的方式中),不可能提前猜出一台机器将拥有哪几个控制器。
【解决方案2】:

您可能正在使用插入 SATA0 端口而不是 HDD 的 DVD 驱动器。在这种情况下,命令 0xA1 (IDENTIFY PACKET DEVICE) 将返回识别数据。

对于 SATA1 - SATA3 端口,尝试设置寄存器 0x​​1F6 的第 4 位(驱动器选择),或按照@rcgldr 的建议使用位于 0x170 - 0x177 的寄存器。

【讨论】:

  • 我尝试设置0x1f6的第4位,我尝试使用第二个通道寄存器0x170,它不起作用。
  • @user145453 - 有些主板还有两组寄存器,可能在 0x160 和 0x1e0,但我不确定端口地址。
  • @user145453 HDD 可能插入了未映射到传统 I/O 范围的 SATA 端口。在这种情况下,BIOS 分配的 I/O 基地址可以在 SATA 控制器的 PCI 头中找到。
  • @user145453 如果您使用的是 SATA 磁盘,请尝试在 BIOS 中设置 IDE 兼容模式。
  • 我相信它已经设置好了。否则,当我尝试其他模式时,忙位没有清除。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-26
  • 1970-01-01
  • 2011-01-22
  • 2019-04-12
  • 1970-01-01
  • 2011-12-07
  • 1970-01-01
相关资源
最近更新 更多