为什么 BIOS 需要在第二条指令中将(看似)随机地址中的值与零进行比较?

Bic*_*eng 6 x86 assembly qemu bios osdev

我试图通过深入了解操作系统的低级细节来学习它。我现在上的课程是MIT 6.828 操作系统工程。实验室要求学生进入 BIOS 以获取一些说明。BIOS 的前三个汇编指令如下:

0xffff0:    ljmp    $0xf000,$0xe05b
0xfe05b:    cmpl    $0x0,%cs:0x6c48
0xfe062:    jne     0xfd2e1
Run Code Online (Sandbox Code Playgroud)

我想不通的是第二个:cmpl $0x0,%cs:0x6c48. 它有什么作用?为什么需要这个条件才能jmp到特定的地方?我在网上搜索了一段时间,但仍然找不到解释。更棘手的是,我发现不同的人会得到不同的地址来进行比较,比如0x6ac80x65a4或者0x6c48这里。

Mic*_*tch 8

这种比较究竟做什么将取决于 BIOS 制造商,但它显然是POST(开机自检)处理的一些标志。某些 BIOS 可能具有完全不同的代码,看起来与这些指令完全不同。由于您使用的是 QEMU,因此使用的默认 BIOS 是SeaBIOS。那cmpl就是确定是否正在重新启动或恢复

如上所述,在模拟器上,SeaBIOS 处理 0xFFFF0000:FFF0 机器启动执行向量。这个向量也被称为机器故障和一些机器“恢复”事件。它也可以被软件调用(如 0xF0000:FFF0)作为重新启动机器的请求(在模拟器、coreboot 和 CSM 上)。

SeaBIOS“恢复和重启”代码处理这些调用并尝试确定调用者所需的操作。代码流在 romlayout.S:reset_vector() 中以 16 位模式开始,它调用 romlayout.S:entry_post() 调用 romlayout.S:entry_resume() 调用 resume.c:handle_resume()。根据请求,handle_resume() 代码可能会转换为 32 位模式。

您可以查看SeaBIOS的源代码以获取以下entry_post代码jmp $0xf000,$0xe05b: .

        ORG 0xe05b
entry_post:
        cmpl $0, %cs:HaveRunPost                // Check for resume/reboot
        jnz entry_resume
        ENTRY_INTO32 _cfunc32flat_handle_post   // Normal entry point
Run Code Online (Sandbox Code Playgroud)

如果 32 位值%cs:HaveRunPost不为零,则为恢复操作,否则为重启操作。HaveRunPostSeaBIOS 的一个版本与另一个版本之间的地址或任何内部 BIOS 变量可能不同。这可能是因为版本之间的代码发生了变化;用于构建 ROM 的编译器/编译器选项;选择的 BIOS 功能等。

  • @RossRidge:SeaBIOS 通过 PCI 配置空间(在英特尔上)更改 PAM 设置,暂时使影子内存从 0xf0000 到 0x100000 可写,该空间允许修改 HaveRunPost 内存位置。SeaBIOS 的“make_bios_writable”函数作为其影子内存功能的一部分用于此目的。 (3认同)
  • 现在的问题是这个值应该如何改变,因为它位于 ROM 中。 (2认同)