I am, purely for hobby reasons, trying to understand some low-level code in the PC. I downloaded an outdated BIOS ROM image for a random old Gigabyte MB (https://www.gigabyte.com/Motherboard/GA-8I845GE775-G-rev-10/support#support-dl-bios), it's almost 15 years old so I hope it doesn't harm anyone's IP rights. I'll be using this file for reference.
I'm stumbled right at the beginning. These seem to be the very first instructions the processor sees after power up:
f000:fff0 ljmp 0xf000:0xe05b
f000:e05b jmp 0xf46c
f000:f46c cli
f000:f46d cld
f000:f470 smsw ax ; read CR0
f000:f473 test al, 1 ; test Protected Mode Enable
f000:f475 je 0xf480
[assuming PE is zero – jump:]
f000:f480 jmp 0xe043
f000:e043 mov al, 0x8f
f000:e045 out 0x70, al ; CMOS controller: disable NMI, set index 0xf
f000:e047 out 0xeb, al ; this port is presumably unoccupied: just a delay mechanism
f000:e049 in al, 0x71 ; read 0xf (CMOS Shutdown Status)
f000:e04b out 0xeb, al ; more delay
f000:e04d or al, al
f000:e04f jmp 0xf483
f000:f483 jne 0xf488
[assuming status = 0 (Power on or soft reset) – pass:]
f000:f485 call 0x4dee
Assuming the CMOS shutdown status is zero upon powering the computer on, the BIOS issues a call at f000:f485
. At that early moment, no attempt would have been done at detecting whether any RAM is even present. The stack segment and stack pointer have not been set up, either. The code at f000:f485
indeed looks like a function and ends with a ret
. How is this possible, where does the call
store the return address?
Or am I misunderstanding the values returned from port 0x71
? I used these two documents for reference:
The meaning of writing 0x8f
to 0x70
: https://wiki.osdev.org/CMOS#CMOS_Registers
The meaning of the values subsequently read from 0x71
: http://www.bioscentral.com/misc/cmosmap.htm
There are 2 cases:
a) "cold boot" (e.g. when the computer wasn't running and you turn it on). In this case; the memory controllers won't be initialized, the shutdown status won't be set, the jne 0xf488
will cause the code to jump somewhere else, and the call
won't be executed.
b) "warm boot" (e.g. when you reset the computer after it's already running). In this case; the memory controllers are still initialized (from when "cold boot" happened previously), shutdown status will be set, the jne 0xf488
won't do anything, and the call
will be executed (but that's fine, because the memory controllers are initialized).
Assuming the CMOS shutdown status is zero upon powering the computer on...
No. The shutdown status byte values are (according to Ralph Brown's Interrupt List):
Note: Ralph Brown's Interrupt List hasn't been maintained for ages. I'd expect some of this is old and/or only applies to some very old computers (e.g. 80286, which didn't have any way to leave protect mode other than reset).