0

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

复制 BIOS 中断函数的行为应该很简单,但在线有关它的信息在现实生活中的使用场景中却乏善可陈。所以我编写了代码来读取 2.5" 硬盘驱动器标识信息,这是 int 13h 的函数。我在检查 0x1f7 状态寄存器的 DRQ(数据准备好查询?)位的阶段遇到了问题。当我评论在 check-DRQ 循环中代码继续执行,但数据全为 0,可能是因为它没有被读取。我尝试过改变从属和主位,以及主/辅助总线......辅助总线通过 DRQ 检查但数据似乎全为 1。重要的是,int 13h 在同一个驱动器和同一台机器上工作正常。有谁知道是否有办法:a)知道硬盘的 ide 位置(主要/​​次要,主/从)正在启动,然后 b) 测试它' s 那里没有读取它,并且 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
4

2 回答 2

2

复制 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 仅使用设备制造商提供的 ROM,并包含在他们的 ISA/PCI 卡中,因此 BIOS 本身没有任何自己的设备代码.

于 2018-12-26T04:55:28.857 回答
0

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

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

于 2018-12-24T18:48:09.340 回答