In the old days, you could usually dump the high part of the 1MB memory (e.g. E000:0000 to F000:FFFF) to retrieve the copy of your BIOS ROM, but nowadays the BIOS no longer fits into 64K or even 128K so all that you'd get would be a copy of the UEFI's CSM (Compatibility Support Module) with most of the code elsewhere, usually above the 1MB mark.
So, in which language, instruction set or machine code is it written?
It's written in a language that can be compiled to machine code that can be executed by the processor (the CPU). Typically, it's a combination of C and assembly language.
Doesn't it need any kind of processor to perform its operations?
Yes, the processor is what runs the BIOS code.
GitHub is a good place to search for such stuff, e.g.:
https://github.com/search?q=0x13A+IA32+MSR&type=Code (may require logging in)
Produces results like:
#define MSR_BOOT_GUARD_SACM_INFO 0x13A
#define B_NEM_INIT BIT0
There is no comment, but from the name it ...
As a tool I would recommend radare2 for this task.
And if you never done something like this before this is probably the best tutorial to get you started with.
Just be in mind its not gonna be a quick and dirty job, might take you a while.
Your quote is about the old legacy BIOS (16-bit). Nowadays most BIOSes implement UEFI-compliant firmware, which works in a pretty different way. The Opal specification published by TCG, describes how the UEFI firmware interacts with self-encrypting harddrives.
However, it seems your scenario is not really BIOS-related. According to ArchLinux wiki on the ...
This technique allows the code to be position-independent, since there are no explicit references to the specific address that holds the string. Instead, the call instruction will push onto the stack whatever address was current at the time. Depending on the assembler (if any) that was used to produce the code, this might simplify some things. If the code ...
You need to load the last 64KB of the ROM at linear address 0xF0000 (0xF000:0000) and create there a 16-bit segment with the base 0xF000. Then all your “low addresses” will line up (they point into the current segment with CS=0xF000).
In case you get references to E000, load the second 64KB chunk and so on.
Once you get to 32-bit code, it will likely be ...
Here's a fragment from the leaked AWARD BIOS source code (file COMMON.MAC):
SIODELAY MACRO ; SHORT IODELAY
jmp short $+2
IODELAY MACRO ; NORMAL IODELAY
WAFORIO MACRO ; NORMAL IODELAY
Probably the fastest and easiest way to get started with analyzing binaries such this is to begin with using binwalk to scan the file.
Here is the signature scan output for your file:
$ binwalk EFI64.ROM
DECIMAL HEXADECIMAL DESCRIPTION
0 0x0 ...
You can try running your BIOS in QEMU. QEMU's -S option will pause boot until a debugger (gdb) is attached. IDA's debugger apparently works fine with QEMU, according to this article: https://www.hex-rays.com/products/ida/support/tutorials/debugging_gdb_qemu.pdf
This is most likely the Cache-As-RAM (CAR) area, used by the BIOS code before initializing DRAM. The BIOS code is checking that it is usable as RAM (writable and reads back the same value).
In general, it's going to be pretty difficult to use QEMU for running BIOS code, as its emulation is likely to be pretty different from the board the BIOS was written ...
Details of such low-level registers are often disclosed only to Intel's trusted partners under NDA since they're not intended to be accessed by the general application programmer but only by writers of BIOS or other system-level code. That said, sometimes you can find info in unexpected places...
#define MSR_POWER_CTL 0x1FC
The MX25U1635E is designed for 1.8 volt logic, whereas your programmer is designed for 3.3 or 5.0 volt logic. You're going to need a 1.8 volt adapter for the programmer or you will damage the MX25U1635E.
If you google CH341A 1.8 volt adapter, you can find them for relatively cheap.
The legacy BIOS code is usually stored compressed in the UEFI filesystem. You can find it in UEFITool by looking for the magic string IFE$ (49 46 45 24) - signature of the EFI_COMPATIBILITY16_TABLE structure.
In AMI based firmware it is usually a RAW subsection of a file names CSMCORE. The following script parses the AMI format raw stream and extracts the ...
Most UEFI implementations use a standard ROM layout (FFS - Flash File System), described in the UEFI's PI (Platform Initialization) specification. There are many tools and scripts which can parse this format, the simplest is probably UEFITool.
Your disassembly doesn't show enough memory to know if the target is empty memory, but the x86 segmentation model means that the jump target for 0xF000:E205 is 0xFE205 (i.e. the (0xF000 << 4) + the 0xE205). IDA doesn't show that in an obvious way by default.
It's not compressed, it's just has some format IDA doesn't recognize, so it makes a wrong assumption that it's code for zilog processor. You should select Meta PC processor instead, and then specify that you want to process it as 32-bit code. It'll allow you to see some pieces of the code. But you'll have to learn the format of this EFI64.ROM file in order ...
The dump is likely different due to NVRAM data (basically settings which need to be saved between boots or even BIOS updates, such as boot device, RAM timings, serial number/MAC address and so on). The contents of the firmware volumes containing code should not change between boots.
There are at least two options I know of to check for differences between ...
As complementary answer, BIOS used to be written in assembler (now is mostly ANSI C code) which compiles to
a) Machine code for old architectures (in the past, like PC IBM; which was actually written in assembler according to https://sites.google.com/site/pcdosretro/ibmpcbios and an old book from Gottfried in Assembler for PC IBM).
b) UEFI bytecode for EFI ...