我目前正在阅读 boot.s
第一个 Linux 内核的源文件(假设 0.01 确实是第一个公开版本)。
我知道 C 和 ASM,后者比前者少得多。即便如此,我似乎能够理解并基本上掌握源文件中的代码。
这个文件让我很困惑。我现在意识到这是因为它处于实模式,而不是保护模式。不用说,我以前从未见过以实模式编写的 ASM 代码。保护模式是 x86 操作系统在我出生之前运行的事实上的模式,所以这是意料之中的。
这是我想更好地理解的例程:
/*
* This procedure turns off the floppy drive motor, so
* that we enter the kernel in a known state, and
* don't have to worry about it later.
*/
kill_motor:
push dx
mov dx,#0x3f2
mov al,#0
outb
pop dx
ret
抬头
outb
,我发现它用于将字节传递到计算机上的端口。我将根据 C 文档大胆猜测,这种情况将“停止电机”字节作为第一个参数传递,并将软盘驱动器端口号作为第二个参数传递。这个接口(interface)是BIOS提供的吗?还是直接通过软驱?我假设 BIOS 具有节俭的“驱动程序”,用于所有基本设备的非常基本的操作。
这就是我难过的地方:似乎
#0x3f2
这样的数字被无中生有。它们显然是硬件端口号或其他东西。这个文件到处都是这样的数字,没有解释他们指的是什么。我在哪里可以找到一个全面的引用资料,其中显示了他们可以从实模式接收的所有硬件端口和控制号?此外,该文件似乎在整个引导过程中使用硬编码的内存地址在内存中移动内核。我在哪里可以找到关于在实模式下可以写入哪些内存地址范围的指南?我还阅读了 Linus 关于重新编程中断以避免 BIOS 和内部硬件中断之间的冲突的评论。我不会撒谎,那是在我头上。
帮助会很大;如果您想知道的话,谷歌似乎对这个话题很少。
最佳答案
这些地址是 30 年前 IBM 发布第一台 IBM PC 时一成不变的。 0x3f0 是主软盘 Controller 寄存器的第一个地址。地址列表是 available here .
IBM 设计团队的一个不同寻常的举动是,他们用标准的现成零件将机器组装在一起。大多数芯片来自英特尔,软盘 Controller 是 NEC 设计的。无意中确保每个人都可以构建克隆。这些克隆使用相同的地址来确保软件兼容性,将 IBM 的选择变成可以硬编码的行业标准。
关于assembly - 实模式 x86 ASM : How are the Basics Done?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8894241/