【发布时间】:2018-01-26 01:22:33
【问题描述】:
我一直在编写一个基本的引导加载程序,它的工作原理就像一个桃子。但是,在我的实际机器上,一些指令被打乱,引导加载程序失败。我已经诊断出这种疾病,但没有很好的治疗方法。似乎 BIOS(顺便说一下,在兼容模式下的 UEFI)正在寻找一个 Bios 参数块 (BPB),找不到一个(因为我没有制作一个),并且粗暴地覆盖了某些字节,从而弄乱了引导加载程序.我目前修复它的方法是通过使用
保留(归零)我的程序的前 50 个字节来启动我的程序集resb 50
但是,这不是一个好的解决方案。考虑到引导加载程序只有 512 字节,这是对空间的巨大浪费。这大约浪费了 10% 的空间!所以这是我的问题:
有没有更好的方法来规避/停止/禁用覆盖引导加载程序部分的 bios?从我的引导加载程序中获取最多字节的最佳方法是什么?
【问题讨论】:
-
您需要在引导加载程序的开头创建一个 BPB,以便 BIOS 不会过度写入您的代码。同样,如果某些 BIOS 在引导加载程序的开头没有找到某些特定指令,它会拒绝加载引导加载程序(JMP 通常是最好的选择)。一些 BIOS 甚至可能会尝试通过检查内容来确定是否存在有效的 BPB,而一些 BIOS 则只是盲目地重写。
-
一个 DOS 4.0 BPB 可以在这个SO Answer(用 NASM 编写)中的 Complete Example with Int 13h Extension Checks 部分下的代码中找到。该示例创建了一个假的 1.44MB 软盘 BPB。 BPB 包括 JMP。所以从
boot:标签到main标签的所有内容都是 BPB -
不是真正的源,但中断向量表在 0x00000 和 0x00400 之间运行。在 0x00400 和 0x00500 之间是BIOS Data Area。该链接布局较低的内存。在最初的 IBM 系统上,也使用了 0x00500 和 0x00520 之间的区域。这就是为什么我通常不会将代码放在 0x00520 以下的原因。至于 0x9C000,这是一个简化。 0xA0000 通常是graphics video memory,所以你想使用比它少的任何东西。
-
你可能会问为什么我没有说 0x00520 到 0xA0000。这是某种简化。 0xA0000 下方是许多计算机上的扩展 BIOS 数据区 (EBDA)。通常它只有 1k,但在这些年来很少见的情况下,它高达 8 到 16k。为了安全起见,我将 0xA0000 减少到 0x9C000 以考虑可能的 16kb EBDA。除非您使用有故障的计算机,否则可以查询该区域的大小。使用 0x9C000 更容易省去麻烦并让您更轻松。当然,这假设您使用的是一台具有至少 640kb 常规 RAM 的机器。
标签: assembly nasm bootloader bios