VOGONS


First post, by EduBat

User metadata
Rank Member
Rank
Member

I looked around but could not find any practical way to get the BIOSes from my computers into files.
The programs I found were either too complicated (flashrom) or simple (romdumpr.)
The problem with flashrom is that it needs to be aware of the chipset and tries to get that by querying the PCI bus. A 486 computer without PCI will not work.
On the other hand, romdumpr just gets whatever is on the F000:000 segment at the time it runs. This presumes that the BIOS at the top of the 4Gbyte address space has a mirror image at that segment, which is not always correct. Most BIOSes run from the top of the 4Gb address space and then dynamically decompress themselves to RAM memory at F000:0000. (aka shadow ROM.)

Frustrated with this I decided to write my own generic BIOS dumper and the results are attached.
It should work on any computer with at least a 386 processor.
The only limitation is that it does not auto detect the BIOS size, which needs to be provided.
(Testing / comments are welcome.)
It runs on DOS (any version above 3) but should also work in FreeDOS (not tested,) in which case it can be placed on a Rufus formatted bootable memory stick and ran from there.

Reply 1 of 16, by zuldan

User metadata
Rank Oldbie
Rank
Oldbie
EduBat wrote on 2026-02-18, 19:52:
I looked around but could not find any practical way to get the BIOSes from my computers into files. The programs I found were e […]
Show full quote

I looked around but could not find any practical way to get the BIOSes from my computers into files.
The programs I found were either too complicated (flashrom) or simple (romdumpr.)
The problem with flashrom is that it needs to be aware of the chipset and tries to get that by querying the PCI bus. A 486 computer without PCI will not work.
On the other hand, romdumpr just gets whatever is on the F000:000 segment at the time it runs. This presumes that the BIOS at the top of the 4Gbyte address space has a mirror image at that segment, which is not always correct. Most BIOSes run from the top of the 4Gb address space and then dynamically decompress themselves to RAM memory at F000:0000. (aka shadow ROM.)

Frustrated with this I decided to write my own generic BIOS dumper and the results are attached.
It should work on any computer with at least a 386 processor.
The only limitation is that it does not auto detect the BIOS size, which needs to be provided.
(Testing / comments are welcome.)
It runs on DOS (any version above 3) but should also work in FreeDOS (not tested,) in which case it can be placed on a Rufus formatted bootable memory stick and ran from there.

Great little utility. Any chance there is an updated version with BIOS size detection?

Reply 2 of 16, by EduBat

User metadata
Rank Member
Rank
Member
zuldan wrote on 2026-04-25, 05:49:
EduBat wrote on 2026-02-18, 19:52:
I looked around but could not find any practical way to get the BIOSes from my computers into files. The programs I found were e […]
Show full quote

I looked around but could not find any practical way to get the BIOSes from my computers into files.
The programs I found were either too complicated (flashrom) or simple (romdumpr.)
The problem with flashrom is that it needs to be aware of the chipset and tries to get that by querying the PCI bus. A 486 computer without PCI will not work.
On the other hand, romdumpr just gets whatever is on the F000:000 segment at the time it runs. This presumes that the BIOS at the top of the 4Gbyte address space has a mirror image at that segment, which is not always correct. Most BIOSes run from the top of the 4Gb address space and then dynamically decompress themselves to RAM memory at F000:0000. (aka shadow ROM.)

Frustrated with this I decided to write my own generic BIOS dumper and the results are attached.
It should work on any computer with at least a 386 processor.
The only limitation is that it does not auto detect the BIOS size, which needs to be provided.
(Testing / comments are welcome.)
It runs on DOS (any version above 3) but should also work in FreeDOS (not tested,) in which case it can be placed on a Rufus formatted bootable memory stick and ran from there.

Great little utility. Any chance there is an updated version with BIOS size detection?

I tried, but I'm unable to come up with way to do it. When you try to read an area of the address space which has nothing assigned to it you get random data, which is indistinguishable from BIOS code, so I gave up for now.

Reply 3 of 16, by zuldan

User metadata
Rank Oldbie
Rank
Oldbie
EduBat wrote on 2026-04-26, 17:53:

I tried, but I'm unable to come up with way to do it. When you try to read an area of the address space which has nothing assigned to it you get random data, which is indistinguishable from BIOS code, so I gave up for now.

NSSI is able to do a BIOS dump without asking for the size. Not sure how it’s doing it.

https://www.navsoft.cz/products.htm

Reply 4 of 16, by zuldan

User metadata
Rank Oldbie
Rank
Oldbie

Maybe this will help

#include <stdio.h>
#include <dos.h>

#define BIOS_SEGMENT 0xF000

int main() {
unsigned char far *bios;
unsigned int size_blocks;
unsigned long size_bytes;

bios = (unsigned char far *)MK_FP(BIOS_SEGMENT, 0x0000);

/* Check signature */
if (bios[0] != 0x55 || bios[1] != 0xAA) {
printf("No valid BIOS signature found at F000:0000\n");
return 1;
}

size_blocks = bios[2]; // size in 512-byte units
size_bytes = (unsigned long)size_blocks * 512;

printf("Detected BIOS size: %lu bytes (%lu KB)\n",
size_bytes, size_bytes / 1024);

return 0;
}

Reply 5 of 16, by zuldan

User metadata
Rank Oldbie
Rank
Oldbie

If you wanted to get more than just the motherboard BIOS

- Scan the upper memory area (0xC0000–0xF0000)
- Detect all option ROMs (video BIOS, network boot ROMs, etc.)
- Detect the system BIOS
- Validate each ROM via checksum
- Dump each ROM to its own file

#include <stdio.h>
#include <dos.h>

#define START_SEG 0xC000
#define END_SEG 0xF000
#define STEP 0x80 /* 2 KB steps (0x80 paragraphs) */

unsigned char far *make_ptr(unsigned int seg) {
return (unsigned char far *)MK_FP(seg, 0x0000);
}

int check_signature(unsigned char far *ptr) {
return (ptr[0] == 0x55 && ptr[1] == 0xAA);
}

int checksum_valid(unsigned char far *ptr, unsigned long size) {
unsigned long i;
unsigned char sum = 0;

for (i = 0; i < size; i++) {
sum += ptr[i];
}

return (sum == 0);
}

void dump_rom(unsigned char far *ptr, unsigned long size, int index) {
char filename[20];
FILE *fp;
unsigned long i;

sprintf(filename, "rom%d.bin", index);

fp = fopen(filename, "wb");
if (!fp) {
printf("Error creating %s\n", filename);
return;
}

for (i = 0; i < size; i++) {
fputc(ptr[i], fp);
}

fclose(fp);

printf(" Dumped to %s\n", filename);
}

int main() {
unsigned int seg;
int rom_index = 0;

printf("Scanning for ROMs...\n");

for (seg = START_SEG; seg <= END_SEG; seg += STEP) {
unsigned char far *ptr = make_ptr(seg);

if (check_signature(ptr)) {
unsigned int size_blocks = ptr[2];
unsigned long size = (unsigned long)size_blocks * 512;
Show last 20 lines

printf("\nROM found at %04X:0000\n", seg);
printf(" Size: %lu bytes (%lu KB)\n", size, size / 1024);

if (checksum_valid(ptr, size)) {
printf(" Checksum: VALID\n");
} else {
printf(" Checksum: INVALID\n");
}

dump_rom(ptr, size, rom_index++);

/* Skip ahead to avoid re-detecting same ROM */
seg += (size / 16) - STEP;
}
}

printf("\nScan complete. %d ROM(s) found.\n", rom_index);
return 0;
}

- Starts at 0xC0000 (where VGA BIOS usually lives)
- Moves in 2 KB increments (standard ROM alignment)
- Looks for the 0x55AA signature
- Reads the size byte
- Verifies checksum (sum of all bytes = 0)
- Dumps each ROM as:
rom0.bin
rom1.bin
etc.

Reply 6 of 16, by EduBat

User metadata
Rank Member
Rank
Member

All processors from the 386 and above start running code 16 bytes below the 4GBytes address so the chipsets need to map the EEPROM(s)/FLASH containing the BIOS to the space just below the 4Gbytes.
Some older chipsets also mirror the last 64Kbytes (or 128Kbytes) before the top of the 4Gbytes onto the last 64Kbytes (or 128Kbytes) of the first megabyte of address space.

What almost all BIOSes do is decompress code&data from the EEPROM/Flash to the RAM at the end of the first 1Megabyte. What we have here is already the result of this decompression stage. They can also decompress "option ROMs" onto the RAM at the space between C000:0000 and E000:0000 if needed.

Programs like romdumpr and NSSI only extract and save these 64Kbytes (or 128Kbytes) "System BIOSes" and "Option ROMS" onto files as we can see in the code you posted. The reason for this is that they are real mode programs running in pure DOS.

BIOSDUMP is a protected mode program running with the 32 bit DPMI DOS extender provided with DJGPP. It is able to see the whole 32bit address space and is able to get the BIOS at the top of the 4Gbytes and save it. It gets the code before any decompression takes place and is exactly what you would get if you took the chip out of the motherboard and read it on an hardware programmer.

Relatively modern BIOSes can be quite big. As examples my Gigabyte GA-7N400 Pro has a BIOS of 512Kbytes and my asus P5Q has a BIOS of 1Mbyte.
On the GA-7N400 Pro depending on whether you want to use the RAID controller or not or the SATA controller or not the BIOS will decompress the respective "option ROMs" to RAM or not.

BIOSDUMP can work on all computers that can run DOS, from a 386SX up to whatever modern computer that still has "legacy BIOS" support (a.k.a. CSM)
I have no way of knowing, a priori, if a computer has a 64K,....512K,.....1M,.....12M....etc BIOS and so far have not been able to find any way to guess it.

Example "modern" PC memory map:

The attachment Screenshot_2026-04-28_17-22-21.png is no longer available

This free book provides a lot more details:
https://github.com/pinczakko/BIOS-Disassembly … jutsu-Uncovered

Reply 7 of 16, by EduBat

User metadata
Rank Member
Rank
Member

Apparently the SMBIOS specification https://en.wikipedia.org/wiki/System_Management_BIOS defines a field in the BIOS structure that indicates the size of the BIOS itself. The main problem is that these specs only became a thing around 1999 or so. I'm not sure if there is interest in developing an automation that will only work on computers from this era onward or if it's ok to leave the program as is. Feedback and/or ideas are welcome.

The attachment Screenshot_2026-08-03_12-18-42.png is no longer available

Reply 8 of 16, by Tiido

User metadata
Rank l33t
Rank
l33t

Dumping the F0000...FFFFF range is fine for many 486 and older things but at some point during 486 era, the BIOSes started to decompress + shadow themselves and in the process what you read there will not match what is actually on the BIOS chip, and burning such an image on a BIOS chip will not work either. This is why FLASHROM and UNIFLASH are chipset aware, so that it can actually dump the actual chip rather than what is shadowed into memory.

T-04YBSC, a new YMF71x based sound card & Official VOGONS thread about it
Newly made 4MB 60ns 30pin SIMMs ~
mida sa loed ? nagunii aru ei saa 😜

Reply 9 of 16, by EduBat

User metadata
Rank Member
Rank
Member
Tiido wrote on 2026-08-03, 14:12:

Dumping the F0000...FFFFF range is fine for many 486 and older things but at some point during 486 era, the BIOSes started to decompress + shadow themselves and in the process what you read there will not match what is actually on the BIOS chip, and burning such an image on a BIOS chip will not work either. This is why FLASHROM and UNIFLASH are chipset aware, so that it can actually dump the actual chip rather than what is shadowed into memory.

Correct. That is why my program gets the top "n" Kbytes from the 32 bit address space. (Where "n" is the input parameter to the program.)
So, as an example, instead of dumping the 000F0000...000FFFFF range, it gets the FFFF0000...FFFFFFFF range. (For a 64Kbyte chip.)
I understand my program may not work all the time, particularly on more modern computers with partitioned flash chips which need a program like FLASHROM or UNIFLASH, but it's a reasonable compromise.

Reply 10 of 16, by Harry Potter

User metadata
Rank Oldbie
Rank
Oldbie

Try scanning down from the top of memory until you get all 0's or 255's. That should be the beginning of the ROM.

Joseph Rose, a.k.a. Harry Potter
Working magic in the computer community

Reply 11 of 16, by Jo22

User metadata
Rank l33t++
Rank
l33t++

Hi, some BIOSes use/support Cloaking technology.
https://en.wikipedia.org/wiki/DOS_Protected_M … rvices#CLOAKING

"Time, it seems, doesn't flow. For some it's fast, for some it's slow.
In what to one race is no time at all, another race can rise and fall..." - The Minstrel

//My video channel//

Reply 12 of 16, by EduBat

User metadata
Rank Member
Rank
Member

Hi all,

I went ahead and created a version where I find the size of the BIOS from the SMBIOS/DMIBIOS tables in the BIOS itself.
That functionality should work fine for computers from around 1999 and above.
For all the older ones it will also work but you need to pass the size of the BIOS as an argument to the program.

The zip includes source code, in case anyone is interested to see how it was done.

I would really appreciate any feedback, particularly regarding any failures, so that I can investigate the issues and fix them.

Thanks!

Reply 13 of 16, by EduBat

User metadata
Rank Member
Rank
Member

After a lot more testing I have now fixed a few bugs that prevented the program from working properly on newer computers and am therefore releasing a new version.

BIOSDUMP.EXE is a program that allows you to extract the BIOS of your
x86 PC compatible computer to a file.

Writen by Eduardo Batalha on 8-Aug-2026.
Distributed under the WTFPL license.
Feel free to do whatever you want with this code as long as you do
not misrepresent me.

This is the third version with a reasonably amount of testing.
It was compiled with DJGPP, it is a protected mode program that
uses the DPMI facilites provided by the CWSDPMI.EXE server
and needs at least a 386 machine.
This version adds auto detection of the EEPROM size by using the
SMBIOS/DMIBIOS tables from the BIOS itself.
It is not a UEFI program, it runs from DOS. The best way to test it
on newer computers is to use a Freedos formatted USB memory stick and
boot the computer from it, then run BIOSDUMP from it. Rufus is a
utility that can create such a USB drive.
The program creates a file called BIOS.BIN in the same folder where
it lives. After running the program just rename this file to whatever
you want.

Tested on:
- Unicorn ENDAT-486AL - Working, the user needs to input BIOS size
- Gigabyte GA-7N400 Pro - Working, ROM size found by DMI
- Compaq N610c - Working, ROM size found by DMI
- Asus P5Q - Working, ROM size found by DMI
- Lenovo T430s - Working, ROM size found by DMI. If you use Freedos to test
do not load himemx to prevent the program from crashing
- Lenovo T450s - Working, ROM size found by DMI

Still to be tested are 386 computers and computers with SMBIOS/DMIBIOS
version equal to or higher than 3.1.

It works by extracting the values present at the top of the 32bits memory
space, where firmware needs to exist in order for any x86 processor to
start. The program should run well on any computer with a 386 processor
or above up to systems where the chipset partitions the BIOS chip, the
so called "Descriptor mode" in intel documentation. On these later systems,
the data in the EEPROM chips is divided into blocks, each dedicated to its
own controller. Besides the block for the main processor, you will have
another for the ME controller, another for the Ethernet controller, etc.
The chipset may hide the data for these other controllers from being
accessed by the main processor without prior chipset programming.
BIOSDUMP is not chipset aware and will make no attempt to unlock access to
these blocks.

The program was compiled with:
gcc -g -o dumper.o dumper.c
gcc -o dumper.exe dumper.o
strip dumper.exe
exe2coff dumper.exe
copy /b cwsdstub.exe+dumper biosdump.exe

Reply 14 of 16, by EduBat

User metadata
Rank Member
Rank
Member

I have also now tested it on an HP Elitebook 850G5, which uses DMI version 3.1. It worked fine (slowly, since it's a 32Mbyte BIOS) but I had to disable HimemX in Freedos.
The only thing pending now is a test on a 386 class machine.

Reply 15 of 16, by zyzzle

User metadata
Rank Oldbie
Rank
Oldbie

Seems like the autodection is a bit wonky. On my Dell i5 Inspiron laptop with an InsydeH2O BIOS and i5-8250u CPU, the program writes a 16384kb file (executed in baremetal DOS on MS-DOS 7.1). Over 50% of this is 0xFF bytes (the initial 8 mb or so). Is it possible to have a 16MB BIOS and half of it would be "empty"?

Reply 16 of 16, by Harry Potter

User metadata
Rank Oldbie
Rank
Oldbie

I believe that searching the top of RAM for all 255's is a pretty reliable method to determine where the actual ROM begins. Try it.

Joseph Rose, a.k.a. Harry Potter
Working magic in the computer community