Only for programmers and BIOS gurus with technical questions.
#45028 by IntuitiveNipple
Fri Jun 01, 2007 1:17 am
Do you have any code to write/read the BIOS NVRAM ?

I'm working on a hack for the Phoenix BIOS on a Sony Vaio VGN-FE41Z laptop to enable the VMX capabilities of the Intel Core 2 Duo T7200 CPU.
The Sony BIOS doesn't enable VMX, and locks MSR 0x3A so it can't be enabled by the operating system later.

I've traced the BIOS and got the bit of code that sets the bits in MSR 0x3A. In that code (in module BIOSCOD6) it conditionally jumps over the instruction that sets the VMX bit (bit-2) based on the result of a far call to a standard location.

To prove it works I've created a custom BIOS with the conditional jump opcode replaced by two NOPs so that the BIOS sets the VMX bit.

Here's the unmodified code:
Code: Select allA866 mov ecx,0x3a        ; MSR 0x3A
A86C rdmsr               ; read
A86E bt eax,0x0          ; don't try to change it if it is already locked
A873 jc 0xa88d           ; skip MSR 0x3A logic
A875 push ax
A876 mov ax,0x195        ; NVRAM setting to check
A879 call 0xf000:0x4120  ; check NVRAM stored setting
A87E pop ax
A87F jz 0xa886           ; If VMX disabled, skip ** replace with 2 NOPs (0x90) **
A881 bts eax,0x2         ; Enable VMX
A886 bts eax,0x0         ; Lock MSR 0x3A
A88B wrmsr               ; write

Unfortunately that location (0xF000:4120 aka 0xF4120) is in a part of the BIOS memory range that is paged in and out as various BIOS modules are needed and so far I've been unable to identify the jump target in the unpacked BIOS modules.

From analysing the complete BIOS this far-call looks like a call to a library function (there are many calls to it with differing values of AX) that reads a value from the system settings stored in the EISA NVRAM (also used by the ESCD extension), with AX set to indicate the flag/value to read.

This isn't the 128 bytes of CMOS battery-backed RAM used by the RTC, but the 8KB of NVRAM that is mapped to FFFF80000.
Code: Select all=BCPNVS PnP NVRAM Storage=
NVRAM Total Size:           0x2000
NVRAM Max. Config Space:    0x1FFF
NVRAM Base Address:         0xFFF80000
ESCD Total Size:            0x2000
ESCD Segment Address:       0x8000
NVRAM Leading Control Area: 0x00000000
NVRAM Leading Data Area:    0x0000

When I can find this code I should be able to work out which bit/byte in NVRAM is used to control VMX, and then write a program to set this value from within a running operating system (my main target is Linux) so that on subsequent reboots the BIOS automatically enables VMX.