BIOS INT 13H问题(从驱动器读取扇区)

问题描述 投票:2回答:1

说明:

为了创建一个简单的独立程序,我在第一部分编写了一个简单的引导加载程序。其目的是将程序加载到内存中。为此,我使用AH = 2的INT 13h。代码是:

disk_load:
  push dx           ; Store DX on stack so later we can recall how many sectors were requested to be read,
                    ; even if it is altered in the meantime.
  mov ah, 0x02        ; BIOS read sector.
  mov al, dh          ; Read DH sectors.
  mov ch, 0x00        ; Select cylinder 0.
  mov dh, 0x00        ; Select head 0.
  mov cl, 0x02        ; Start reading from second sector (i.e. after the boot sector).
  int 0x13            ; BIOS interrupt.
                      ;  <!----here
  pop dx
  ret

load_software:
  mov bx, 0x7e0
  mov es, bx
  xor bx, bx
  mov dh, 66
  mov dl, [BOOT_DRIVE]
  call disk_load

我在VirtualBox 5.2.8中进行了所有练习,效果很好。将所有内容移动到具有VirtualBox 6.0.14的第二台计算机上均无法通过实验。中断在CF置1时结束,指示失败。

阅读Boot loader doesn't jump to kernel code中的出色答案,我已解决了未指定DS值可能引起问题的潜在问题。如果在int 0x13调用之前停止并转储CPU状态,则两个VirtualBox上的状态都将保持一致:

00:00:05.930849 eax = 00000280 ebx = 00007e00 ecx = 00000002 edx = 00000000 esi = 00000000 edi = 0000fff0

00:00:05.930857 eip = 00007cc8 esp = 00007bf9 ebp = 00007bff iopl = 0 nv up ei plnz na po nc

00:00:05.930864 cs = {0000 base = 0000000000000000限制= 0000ffff标志= 0000009b} dr0 = 00000000 dr1 = 00000000

00:00:05.930877 ds = {0000 base = 0000000000000000限制= 0000ffff标志= 00000093} dr2 = 00000000 dr3 = 00000000

00:00:05.930884 es = {0000 base = 0000000000000000限制= 0000ffff标志= 00000093} dr4 = 00000000 dr5 = 00000000

00:00:05.930891 fs = {0000 base = 0000000000000000限制= 0000ffff标志= 00000093} dr6 = ffff0ff0 dr7 = 00000400

00:00:05.930898 gs = {0000 base = 0000000000000000限制= 0000ffff标志= 00000093} cr0 = 00000010 cr2 = 00000000

00:00:05.930904 ss = {0000 base = 0000000000000000限制= 0000ffff标志= 00000093} cr3 = 00000000 cr4 = 00000000

00:00:05.930910 gdtr = 00000000000fe89f:0047 idtr = 0000000000000000:ffff eflags = 00200246

解析所有值,我只能得出结论,该中断的所有输入参数均已正确设置。转储后的状态已设置CF和错误代码:

00:00:08.984877 eax = 00000900 ebx = 00000000 ecx = 00000002 edx = 00000000 esi = 00000000 edi = 0000fff0

00:00:08.984887 eip = 00007cca esp = 00007bf9 ebp = 00007bff iopl = 0 nv up ei pl nz na po cy

00:00:08.984896 cs = {0000 base = 0000000000000000限制= 0000ffff标志= 0000009b} dr0 = 00000000 dr1 = 00000000

00:00:08.984909 ds = {0000 base = 0000000000000000限制= 0000ffff标志= 00000093} dr2 = 00000000 dr3 = 00000000

00:00:08.984917 es = {07e0 base = 0000000000007e00限制= 0000ffff标志= 00000093} dr4 = 00000000 dr5 = 00000000

00:00:08.984925 fs = {0000 base = 0000000000000000限制= 0000ffff标志= 00000093} dr6 = ffff0ff0 dr7 = 00000400

00:00:08.984934 gs = {0000 base = 0000000000000000限制= 0000ffff标志= 00000093} cr0 = 00000010 cr2 = 00000000

00:00:08.984941 ss = {0000 base = 0000000000000000限制= 0000ffff标志= 00000093} cr3 = 00000000 cr4 = 00000000

00:00:08.984948 gdtr = 00000000000fe89f:0047 idtr = 0000000000000000:ffff eflags = 00200247

[注意错误代码AH=9 数据边界错误(在64K边界或> 80h扇区上尝试的DMA)使我进入https://en.wikipedia.org/wiki/INT_13H,在此声明:

缓冲区的寻址应保证完整的缓冲区位于给定的段内,即(BX + size_of_buffer)<= 10000h。

这将解释我的最初问题,因此我进行了另一项修复以设置es=0x7e0bx=0。这是上面显示的代码的状态。但是,即使该代码在上述状态下也会失败。

进一步的测试表明,我最多可以成功读取65个扇区,但失败66个或更多。由于它是一个怪异的数字,我计算出第65个扇区的结尾:0xffff。因此问题变得更加混乱。

问题:

我的es=0x7e0bx=0解决方案是否应避免段交叉(据我所知)?

如果这样做,为什么在跨越线性地址时似乎是问题所在?

或者一个人可以穿过该段,但不能穿过线性地址中的0xffff标记吗?

谢谢您的帮助。

assembly x86 virtualbox bootloader bios
1个回答
3
投票

问题是您“尝试在64K边界上尝试DMA”。这是事实,您的目标缓冲区的范围从物理地址0x07E00到0x17E00,跨越了0x10000的64K边界。 (这与段边界无关,因此,使用哪个段和偏移值到达0x07E00物理地址都没有关系。)

这样做的原因在于如何以便宜的价格设计原始的IBM PC。他们没有使用带有16位总线和16位支持芯片的16位8086,而是使用了带有8位总线的便宜16位8088 CPU,可以与便宜的8位支持芯片一起使用。特别是the DMA controller they chose仅能寻址64K存储器,这是DMA控制器设计用于8位CPU的典型寻址限制。他们通过使用单独的芯片来提供DMA地址的高四位来使其工作,从而允许对8088的完整1024K地址空间进行寻址。 (在IBM PC AT上,它已扩展为提供高8位,以便可以访问整个80286 16M地址空间。)

[不幸的是,这意味着在DMA操作期间DMA地址的高四位是固定的,这实际上将1024K地址空间划分为十六个64K页。任何跨越64K边界执行从一页到另一页的DMA操作的尝试都将环绕到页面的开头。尽管BIOS可以通过将读取分为两个单独的读取来解决此问题,每个64K页面一个,但它仅返回错误。

注意,由于硬盘接口通常不使用IBM PC DMA控制器,因此通常这只是软盘访问的问题。

由于跨轨道和圆柱边界时也存在类似的潜在边界问题,因此解决此问题的最佳方法是一次只读取一个扇区,如Jester和Michael Petch在评论中所述。作为一个简单的解决方法,您可以移动缓冲区,使其从物理地址0x10000开始,但是您可能会发现在现实世界的系统中,您只能读取轨道上的其余扇区。

© www.soinside.com 2019 - 2024. All rights reserved.