Decoding the NVRAM from the Phoenix BIOSROM image/ Mod your Phoenix Setup menu.
First this is just a long note on where the locations are and some decoding for learning about the phoenix bios. This is not a step by step guide on modding your bios for adding features. This info will point you in the right way but bottom line messing with the bios can brick your machine. Don't go messing if you have no idea what building or modding is. This is still a work in progress and might be missing some ref points from my scribble notes... Trying to collect and format these notes. Note all the numbers that I use in reference are in Hex format unless specifically stated other wise.
The NVRAM can be decoded by two ways. One is directly from the stored memory location of the PC you are working on. The other is by finding the token table from the BIOS image. In memory the token table is found in the F000:0000 range of memory.. You can use a tool like symcmos or code something yourself to search and dump the tables. DOS debug will work fine. Search for the string BCPNV for the memory locations. This is the location the phoenix dispatch messenger will check for. symcmos searches for the the $PDM in memory. Decomp your BIOS image and search for $PDM, romexec0.
PDM: Search in memory for '$PDM'.
Code:
F000:5FB0 24 50 44 4D 01 0B 46 3E-7B 00 F0 00 00 00 00 00 $PDM..F>{.......
This has a 8 bit checksum = 00 check. When adding up the bytes it should end in 00. The 0B, 0B is total length. The next area is the far jump location in memory for the $PDM area. In my case this was E649:177D.
PDM_1: The PDM controls access to the NVRAM token table. For example the VT bit, Virtual Technology Processing option is disabled in many BIOS. The OEM vendor has chosen to disable this. If you debug your BIOS you will find the MSR call to verify if this bit is enabled or disabled. The PDM locations will be called. Here is what my PDM table looks like in IDA. 1761 through 177B holds the jump offset table. The calls to these locations are below the 117D, first call 1799. It will be possible to enable and disable some options in your BIOS directly from the OS using the calls in the BIOS. symcmos can import some NVRAM settings, often cleared on power cycle though. This is where hacking the NVRAM table in your BIOS ROM will come in handy as some bytes are locked from writing by MSR.
Cut some of the code to shorten it.
Code:
E649:1761 off_E7BF1 dw offset sub_E7C3A ; DATA XREF: seg000:1799
E649:1763 dw offset sub_E7C56
E649:1765 dw offset sub_E7C5D
E649:1767 dw offset sub_E7C64
E649:1769 dw offset sub_E7C7D
E649:176B dw offset sub_E7D2F
E649:176D dw offset sub_E7D3C
E649:176F dw offset sub_E7D49
E649:1771 dw offset sub_E7D56
E649:1773 dw offset sub_E7C90
E649:1775 dw offset sub_E7D63
E649:1777 dw offset sub_E7CA8
E649:1779 dw offset sub_E7CC6
E649:177B dw offset sub_E7C43
E649:177D ; ---------------------------------------------------------------------------
E649:177D
E649:177D loc_E7C0D:
E649:177D push bp
E649:177E mov bp, sp
E649:1780 push gs
E649:1782 push ds
E649:1783 push es
E649:1784 pushad ; Push all General Registers (use32)
E649:1786 push 0F000h
E649:1789 pop gs
E649:178B assume gs:nothing
E649:178B mov ax, 0FFFEh
E649:178E mov di, [bp+6]
E649:1791 cmp di, 0Eh ; Compare Two Operands
E649:1795 jnb short loc_E7C2E ; Jump if Not Below (CF=0)
E649:1797 shl di, 1 ; Shift Logical Left
E649:1799 call cs:off_E7BF1[di] ; Indirect Call Near Procedure
E649:179E
E649:179E loc_E7C2E: ; CODE XREF: seg000:1795j
E649:179E mov gs, ax
E649:17A0 assume gs:nothing
E649:17A0 popad ; Pop all General Registers (use32)
E649:17A2 mov ax, gs
E649:17A4 pop es
E649:17A5 pop ds
E649:17A6 pop gs
E649:17A8 assume gs:nothing
E649:17A8 pop bp
E649:17A9 retf ; Return Far from Procedure
E649:17AA
E649:17AA ; =============== S U B R O U T I N E =======================================
E649:17AA
E649:17AA
E649:17AA sub_E7C3A proc near ; CODE XREF: seg000:1799p
E649:17AA ; DATA XREF: seg000:off_E7BF1o
E649:17AA mov ax, [bp+8]
E649:17AD call sub_F3E3F ; Call Procedure
E649:17B2 retn ; Return Near from Procedure
E649:17B2 sub_E7C3A endp
E649:17B2
E649:17B3
E649:17B3 ; =============== S U B R O U T I N E =======================================
E649:17B3
E649:17B3
E649:17B3 sub_E7C43 proc near ; CODE XREF: seg000:1799p
E649:17B3 ; DATA XREF: seg000:177Bo
E649:17B3 mov ax, [bp+8]
E649:17B6 call sub_E7CEE ; Call Procedure
E649:17B9 jb short locret_E7C55 ; Jump if Below (CF=1)
E649:17BB movzx si, byte ptr [si+0Eh] ; Move with Zero-Extend
E649:17BF call sub_E7D25 ; Call Procedure
E649:17C2 mov ax, 0
E649:17C5
E649:17C5 locret_E7C55: ; CODE XREF: sub_E7C43+6j
E649:17C5 retn ; Return Near from Procedure
E649:17C5 sub_E7C43 endp
E649:17C5
E649:17C6
E649:17C6 ; =============== S U B R O U T I N E =======================================
E649:17C6
E649:17C6
E649:17C6 sub_E7C56 proc near ; CODE XREF: seg000:1799p
E649:17C6 ; DATA XREF: seg000:1763o
E649:17C6 mov bx, 2
E649:17C9 call sub_E7C6B ; Call Procedure
E649:17CC retn ; Return Near from Procedure
E649:17CC sub_E7C56 endp
E649:17CC
E649:17CD
E649:17CD ; =============== S U B R O U T I N E =======================================
E649:17CD
E649:17CD
E649:17CD sub_E7C5D proc near ; CODE XREF: seg000:1799p
E649:17CD ; DATA XREF: seg000:1765o
E649:17CD mov bx, 0Ah
E649:17D0 call sub_E7C6B ; Call Procedure
E649:17D3 retn ; Return Near from Procedure
E649:17D3 sub_E7C5D endp
E649:17D3
E649:17D4
E649:17D4 ; =============== S U B R O U T I N E =======================================
E649:17D4
E649:17D4
E649:17D4 sub_E7C64 proc near ; CODE XREF: seg000:1799p
E649:17D4 ; DATA XREF: seg000:1767o
E649:17D4 mov bx, 6
E649:17D7 call sub_E7C6B ; Call Procedure
E649:17DA retn ; Return Near from Procedure
E649:17DA sub_E7C64 endp
E649:17DA
E649:17DB
....
E649:18E0 ; ---------------------------------------------------------------------------
E649:18E0 call sub_E7CEE ; Call Procedure
E649:18E3 retf ; Return Far from Procedure
E649:18E4 ; ---------------------------------------------------------------------------
E649:18E4 call sub_E7D1A ; Call Procedure
E649:18E7 retf ; Return Far from Procedure
E649:18E8 ; ---------------------------------------------------------------------------
E649:18E8 call sub_E7CFC ; Call Procedure
E649:18EB retf ; Return Far from Procedure
E649:18EC ; ---------------------------------------------------------------------------
E649:18EC call sub_E7D0A ; Call Procedure
E649:18EF retf ; Return Far from Procedure
E649:18F0 ; ---------------------------------------------------------------------------
E649:18F0 retn ; Return Near from Procedure
E649:18F0 ; ---------------------------------------------------------------------------
PDM_2:
In the few roms I have looked at the $PDM has been found in the ROMEXEC0.ROM file. The entire BCP table structure can be found below the $PDM entry. The PDM call locations for me is in the BIOSCOD02.ROM file. I loaded up my ROM in IDA and adjusted it to get the correct offsets. To get your actual offsets will require forcing the memory locations when loading in IDA. You can also use a NDISASM to decompile your rom images but this is not always accurate because you don't know what the start location of the CODE section is. The rom has no structure like an exe does. You need to load up in 16 bit mode. example of using NDISASM.
ndisasm -a -p intel -b 16 input.rom > output.dasm
NVRAM: NVRAM holds the entire token table assigned by Standard Defaults Table and Manufacture Defaults Table. Look for the BCPNV in memory or the ROMEXEC file. This is similar pattern with many of the table structures. See below romexec and memory. The 1F is the length from BCPNV to end. The bytes that follow are the locations stored in endian format. 32,66 is memory location F000:6632. If you use dos debug. cmd prompt. type in DEBUG. screen should have blinking cursor -. d F000:6632 <- use your memory location not mine. enter q to quit
Code:
romexec 51C3:
h: 10 42 43 50 4E 56 20 00 01 1F 00 00 32 66 32 66 .BCPNV .....2f2f
h: 00 00 4A 46 FF FF B8 69 12 70 B0 66 30 68 2C 3B ..JF...i.p.f0h,;
memory
F000:6630 42 43 50 4E 56 20-00 01 1F 00 00 32 66 32 BCPNV .....2f2
F000:6640 66 00 00 4A 46 FF FF B8-69 12 70 B0 66 30 68 2C f..JF...i.p.f0h,
6632 is the CMOS Default Table Offset, the second 6632 is the size.
464A is the CMOS Checksum
FFFF is CRC Mask
69B8 offset starts the Token Table.
7012 offset ends the Token Table.
66B0 offset starts the Standard Defaults for NVRAM
6830 offset starts the Manufacturing Defaults for NVRAM
3B2C offset starts Media for NVRAM.
Using PBE, you can see the same results from the BCP menu.
If you use dos DEBUG for those locations offset locations you will see your tables in memory. d F000:69B8 will show the Start of Token table.
To find the physical locations in the file just do the math to find the offset. Using 6632 as the ref point. In my romexec, 6632 is the same as 51C3. The offset for the token table start is 69B8. 69B8 - 6632 = 386. Add that to physical location. 51C3 + 386 = 5549.
TOKEN TABLE:
The toke table is a table by 3's. Every 3 bytes is a new table. The location matches the offset of the file location. So it makes a lot easier to just copy the entire table to a new file. 01 8F 00 is the first token, 0. To save for size, I'm not going to cut n paste the entire table. Only going to show the first 3F bytes of the Token table. My token table is 659h in size.
Code:
5540h: 00 24 4E 56 54 01 01 12 70 01 8F 00 01 23 01 41 .$NVT...p....#.A
0 1 2 3 4 5 6 7 8 9 A B C D E F
0000h: 01 8F 00 01 23 01 41 A7 01 51 33 03 51 34 03 51 ....#.A..Q3.Q4.Q
0010h: 35 03 51 36 03 51 37 03 51 38 03 51 39 03 51 3A 5.Q6.Q7.Q8.Q9.Q:
0020h: 03 51 3B 03 51 3C 03 51 3D 03 D0 E4 30 50 86 02 .Q;.Q<.Q=...0P..
0030h: D0 E0 30 08 00 90 00 50 70 00 58 00 00 59 60 00 ..0....Pp.X..Y`.
So Token 0C is [51 34 03] [x1 xx xx], the 1 in 51 means Media 1, [xx 34 x3] the token start location or bit start is 334, [xx xx 0x] the 0 is the width bit. Add 1 to what ever this number is. So my token 0C starts at 334 and is 1 bit width with possibly of max value 1, 1 or 0. Do this for every 3 bytes. The next token would be 0F. 51 35 03 Token starts at 335, width is 1, media location 1... Tokens are stored in memory in by the starting sort order. So for these two, the entries are together in memory. bit 334 and bit 335. If you were sort your final table, sort by media store then start location. The location will follow by width plus byte. So if a token is 4 bits width, the next token start will be 4 bits away. ex if token 37 was 4 bits wide starting at 336, the next available location would be 33A. No token table would start at 338 in that media store.
TOKENS:
From the BCPNV table go to the Standard Defaults Table offset. The ending byte is the byte before the start of the MFG table. Mine is 17F bytes length. Copy and paste both tables into new files. This helps with the locations. Below is my Std table and Media Store. Media store is going to make 8 locations. 0 - 7 Grab the first F bytes.
Code:
Std Default Table
0000h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0010h: 40 46 00 C8 01 00 00 00 00 00 00 60 02 22 B8 14 @F.........`."..
0020h: 42 C0 11 A9 0D 39 F8 04 82 05 84 60 20 8A 00 00 B....9.....` ...
0030h: 00 00 20 00 00 02 00 00 00 00 00 00 00 00 00 00 .. .............
0040h: 00 00 00 00 33 00 00 00 00 40 F0 FF 01 FC 01 C0 ....3....@......
0050h: 84 00 00 00 00 00 00 00 68 04 E0 FE FF 01 00 02 ........h.......
0060h: 11 30 11 11 11 11 00 0F 00 00 00 00 0F 40 F4 8B .0...........@..
0070h: 00 00 64 EF 48 84 00 90 04 E0 90 86 00 00 00 80 ..d.H...........
0080h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0090h: 00 80 00 00 00 01 00 00 00 00 00 00 00 00 00 00 ................
00A0h: 00 00 00 00 00 00 00 00 00 00 64 03 D0 95 BD 0F ..........d.....
00B0h: 00 01 00 00 00 00 00 40 00 00 00 00 00 00 00 00 .......@........
00C0h: 00 00 00 00 00 00 00 02 00 00 00 10 00 02 40 40 ..............@@
00D0h: 18 00 00 E1 E4 00 00 00 10 00 40 00 00 01 00 04 ..........@.....
00E0h: 00 10 00 40 00 00 39 00 60 BC 1F 00 00 00 00 00 ...@..9.`.......
00F0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 5A ...............Z
0100h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0110h: 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 ................
0120h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0130h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0140h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0150h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0160h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0170h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
Media Table
0000h: 00 00 00 04 00 08 A8 08 A8 08 B0 08 B0 08 B0 08 ................
Media Table broken down.
Media 0 = 0000
Media 1 = 0400
Media 2 = 0800
Media 3 = 08A8
Media 4 = 08A8
Media 5 to 7 = 08B0
The media table represents the max amount bits can be stored in that table. Media 0 starts 00. Media 1 starts at 400h so 3FFh is the last bit of media 0. Converting the entire range into binary would result in 3FF entries of 1's 0's. So we have two sets of bits 3FFh wide. Media 2 starts 800, 3 08A8 etc... The table needs to broken down into what holds what media location in bytes. So 400h bits can be represented by our bytes table by dividing it into 8 bits. 400h / 8h = 80h Media 1 starts at 80h. So 0 - 7F is Media 0, 80h - FFh is Media 1. 100h starts Media 2 but is 15 bytes len because Media 3 starts 08A8. 115h starts Media 3 and 4.
Token Value:
Use the locations of the table above to figure out what the value of the token is. In the example above we used 334 Media 1. 334 divide by 8, be sure in hex. 334 / 8 = 66 not using remainders in Hex. 66 * 8 = 330. So 66h is the location in media 1. Media 1 starts at 80h + 66h = E6h Token at E6 is 39, use the table above. Break 39 down into binary. 00111001 Take 66 and multiply by 8 to get where the bits start is. 66h * 8h = 330h So the start location of our binary number for 39h is bit 330. Working in reverse order here.
Code:
0 | 0 | 1 | 1 | 1 | 0 | 0 | 1
337 336 335 334 333 332 331 330
Bit 334 is enabled Change bit 334 to 0 and convert the binary back to hex. 00101001 is 29h So E6 can hold 8 bits of info. If 334 and 333 were both disabled, E6 will become 21h.
Token Ref:
That is break down of the token table. Now to find out what token represents what value. IE find out what token 0C, at start point 334, in media 1, is represented at location E6 with the value of 39. The easiest way is to use SYMCMOS tool from Phoenix. Take this tool and your strings.rom and template.rom and you have a complete map of your system. This also allows you to map out your BIOS Setup to enable options in your BIOS. It's not the only way, you can do it manually or parse the file with your own code to dump it.
SYMCMOS:
First you need to run this tool from a boot disk. Running from inside windows will cause problems with memory locations and access rights. freedos is supported by this tool.
I am going straight into the functions needed to get a dump but it does more than this.
rename templat0.rom to nodes.rom, rename strings0.rom to strings.rom
Run symcmos -v2 -C This will combine the two files in regions for symcmos to map out. It creates a file called combine.rom
run symcmos -v2 -Fcombine.rom -Ssymbol.txt >symbol_.txt The ">sysmbol_.txt" is going dump/pipe the screen output into a text file. Run it without the pipe to see it in action. It displays a bunch of info not included from the dump file. There are no spaces after the -S -F and file name.
Now run it with -L for a list file that can be edited and imported.
symcmos -v2 -Lliteral.txt Output the pipe again to a text file to keep a list of the skipped. The -L dump you can import a new bit setting for any token if it is writable. Read more in the documents about using symcmos.
Note different versions of symcmos display more info than others in the output screen.
Now if your PC was the same as mine you would get a print out and see that 334 is really AHCI in the Advanced menu of the BIOS:
Code:
Advanced
Internal_Device_Configurations
_AHCI_Configuration:
( token 0xC start 0x334 width 0x1 )
( maximum 0x1 default 0x1 PICK_FIELD )
= [0] Disabled
=* [1] Enabled
writeOptions(00h,14h,0808h,0806h,5e6ah,5eb3h,) ...
( token 0xC start 0x334 width 0x1 ) max 0x1, default 0x1
Now because this symcmos read the settings directly from the NVRAM location we get our current settings that matches the bios rom file we are using. If you use a bios file not for the PC you are running it on, it will fail. For this you need to patch the tool, code your own or modify the symcmos tool to read physical memory location or patch the segment and manually load up the tokens in memory to a matching segment. You could parse this info out with a perl script, just need to know how the setup is created...
Setup:
The setup table is controlled by the templat0.rom and strings0.rom files. You will need to copy the bytes of the strings0.rom file to a new file and delete the header so the offsets match up.
Code:
0000h: 53 54 52 50 41 43 4B 2D 42 49 4F 53 00 00 00 00 STRPACK-BIOS....
0010h: 00 00 00 00 00 00 00 00 02 00 02 00 F9 8D 52 03 ..............R.
0020h: 75 73 1A 00 D3 64 E0 08 EF 08 19 09 39 09 84 09 us...d......9...
All the bytes up to F98D are header. Remove. the 02 00 02 00 means there are two languages in this file. F98D is the length of the first language, after 8DF9: starts JP (Japan) our section is EN (US). Yours may have more or only 1. This should be the same file as OLD.RLS from unpacking the bios.rom in Phoenix Bios Editor. PBE divides them up by OLD1, OLD2, OLD3.RLS
So the file I am working with will starts off like this.
Code:
0000h: F9 8D 52 03 75 73 1A 00 D3 64 E0 08 EF 08 19 09 ..R.us...d......
0010h: 39 09 84 09 AD 09 BC 09 E5 09 00 0A 0A 0A 16 0A 9...............
0020h: 25 0A 34 0A 43 0A 52 0A 61 0A 70 0A 7F 0A 8E 0A %.4.C.R.a.p....
0030h: 9D 0A AA 0A B1 0A B6 0A C8 0A D3 0A EB 0A 10 0B ................
0040h: 25 0B 2A 0B 2F 0B 34 0B 39 0B 3E 0B 43 0B 48 0B %.*./.4.9.>.C.H.
0050h: 4D 0B 52 0B 57 0B 5C 0B 61 0B 66 0B 6B 0B 70 0B M.R.W.\.a.f.k.p.
0060h: 75 0B 7A 0B 7F 0B 84 0B 89 0B 8E 0B 93 0B 98 0B u.z............
0070h: 9D 0B A2 0B A7 0B AC 0B B1 0B B6 0B BB 0B C0 0B ................
This file is a map in table format that is linked to the offsets from the template file (nodes). The NODES are mapped in a continous jumps until it reaches 0000. 0000 is the end of that one node. When the node is terminated it jumps back to the last jump it came from.
Below is a clip from the strings rom. At location 0674: 09 67 This points to 6709: Byte 4D for Main, the 00 byte terminates after Main.
Code:
0670h: F5 66 01 67 09 67 0E 67 1D 67 3A 67 50 67 7D 67 .f.g.g.g.g:gPg}g
6700h: 00 4D 61 67 65 6E 74 61 00 4D 61 69 6E 00 4D 61 .Magenta.Main.Ma
In the nodes file (templat0.rom) an offset calls to location 0674 in the format of 74 06.
Code:
11ADh: 10 0A 74 06 00 00 6B 39 98 39 ..t...k9.9
Location at 11AD: which is also linked as AD 11 in the node table.
These bytes I am still working on a few items. What I have worked out is the first byte determines the type. The 2nd byte is the total length starting from first byte. The 3rd and 4th byte are the 1st table reference in strings.rom. The 5th and 6th byte are the 2nd table reference in strings.rom. (item and description) IE 1st jump = "Floppy Fisk A:" 2nd jump = "Sets Floppy Disk A type to blah blah..." If the 2nd table is 00 00, node is terminated there is no 2nd ref. Probably just a blank space or information field. So with this example the BIOS setup screen; the word Main shows up with nothing in the second field.
The calling jump will be linked to the first byte location; 11AD: in the format AD 11
Code:
0170h: 00 00 AD 11 8E 01 99 11 0E 03 B7 11 52 06 37 1F ............R.7.
0180h: 56 09 A7 12 B4 08 A3 11 F4 08 00 00 00 00 33 13 V.............3.
0190h: 00 00 23 11 00 00 EF 10 00 00 C1 11 00 00 4F 0C ..#...........O.
01A0h: 00 00 C1 11 00 00 31 18 3E 02 25 18 02 02 19 18 ......1.>.%.....
At location 0172: you see AD 11 8E 01. This is the beginning of ROOT for the menu items. It is one continous jump and return. 0000 0000 ends the node and sends return back. 11AD is [Main] linked to offset 018E in nodes. So jump to 11AD get info until 0000, return and check if we are linked or 0000. It's linked to 018E, jump to 018E until 0000 then return. Goto 1199 [Advanced] return, jump to 030E till 0000 return. These first rows are your front page in BIOS Setup. Now if the first link had 0000 next to 11AD we jump to next table 1199 instead. AD 11 00 00 99 11 0E 03. This means there is nothing linked to 11AD. Just goto 11AD get the data from strings and return back, jump to 1199.
11AD Main
1199 Advanced
11B7 Security
1F37 Boot
12A7 Info
11A3 Exit
0000 0000 End
Notice after 0000 is the file offset 018E is linked to [1333] This is the first jump location linked from Main 11AD. So the entire table nodes that are linked to 11AD are read first, the entire contents of Main. Then come back and read entire contents of Advanced, etc. The first jump is to a lower location in the template that is providing info for table entry in strings. Lets follow 1333.
1333 Node
Code:
1333h: 10 0A 00 00 00 00 75 41 69 41 ......uAiA
10 = Type General Text, 0A is length then 0000 Blank space just return.
Return back to 018E, linked? No goto 1123.
Code:
1123h: 21 0A 92 08 90 08 E4 36 EF 36 !......6.6
21 = Time Len 0A, 1st offset in strings is 0892: 2nd offset is 0890. 36E4 36EF are fillers, jumps to 55 8B nodes.
Jump to 0892: and 0890 in strings.
0890h: 2A 31 FD 87 0A 88 45 88 62 88 B0 88 C0 88 C3 88 *1....E.b.......
....
This jumps to 87FD and 312A in strings and look for text, store the values and return to call.
Code:
87FD: System Time:
87F0h: 00 54 4D 31 20 61 6E 64 20 54 4D 32 00 53 79 73 .TM1 and TM2.Sys
8800h: 74 65 6D 20 54 69 6D 65 3A 00 43 6F 6E 74 72 6F tem Time:.Contro
312A: Adjust calendar clock...
3120h: 00 43 79 61 6E 00 4D 44 59 00 41 64 6A 75 73 74 .Cyan.MDY.Adjust
3130h: 20 63 61 6C 65 6E 64 61 72 20 63 6C 6F 63 6B 2E calendar clock.
3140h: 0D 0D 3C 54 61 62 3E 2C 20 3C 53 68 69 66 74 2D ..<Tab>, <Shift-
3150h: 54 61 62 3E 20 6F 72 0D 3C 45 6E 74 65 72 3E 20 Tab> or.<Enter>
3160h: 73 65 6C 65 63 74 73 20 66 69 65 6C 64 2E 00 53 selects field..S
Here is an example of one with data fields. The call is coming from a linked chain in the Advanced menu to location 03EE:
Code:
0E33 03EE: 00 14 E4 02 E6 02 A7 2A C9 2A 91 2A 9C 2A F8 01 0A 07 12 07
00 = Pick Field. 14 Length. 02E4, 02E4 call to stings. 2AA7, 2A91, 2A9C Fillers. [F8 01] Token 1F8. 070A, 0712 Call to strings.
02E4: in strings, jumps to "Virtualization Technology:"
02E6: in strings, jumps to "Select Virtualization.."
F8 01 TOKEN 1F8 [50 13 01] START 113, WIDTH 1 (0+1) MAX SIZE 1 [1], 50 MEDIA 0
0A 07 070A: Disabled
12 07 0712: Enabled
Several locations are shared values. Like 070A and 0712 are called to many times as the text is seen many times in your setup menu.
00 = Pick Field
01 = Pick Field
10 = Generic Text
11 = Information
21 = Time
22 = Date
23 = Free form Hex
more
As long as there is a return closing the node 0000, you can call to locations that are not in your menu screen. There are several tables that call to the same Blank space, this is just for spacing on your setup menu. If you know where the lower table entry is, swap out the call location to your menu you want displayed. Store it in the same pattern. So if I wanted to replace blank space with VT Bit, change the call 33 13 to 33 0E. Sometimes 0000 0000 has been entered to terminate the node menu, insert a call location to the blank space or other menu item so the jumps continues on to the disabled options. You can find these by following the calls to linked menus. The final call should end 0000 0000, the next address should be linked to the next menu item in return call. If it's not linked to anything above, this is an inserted terminated return to hide those options. Insert a call to black space, next time the menu is read those options should be visible. You can verify this with PBE. After you edit the templat0.rom, rebuild the rom, save and open the new rom. Click the setup menu and you should see them listed, click emulate.
Some roms like this one, the items in the menu are disabled another method. I am still looking to prove the reason. I think it has something to do with the hole.rom. There is another table inside the setup listed under $PDW string in the template. I have not looked much further into this one.
Code:
0AA0h: 00 00 D4 08 F6 04 C8 02 00 00 24 50 44 57 01 00 ..........$PDW..
0AB0h: E2 0A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0AC0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0AD0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0AE0h: 00 00 2E 83 3E BC 0A 05 0F 83 AA 00 2E 89 2E BA ....>...........
..
If anyone has some corrections or add on please let me know. This is still a work in progress. Knowing how the table is called, you control what is shown. Unlocking the setup could open up some more mods methods. The hole locations seem to store some info from the CMOS and DMI set by the OEM. The store method has been similar. locations with types, length and check sums. Tables stored in bits that can be mapped out with byte tables...
credit to some of the info
Examples on understanding the PDM and NVRAM http://intuitivenipple.net/bios/example/
wimbios thread on hacking nvram posted by intuitivenipple
intel and phoenix bios docs
symcmos ftp://ftp.supermicro.com/utility/Phoenix_bios_utility/
symcmos and nvram, other phoenix tools http://www.users.on.net/~fzabkar/BIOSutil/Phoenix/
ndisasm http://sourceforge.net/projects/nasm/
ida http://www.hex-rays.com/idapro/idadownfreeware.htm
insight debug http://www.bttr-software.de/products/insight/
olly debug http://www.ollydbg.de/
fujitsu bios file used to ref n6410 bios 1.09 http://support.fujitsupc.com
Bookmarks