I am trying to learn operating system by diving into the low-level details of it. And the course I'm now on is MIT 6.828 Operating System Engineering. The lab asks students to trace into the BIOS for a few instructions. The first three assembly instructions of BIOS list as folllows:
0xffff0: ljmp $0xf000,$0xe05b
0xfe05b: cmpl $0x0,%cs:0x6c48
0xfe062: jne 0xfd2e1
What I can't figure out is the second one: cmpl $0x0,%cs:0x6c48
. What does it do? Why need this condition before jmp
to a specific place? I have searched on the web for a while, but still can't find an explanation. And what's trickier is that I find different people get different addresses to compare to, like 0x6ac8
, 0x65a4
or 0x6c48
here.
What exactly that comparison does will depend on the BIOS manufacturer, but it is clearly some flag for POST (Power on Self Test) processing. Some BIOSes may have completely different code that doesn't look anything like those instructions. Since you are using QEMU, the default BIOS being used is SeaBIOS. That cmpl
is to determine if a reboot or a resume is being done:
As noted above, on emulators SeaBIOS handles the 0xFFFF0000:FFF0 machine startup execution vector. This vector is also called on machine faults and on some machine "resume" events. It can also be called (as 0xF0000:FFF0) by software as a request to reboot the machine (on emulators, coreboot, and CSM).
The SeaBIOS "resume and reboot" code handles these calls and attempts to determine the desired action of the caller. Code flow starts in 16bit mode in romlayout.S:reset_vector() which calls romlayout.S:entry_post() which calls romlayout.S:entry_resume() which calls resume.c:handle_resume(). Depending on the request the handle_resume() code may transition to 32bit mode.
You can look at the source code for the SeaBIOS for the entry_post
code which is where the jmp $0xf000,$0xe05b
takes you: .
ORG 0xe05b
entry_post:
cmpl $0, %cs:HaveRunPost // Check for resume/reboot
jnz entry_resume
ENTRY_INTO32 _cfunc32flat_handle_post // Normal entry point
If the 32-bit value at %cs:HaveRunPost
is not zero then it is a resume operation, otherwise it is a reboot operation. The address of HaveRunPost
or any internal BIOS variables may differ between one version of a SeaBIOS to another. This may because of changes to code between versions; compiler/compiler options used to build the ROM; BIOS features chosen etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With