我目前正在阅读有史以来第一个Linux内核的源代码中的boot.s文件(假定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文档进行猜测,即这种情况会将“ stop motor”字节作为第一个参数,并将软盘驱动器端口号作为第二个参数传递。

BIOS提供此接口吗?还是直接由软盘驱动器?我假设BIOS具有节俭的“驱动程序”,可用于所有基本设备的非常基本的操作。

这就是我感到难过的地方:似乎#0x3f2之类的数字已被淘汰出局。显然,它们是硬件端口号。该文件中撒满了这些数字,没有说明它们指的是什么。在哪里可以找到全面的参考资料,其中显示了它们可以从实模式接收的所有硬件端口和控制编号?同样,该文件似乎在整个引导过程中使用硬编码的内存地址在内存中移动内核。在哪里可以找到有关在实模式下可以写入哪些内存地址范围的指南?

我还阅读了Linus关于重新编程中断以避免在BIOS与内部硬件中断之间发生冲突的评论。我不会说谎,那是我的头。

帮助会很棒;如果您想知道的话,Google在这个话题上似乎很少。

最佳答案

首先,欢迎来到实模式汇编器世界!
您可能已经意识到,实模式和保护模式之间的实际汇编程序几乎相同-主要区别在于操作数大小和内存布局/管理。

互联网上有一些用于实模式的资源-您只需要寻找它们!一个非常重要的资源是Ralf Brown's Interrupt列表(称为RBIL)-它提供了大量有关实模式编程中使用的各种中断的信息。另一个是BiosCentral的CMOS memory map,它描述BIOS在各种内存位置中存储(或应存储)的信息。

要回答关于您发布的Linux代码的一些问题:
outb是将al中的字节写入端口dx的指令-0x3f2是软盘控制器端口。 Wikipedia可以帮助您了解x86端口号的基本列表,但是您必须深入了解有关al位的实际格式的详细信息。


在实模式下可以写入哪些内存地址范围?


您应该对INT 15h(AX = E820h)进行一些研究-它返回一个内存映射,描述可以使用哪些内存区域以及保留哪些内存区域。但是请注意:在查看中断时,重要的是要了解中断的程度,因为较旧的BIOS可能不支持中断。


...重新编程中断以避免BIOS与内部硬件之间的冲突
打断


许多硬件设备都有可编程的中断(用于在需要注意时为硬件提供服务)。通常,BIOS会在其启动例程期间整理出一个初始分配,但对于操作系统而言,出于自己的目的重新调整硬件中断或防止已知的不兼容现象并不少见。

最后一点:it seems that numbers like #0x3f2 are being pulled out of thin air。答案是肯定的。许多Linux引导源都是令人恐惧的(是的,这只是我的观点),并且似乎确实散布了看似随机的地址,端口号和其他位,而没有任何有意义的解释。坚持下去,查找其他实模式资源,最终它将变得有意义。哦,如果您遇到全面的参考文献,请告诉所有人(因为目前尚不存在)。

07-28 03:03
查看更多