FreeDOS Memory Management: Conventional, Upper, and Extended Memory
Why DOS memory is split into distinct regions with different rules, and how HIMEM.EXE and EMM386.EXE make more of it usable.
Nothing exposes DOS’s real-mode x86 heritage more directly than its memory model — a set of hard boundaries inherited from the original 8088’s 20-bit address bus, still shaping how FreeDOS manages RAM today. Where a modern OS gives every process a flat, virtual 64-bit address space, DOS memory is split into named regions with genuinely different rules for each.
Conventional memory: the original 640KB ceiling
The famous 640KB barrier comes directly from the original IBM PC’s memory map: the first 1MB of address space was divided between RAM for programs (conventional memory, 0–640KB) and reserved space for video memory, ROM BIOS, and expansion cards (640KB–1MB). Every DOS program, by default, competes for space within that same 640KB — which is why memory optimization was such a serious concern in the DOS era, and remains relevant to FreeDOS today for the same binary-compatibility reasons.
C:\>mem
Memory Type Total Used Free
---------------- ------- ------ ------
Conventional 640K 89K 551K
Upper Memory Blocks: reclaiming the reserved region
Not all of the 640KB–1MB reserved region is actually used by hardware on a given system — the unused gaps are called Upper Memory Blocks (UMBs), and EMM386.EXE is what makes them usable for loading drivers and TSRs, freeing conventional memory for actual applications:
DEVICE=C:\FREEDOS\HIMEM.EXE
DEVICE=C:\FREEDOS\EMM386.EXE RAM
DOS=UMB
DEVICEHIGH=C:\FREEDOS\ANSI.SYS
LOADHIGH C:\FREEDOS\DOSKEY.EXE
EMM386.EXE has to run in virtual 8086 mode to pull this off — trapping and remapping memory access, since real mode itself has no native concept of relocating what lives at a given physical address.
Extended memory: everything above 1MB
Extended memory (XMS) is simply the RAM above the 1MB boundary — inaccessible to real-mode code directly, but reachable through the XMS specification, implemented by HIMEM.EXE. Most extended memory usage in FreeDOS is indirect: a well-behaved DOS program calls the XMS driver’s API to allocate and copy data into extended memory rather than addressing it directly.
DEVICE=C:\FREEDOS\HIMEM.EXE /TESTMEM:OFF
C:\>mem /c
The High Memory Area: a special 64KB sliver
Because of a quirk in how the 80286 and later CPUs handle address wraparound, there’s a specific 64KB region just above the 1MB boundary — the High Memory Area (HMA) — that real-mode code can actually address directly, given the right A20 line handling. DOS=HIGH loads the core of the DOS kernel itself into the HMA, which is why enabling it visibly increases the conventional memory left over for applications:
DOS=HIGH,UMB
Expanded memory: an older, different mechanism
Expanded memory (EMS) predates XMS and takes a different approach entirely: a fixed 64KB “page frame” window inside conventional/upper memory acts as a bank-switched viewport onto a much larger pool of physical memory, swapped in 16KB pages on demand. EMM386.EXE can emulate an EMS page frame using extended memory, which is why the same driver shows up controlling both UMBs and EMS — it’s genuinely doing double duty.
DEVICE=C:\FREEDOS\EMM386.EXE RAM FRAME=E000
Reading the memory map live
MEM /C gives the full breakdown — conventional, upper, and extended/XMS usage, program by program — the closest FreeDOS equivalent to free on Linux or Activity Monitor’s memory tab, just reporting on named regions with fundamentally different addressing rules rather than one flat pool:
C:\>mem /c /p
Why this fragmented model still matters
None of this complexity is arbitrary — it’s the direct, visible consequence of maintaining binary compatibility with 16-bit real-mode software written against the original 8088’s addressing limits, decades after the CPUs involved could trivially address far more memory in native modes. Every DOS memory-management technique — loading high, expanded memory page-frames, the HMA trick — exists purely to squeeze more usable space out of that original 1MB map without breaking compatibility with software that still assumes it. It’s a genuinely different set of trade-offs than any virtual-memory OS makes, and understanding it end-to-end is understanding exactly why “memory management” meant something so different before protected mode became the default.