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到特定的地方?我在网上搜索了一段时间,但仍然找不到解释。更棘手的是,我发现不同的人会得到不同的地址来进行比较,比如0x6ac8,0x65a4或者0x6c48这里。
这种比较究竟做什么将取决于 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 功能等。