Playing with rxDOS

My current pastime has been looking at rxDOS with its quite an odd history. To the best of my knowledge rxDOS was written by Michael Podanoffsky and was included with his book `Dissecting DOS’ in 1994. The version of rxDOS, included with the book, is marked RxDOS Version 6.00. In 1999, the rxDOS source was released under GNU Public License and is marked version RxDOS Version 7.1.5.

I said odd earlier because sometime in 2008 C. Masloch ported the 7.1.5 source from the original MASM source to NASM and released RxDOS 7.20N for developers.

Do not use RxDOS version 7.20N. It tries to re-produce every bug of RxDOS 7.1.5 (as found on the FreeDOS mirrors). It is not usable currently. The release of version 7.20N is only intended for developers.

rxDOS readme

From 2008 through 2018, rxDOS versions 7.21 through 7.25 were released. I am not really sure about the 7.25 version being released, but that is what the source claimed. All the versions from 7.20N through 7.25 are tagged in my Gitlab.

I have not seen any announcements, but it looks like there is some rxDOS work that I found on the site. The rxDOS updates are listed here. Also, E. C. Masloch’s Gitgub repo. Another interesting page is 25+ YEARS OF DOS HISTORY that seems its last update was 2006-09-03.

Anyway, my main interest is going through Podanoffsky’s Dissecting DOS to pass some of the winter days until I get bored. The original source uses MASM 5.1 and from a quick check the source compiles with this version. I use either wasm from Jiří Malák’s Open Watcom v2 build or a current version of UASM* which is currently version 2.56 as of October 2022. As a note, the UASM website triggers Norton giving Dangerous Webpage Blocked which in my experience is not correct. Finally, I only have the 2008 and newer sources for reference. I just do not use NASM and really have no plans to learn it.

All the sources I mentioned above are on my Gitlab account and on my home account.


To build on the vdi_info post, I am throwing in my oemboot file. I have used this several times over the years in various forms, in general just to get a loader binary into memory. In its current form it uses LBA after doing an int 13 0x41 check error. Are there bugs? Maybe. It works for my purposes.

Here is a brief description of how it works:

  • 1. Scan directory for a loader file with a name defined by LOADFILE, 8.3 format
  • 2. Loads LOADFILE to memory defined by LOAD_SEG and LOAD_OFF, I use 0x7C000.
  • 3. Far jump to start of loader. The jmp far ptr loader_start is around line 470 and before the jump I load registers with “stuff” I want to pass to the loader.

Some simple BPB Error Codes:
1 – No bios extensions – IBM/MS INT 13 Extensions not supported
2 – Root directory read – could not read root directory
3 – LOADFILE not found
5 – FAT error – bad read or sig error

That is about it. The oemboot.asm file is very commented with good info and random thoughts, so I could remember why I had done certain things. The example files are located:

Code repo: Gitlab or My Gitlab

Okay, let’s put my simple test environment together. I make a raw vdi image then run it attached to a VM so I can format it to FAT16 and make the partition active. Next, I use vdi_info.exe to create which will be an include for oemboot.asm. I use uasm to compile oemboot.asm with the following commands:

uasm32 -bin [path to includes] -Fo oemboot.bin oemboot.asm

I write the oemboot.bin back to the vdi using the vdi_info.exe -w option. Next, the loader I am using just gets copied to the FAT16 vdi and boot with bochs.



This is a utility of need. I needed to get info from a virtualbox vdi image so that I could modify the boot sector. By modify, I mean to dump the required BPB info to an include file and graft my compiled oemboot boot sector on to the vdi. I did this a year ago and it has been used via a makefile since. What this means is I need to go back and figure out everything it does.


Again, this tool is to make my life easier. Currently, I use Open Watcom v2 maintained by Jiří Malák. I compile it on a 32bit system, either an old Win XP image or a ReactOS image. I assume it would compile on AcraOS, I just have not tried to do so. I have only been using FAT16 because it is simple, and I just wanted to get things running.

My build flow is to compile my boot loader on a 32bit system, transfer the boot loader to a vdi image, and boot via bochs from Linux. To get the boot loader in memory, I use a custom boot sector named oemboot (I know, not very original). Without going into details, a vdi has a different structure than a normal hard drive image and it is tedious to extract the vdi information to an include file (BPB include) and, after compiling oemboot, writing the boot sector back to the vdi. The result was this tool that made the task easier when swapped to a new vdi or write a new boot sector to my dev image.

Code repo: Gitlab or My Gitlab

Be careful, while I put the repo together, I already see things I need to fix. Not big things, but mistakes that happen in a hurry. For example, in the v1.0 source if WRITEBPB is true I should skip the input file check until later. Oops.

How it works

The command line options are if you run vdi_info -h :

vdi_info: get dev image vdi information.
Version 1.0, compiled Nov  5 2022 with OpenWatcom 2.0

usage: vdi_info [-f alt filename][-i][-m][-p][-w] vdi_filename

   -f #  alternate input filename for -w option.
   -i    Dump BPB inc to
   -m    Dump MBR to mbr.bin.
   -b    Dump active BPB to bpb.bin.
   -w    Write newmbr.bin to active BPB.
   -h    help message.

Valid option combinations:
  1. -m, -b, or -i single or all at once to dump MBR, BPB and INC.
  2. -w only or with optional -f <filename> for alternate BPB image to add.

The output with vdi name input results in some info about the image:

vdi_info fat16drive.vdi

Info: Input file found (fat16drive.vdi) and opened.

<<< Oracle VM VirtualBox Disk Image >>>
Image Version: 1.1
Image Sig: BEDA107F
Header size: 190
Drive Start: 200000
MBR Sig: AA55 Valid MBR signature!

Part num  1
State: 80
Head:  1
End:   1
Type:  6
Head:  F
End:   CD3F
Off:   3F
Sect:  32AE1

Part num  2
State: 0
Head:  0
End:   0
Type:  0
Head:  0
End:   0
Off:   0
Sect:  0

Part num  3
State: 0
Head:  0
End:   0
Type:  0
Head:  0
End:   0
Off:   0
Sect:  0

Part num  4
State: 0
Head:  0
End:   0
Type:  0
Head:  0
End:   0
Off:   0
Sect:  0

Active partition 1 found at offset 3F
Boot sector VDI offset:  2129408

All done!


Read the vdi and get what is expected to be the MBR and check for a valid signature. If the -m option is passed then write the MBR to a file named mbr.bin.


The MBR is scanned for the first active partition and extracted. If the -b option is passed, then write the BPB of the first active partition to a file named bpb.bin.


So, here is the real use for this tool. When vdi_info -i <vdi file> is executed it outputs Why did I name the output ? Who knows, I was probably tired or dyslexic. Anyway, I should really change it to Passing -i goes through all the step above, read MBR, scan for first active partition, load the BPB of that partition, and dump it to an include file. The following is the output for my current development image.

; *** BPB output of vdi_info *** 

BS_OEMName      db  'MSDOS5.0'

BPB_BytsPerSec 	dw  0X0200
BPB_SecPerClus 	db  0X04
BPB_RsvdSecCnt 	dw  0X0001
BPB_NumFATs    	db  0X02
BPB_RootEntCnt 	dw  0X0200
BPB_TotSec16    dw  000000
BPB_Media       db  0XF8
BPB_FATSz16 	dw  0X00CB
BPB_SecPerTrk   dw  0X003F
BPB_NumHeads    dw  0X0010
BPB_HiddSec     dd  0X0000003F
BPB_TotSec32 	dd  0X00032AE1

BS_DrvNum       db  0X80
BS_Reserved1    db  0000
BS_BootSig      db  0X29
BS_VolID        dd  0X2A6316E8
BS_VolLab       db  'TESTDRV    '
BS_FilSysType   db  'FAT16   '

; *** end of BPB output ***


This finds the active partition and writes a new boot sector from the file named newbpb.bin or the file name passed with the -f option.