Preliminary Bios Modification Guide

Table of Contents

  1. Bios Chip Hacking Trick. This part discuss how to do a hotswapping procedure to backup your current bios.
  2. Preliminary Award Bios Modification Guide. This part discusses how to modify/hack your bios to patch certain things.
  3. Pinczakko notes on building an error free .COM file using MASM611.

Bios Chip Hacking trick

Finally I found the trick to hack my bios safely without using the so called Bios Savior, the trick as follows:

  1. Use a bios chip (FlashROM) with the same type as the one in your current Mobo as a backup in case something went wrong. To do so, remove any protectors that avoid you from seeing the type of your mobo bios chip (Usually Award or Ami logo(s)), this will void your warranty, so proceed at your own risk. Then identify it, in my case it's written as follows (in the top of the chip):
       Winbond W29C020C-90B
    where the W prefix means built by Winbond and the xxxxxxxxxxx perhaps is the batch number. And the bios chip type is 29C020 , in my experience the C after W29c020 doesn't really matter and the postfix 90 need to be concerned, it means 90 ns access time. The chip I use as a backup chip is:
       Atmel AT29C020
    xxxxx 90
    where the AT prefix means made by Atmel and the 29C020, and 90 means 90 ns access time.

    !!! CAUTION !!!
    do these first:

    • Find the datasheet of the bios chip of your current motherboard.
    • Find the datasheet of the bios chip you're gonna use as a backup.
    • Make sure both the chip compatible each other in terms of voltage level (in my case 5 volts-only), capacity (in my case 256KB), access time.
    • ALWAYS double check chip position every time you're going to insert the bios chip into your mainboard, because if it's wrong there's a big chance u're destroying the chip.
  2. Do a hot flash (hot swapping), and flash the bios binary file to the bios chip (in my case the Atmel one). Remember the caution above !.

    Double check chip position every time you're going to insert the bios chip into your mainboard. If it's wrong there's a big chance u're destroying the chip.

    Alert !!!
    In this step BUG sometimes occur. As in my case, at first I use UNIFLASH ver 1.25 (since it's mentioned in the readme file that AT29c020 already verified with the flasher ). But BUG OCCUR, the flasher didn't recognize the Atmel chip. I'm aware that the flasher have some problem with my northbridge VIA693A aka VIA Apollo Pro 133, and that could be the cause of this BUG.

    Legacy solution :
    Then I decide to use awardflash version 7.31, the one comes with the mobo bin file, it works :).

    Update: This is not a problem anymore and has been fixed in later version of uniflash. The version that I'm using now is uniflash 1.34 and it worked without problem at all.

  3. Now you get a brand new backup bios without using Bios Savior. cool isn't it ... :)
    Note: my system is as follows:
    Processor Intel(R) Celeron (tm) 300A @ 540 MHz
    Processor converter card Abit Slotket III VCore @ 2.05 Volts VIO @3.4 Volts
    Motherboard Iwill VD133 (Award modular bios v4.51 PGNM, VIA693A Northbridge, VIA596B Southbridge, bios version : July28th 2000 [VD30728.bin])
    Harddrive Maxtor 2B020H1 ATA100 20GB 5400RPM
    CDROM Teac CD-540E
    SDRAM 256 MB CL2 timing turbo @ 120 MHz
    Video Card Power Color Riva TNT2M64 with hacked bios (AGP), TsengLabs ET6000 video card (PCI)
    Sound Card Addonics SV550 (Yamaha 724 chip w/ preamp.)
    Anyway remember that when flashing the bios I remove the Sound card, and disconnect all IDE (ATAPI) connector from the mobo to prevent any error that may damage the system. Then booting safely from the floppy disk (sometimes fron CDROM too).

    April 17th 2002 : Bug Found
    I've tried to flash a beta bios to this chip this morning (April 17th 2002) and it always failed to write at some sectors so sometimes I've got to do it couple of times to get flashed entirely without a damaged (un-writed segment). I'll try the uniflash anyway by using the -force option to force the flashing procedure, and let's see which flasher is the better one.

    June 18th 2002 : Partial solution to the bug :)
    Today the same bug occur again but in rather different form. At first I flashed the chip w/ a modded bios, and it get flashed (by using awdflash 7.31) unfortunately the bios couldn't POST so I do a hot flash w/ my real bios chip, the one that come w/ the mobo. Unfortunately I never managed to finish the flashing process in normal way, and the chip got wrong binary written into it. Then I try to use the same flasher(awdflash 7.31) and also tried Uniflash to fix the content of the chip, but it just couldn't even do the flashing process. After many times trying it. Finally I decided to try to use another awdflash version, and I got awdflash 7.76b that come w/ Iwill BD100Plus mobo, it's also an award 4.51PGNM version so it's safe to be used, then I do a hot flashing, and the flashing process run smoothly i.e. it worked well :).

    This is not a problem anymore and has been fixed in later version of uniflash. The version that I'm using now is uniflash 1.34 and it worked without problem at all.

Preliminary Award Bios Modification Guide

Before proceeding to the tutorial, I assume that you already knows the basic structure of an x86 mainboard bios file, i.e. what is original.tmp and what is an option/expansion rom. If you don't, then look for some info on the web. I'll provide these info's in this website when I have enough time to type it down :).

Here's another important thing to note: The ISA option ROM vs PCI option ROM . I've tried to add option rom which is exactly the same using /PCI and /ISA option in CBROM ver 2.07 but it behaves really different, as a note, I built the option rom using plain *.com file using masm with ml version 6.14 (from masm32 distribution) and link.exe version 5.31 from masm611 distribution, the description is as follows:

  • The /ISA version behaves as expected.
  • The /PCI version didn't even execute, but I neither add the PCI header in the binary nor the other IDs such as PCI ID, perhaps this is the cause, but I believe may be the BIOS code itself searches for a valid device for every single PCI option rom added to the BIOS.
So, we'll stick to the proven solution, i.e. the ISA option ROM. You are free to test the PCI option ROM and if you are success to implement it, please inform me.

Finally I know the reason why the PCI expansion ROM version, is not executed. To be able to successfully execute PCI expansion ROM there are 2 things that have to be accomplished :

  • The XROMBAR (Expansion ROM Base address) register in the PCI chip itself have to be enabled, so that it is possible to map the expansion ROM bios chip in real mode into the processor address space
  • The PCI CHIP ID and the PCI Vendor ID in the ROM code have to match the PCI CHIP ID and PCI Vendor ID in the real PCI chip (that's hardwired in the chip)
-- END UPDATE -- The purpose of this mod is to patch certain chipset registers in Host bridge (contained in the northbridge chipset of my mobo). There are two ways to accomplish the task:
  • By modding original.tmp (main bios file extracted from a bios file) chipset register default value.
  • By adding a new isa expansion/option rom file by means of CBROM to the original mainboard bios file (target bios).
detailed description :
  • To mod original.tmp, first extract original.tmp from the original bios file using awardmod, modbin or other tools. In this case I use awardmod. Then edit the chipset register default value by searching the following bytes:
    02 70 00 
    the value means :
    • 02 -- somekind of separator between registers value
    • 70 -- register number 70
    • 00 -- device number 0 function 0 or hostbridge main function device the complete bytes value depends on your bios but at most you�ll find this bytes only once in original.tmp. The address where you�ll find these bytes may vary but in my case it�s around 10e30 or segment 2 address 0e30. The above value have the format:
      02 70 00 xx xx yy yy
      where :
      • 02 -- somekind of register separator
      • 70 -- register number 70
      • 00 -- dev 0 function 0
      • xx xx -- mask of the register�s default value
      • yy yy -- Default value of the reg (offset)
      The mask bit were ANDed w/ default value to obtain the desired chipset register default value. Most of the time I modded the mask bit and the default value to get the desired tweaked value.
      • Before you use the modded bios (of course after packing the original .tmp and other components back by using awardmod in my case), check wheter it is GOOD or BAD by using modbin and cbrom. To do so, just open it, and see if it�s not odd looking. I Use HEXWORKSHOP and Hiew.exe to edit the original.tmp
      • This method only tested on awaard bios version 4.5x PGNM, haven't been tested on another award bios version. Some of my friend confirm that this is not working i.e. different in award bios version 6.0 PGNM but I haven't got the time to do a crosscheck.
  • To mod in the second way, make an ISA option/expansion rom. Building *.rom , i.e. expansion rom from plain binary file (*.com) you've created is pretty easy. But, before proceeding further, let me tell you what a *.rom file really is. Based on my recent "research", a *.rom file actually is a binary file that conform the following conditions:
    • It's a plain binary file.
    • Its size is a multiple of 512 bytes.
    • Its header has the following format:
      1. 1. 55AAh ;this is the 1st and the 2nd byte, its a bootable code sign, it's actually AA55h, but Intel uses little endian that's why it's reversed.
      2. 2. xxh ;this is the 3rd byte, where xx is the hex number that indicate the size of the rom in multiple of 512 bytes, e.g. for a 512 bytes rom it will be 01h.
      3. 3. jmp ;Commonly this is the 4th through 6th byte, usually this is a near jump instruction that invoke the real initialization code of the rom.
      4. 4. ret (far);the last byte in the header, it invokes a far return to pass the program execution back to the main bios (original.tmp), you can invoke it in the initialization part as well, so this is not a must have. See the example code for more info�s.
    • Its byte checksum is exactly zero, i.e. after all of its bytes summed and goes through modulo 100h operation, it's equal to zero. In practice this should be pretty easy, for example if you use Hexworkshop version 3.0, from Tools menu choose generate checksum and choose byte (8 bit) checksum to see the checksum of your file, for a valid rom it should be equal to zero, this can be very handy if you want to turn your plain binary file into a valid rom, just open the file using Hexworkshop or similar hex editor program and then generate the checksum of your *.com file, if it's not zero then substract the remainder of your current checksum from 100h, this is the byte you need to insert into your plain binary file, for example if the remainder shown in Hexworkshop is 0x2C then you will need to add D4 (4D will also works) into your file. I usually add this byte into the end of the program to compensate for the checksum needed, after the return instruction, so that it won't interfere with your main code.
    O.K., after knowing how the exact format of a rom file we only need to concern about how to implement it.
    1. First, the header format should be eeasy to be handled in assembly (masm syntax), we only need to generate a plain binary file i.e. building a *.com file if we're using masm.
    2. Second, to get the real *.rom file wwe neeed a hexeditor i.e. hexworkshop and compensate for the size and checksum so that the expansion rom wouldn't be rejected by cbrom. To compensate for the size, just insert 00h as much as possible until it's size is a multiple of 512 bytes from Edit|Insert menu in Hexworkshop then proceed to compensate for the checksum as explained above and voila'... you're done :)
    3. Here's an example of a working source code in plain binary (it uses masm, so just build ordinary *.com file and then adjust the checksum using a binary hex editor such as hexworkshop 3.0).
      ;;------------------- TEST.ASM ---------------------------------------------------
      ;;Macro definition
      PATCH_PCI  macro  reg_addr,mask
              mov     eax,reg_addr    ;fetch  addr of the regs to be patched
              mov     dx,in_port      ;fetch input port addr of PCI cfg space
              out     dx,eax
              mov     dx,out_port 
              in      eax,dx
              or      eax,mask        ;mask the regs value (activate 
                                      ;certain        bits)
              out     dx,eax
              ASSUME CS:CSEG
              ORG 0
      ;;Expansion rom header
              DB      55h             ;;Rom signature byte 1 
              DB      0AAh            ;;Rom signature byte 2
              DB      01h             ;;512 bytes
              call    INIT            ;;jump to initialization
              retf                    ;;return far to main bios routine (original.tmp)
      ;;equates, have been tested d00d & works fine
              in_port         equ 0cf8h
              out_port        equ 0cfch
              ioq_mask        equ 00000080h
              ioq_reg         equ 80000050h
              bank_mask       equ 20000844h
              bank_reg        equ 80000068h
              tlb_mask        equ 00000008h
              tlb_reg         equ 8000006ch
              dram_mask       equ 00020202h
              dram_reg        equ 80000064h
              ORG 100h
      INIT    PROC    NEAR
              PATCH_PCI ioq_reg, ioq_mask             ;patch the ioq reg
              PATCH_PCI dram_reg, dram_mask   ;patch the DRAM 
                                                      ;controller i.e. the 
                                                      ;interleaving part
              PATCH_PCI bank_reg, bank_mask   ;patch bank active 
                                                      ;page ctl reg
              PATCH_PCI tlb_reg, tlb_mask             ;Activate Fast TLB 
              retn                    ;return to this rom's header 
      INIT    ENDP
              ORG 200h                ;extend the file into 512 bytes
      CSEG            ENDS    
      ;;-------------------------- END OF TEST.ASM ------------------------------------
      Here's the resulting hexfile:
      Address         Hexadecimal contents                             ASCII
      00000000     55AA 01E8 FA00 CB4D 0000 0000 0000 0000         U..............M
      00000010     0000 0000 0000 0000 0000 0000 0000 0000         ................
      00000020     0000 0000 0000 0000 0000 0000 0000 0000         ................
      00000030     0000 0000 0000 0000 0000 0000 0000 0000         ................
      00000040     0000 0000 0000 0000 0000 0000 0000 0000         ................
      00000050     0000 0000 0000 0000 0000 0000 0000 0000         ................
      00000060     0000 0000 0000 0000 0000 0000 0000 0000         ................
      00000070     0000 0000 0000 0000 0000 0000 0000 0000         ................
      00000080     0000 0000 0000 0000 0000 0000 0000 0000         ................
      00000090     0000 0000 0000 0000 0000 0000 0000 0000         ................
      000000A0     0000 0000 0000 0000 0000 0000 0000 0000         ................
      000000B0     0000 0000 0000 0000 0000 0000 0000 0000         ................
      000000C0     0000 0000 0000 0000 0000 0000 0000 0000         ................
      000000D0     0000 0000 0000 0000 0000 0000 0000 0000         ................
      000000E0     0000 0000 0000 0000 0000 0000 0000 0000         ................
      000000F0     0000 0000 0000 0000 0000 0000 0000 0000         ................
      00000100     6660 66B8 5000 0080 BAF8 0C66 EFBA FC0C         f`f.P......f....
      00000110     66ED 660D 8000 0000 66EF 66B8 6400 0080         f.f.....f.f.d...
      00000120     BAF8 0C66 EFBA FC0C 66ED 660D 0202 0200         ...f....f.f.....
      00000130     66EF 66B8 6800 0080 BAF8 0C66 EFBA FC0C         f.f.h......f....
      00000140     66ED 660D 4008 0020 66EF 66B8 6C00 0080         f.f.@.. f.f.l...
      00000150     BAF8 0C66 EFBA FC0C 66ED 660D 0800 0000         ...f....f.f.....
      00000160     66EF 6661 C300 0000 0000 0000 0000 0000         f.fa............
      00000170     0000 0000 0000 0000 0000 0000 0000 0000          ................
      00000180     0000 0000 0000 0000 0000 0000 0000 0000         ................
      00000190     0000 0000 0000 0000 0000 0000 0000 0000         ................
      000001A0     0000 0000 0000 0000 0000 0000 0000 0000         ................
      000001B0     0000 0000 0000 0000 0000 0000 0000 0000         ................
      000001C0     0000 0000 0000 0000 0000 0000 0000 0000         ................
      000001D0     0000 0000 0000 0000 0000 0000 0000 0000         ................
      000001E0     0000 0000 0000 0000 0000 0000 0000 0000         ................
      000001F0     0000 0000 0000 0000 0000 0000 0000 004D         ................. 
      1. Take a look at the header, you get thee magic number 55AAh, then 01 which is the checksum that indicates a 512 bytes option rom file, then E8 FA 00 , it is a near call instruction, with FA relative displacement to main procedure that located in 100h address. Then followed by CB which is decoded to a far return to a calling procedure, in this case the main bios (original.tmp).
      2. Then now the main procedure. If we decoded the instruction, we would find this code:
           pushad          ;32 bit pushad (that's why uses 66 prefix) to save all regs
                mov eax,80000064        ;enable pci configuration access mechanism 1 to offset 64 
                mov dx,0cf8     ;of device 00:00:00
                out dx,eax              
                mov dx,ocfc     ;get the data of offsets 64,65,66
                in  eax,dx              
                or  eax,00020202        ;turn on bit 1 of offsets 64,65,66
                out dx,eax                              
                ...             ;these instruction repeat above codes to set different
                ...             ;offsets
                popad           ;32 bit popad (that's why uses 66 prefix) to restore all regs
                ret             ;near return to the header post E8 FA 00
        • The 4D in the last byte of the option room was added by me (it is previously 00h after assembled) to make the file 8 bit checksum equal to 00h, i.e. sum all the bytes and mod 100h is 00h.
        • This method works great for me, I wish to know if it's not working in certain circumstances.

Pinczakko notes on building an error free .COM file using MASM611

  1. The general form of a com file in MASM611 to generate an x86 ROM file as follows ( This is a real working example ) :
    .386                    ;;Processor type to use (actually) availabe GPR
    option segment:use16    ;;USE 66h,67 prefix for 32 bits operand
    .MODEL TINY             ;;generic com file format
                            ;;This is where you should put your macro declarations
    org 100h                ;;com begins at 100h, then comes the real routine
            pushad                  ;save all GPR
            mov eax,dram_reg        ;fetch the address of the regs
            mov dx,in_port          ;fetch the input port addr config space
            out dx,eax
            mov dx,out_port 
            in  eax,dx
            or  eax,dram_mask       ;mask the regs value 
            out dx,eax
            popad                   ;restore all GPR
            retn                    ;return near to the header
    ;;The following part actually not only for equates but possibly also for 
    ;;data declaration 
            dram_mask       equ 00020202h
            dram_reg        equ 80000064h
            in_port         equ 0cf8h
            out_port        equ 0cfch
            end start
  2. To build *.com file of the routines above (assuming the file named hello.asm), invoke the following :
    ML /AT hello.asm /link /TINY
    Note: remember to copy the link.exe file to ml.exe directory to execute the commands above. Also remember to place the file to be assembled in the same directory as ML.EXE and link.exe .
That's all. Happy modding, just find the tools needed and be aware that I have no responsibility to the damage that my occur if you are doing what I've explained here. Proceed at your own risk.

Latest update: August 10th, 8:22 JAVT

copyright © Darmawan M S a.k.a Pinczakko