MS-DOS 6.22 Upper Memory Block Fragmentation

This article explains how MS-DOS 6.22 manages Upper Memory Block (UMB) fragmentation within the Upper Memory Area (UMA). Because the 16-bit real-mode architecture of MS-DOS prevents runtime memory compaction or dynamic defragmentation, the operating system relies on static allocation strategies, Memory Control Block (MCB) chains, and load-order optimization through utilities like MemMaker to mitigate fragmented memory regions.

The Real-Mode Constraint on Defragmentation

MS-DOS 6.22 runs primarily in real mode, meaning running programs and drivers rely on hardcoded, segmented memory addresses (segment:offset). Once a Terminate-and-Stay-Resident (TSR) program or device driver loads into memory, it cannot be dynamically relocated to another address space. Consequently, MS-DOS cannot perform active or run-time memory defragmentation on UMBs. Once a memory hole forms between two resident programs in upper memory, that space remains fragmented until the system is rebooted.

EMM386 and Memory Control Blocks

UMB management begins with HIMEM.SYS and EMM386.EXE. When DOS=UMB is specified in CONFIG.SYS, the DOS kernel links the Upper Memory Area (addresses between 640 KB and 1024 KB) into its global memory pool.

EMM386 detects unused address space between video RAM, system ROMs, and adapter cards, mapping extended memory pages into these gaps. DOS organizes each identified continuous pocket of memory using standard Memory Control Blocks (MCBs). If the UMA is physically split by hardware (for example, video RAM at A000h–C7FFh and network adapter ROM at D000h–D7FFh), DOS creates distinct, non-contiguous UMB regions, each governed by its own chain of MCBs.

Allocation Strategies: First Fit, Best Fit, and Last Fit

To prevent premature fragmentation when software requests memory, MS-DOS 6.22 uses configurable memory allocation strategies accessible through Interrupt 21h, Function 58h:

  • First Fit: DOS searches from the lowest available memory address and allocates the first block large enough to satisfy the request. While fast, this method often leaves small, unusable slivers of memory dispersed across the UMA.
  • Best Fit: DOS scans all available blocks in the UMB pool and allocates the one closest in size to the requested amount. This leaves larger contiguous regions intact for subsequent, larger drivers, directly minimizing fragmentation.
  • Last Fit: DOS searches from the highest memory address downward, packing drivers toward the top of the UMB space.

By default, DOS uses First Fit, but specialized configuration utilities adjust these flags before placing drivers.

Regional Segmentation with the /L Switch

MS-DOS 6.22 introduced fine-grained placement controls for DEVICEHIGH (in CONFIG.SYS) and LOADHIGH (in AUTOEXEC.BAT) via the /L parameter. The /L switch enables an administrator to specify which distinct UMB region a program must occupy (e.g., /L:1 or /L:2).

Furthermore, many drivers require more memory during initialization than they do while idling as a resident process. The /L switch accommodates this by allowing an initialization size parameter (e.g., /L:1,12048). DOS ensures that the specified UMB region has enough temporary space to accommodate the initialization footprint without spilling over into or fragmenting adjacent regions.

Automated Optimization via MemMaker

Because MS-DOS 6.22 cannot defragment upper memory dynamically, it addresses fragmentation through preventative pre-allocation via the MEMMAKER utility.

MemMaker resolves fragmentation statically by performing test reboots. During these boots, it measures both the transient initialization size and the final resident size of every driver and TSR. It then calculates an optimal loading sequence using a bin-packing algorithm. By ordering the load commands so that drivers requiring large initialization footprints load first, and by locking programs into designated UMB regions via the /L switch, MemMaker packs drivers tightly against one another, effectively eliminating dead space and preventing unusable memory fragments before the operating system finishes booting.