12

I had always assumed that EMM386.EXE was responsible for managing the Upper Memory Blocks - UMBs - the memory space between 640KiB and 1MiB in real mode x86. For example, on MS-DOS 6.22, help emm386.exe shows:

Provides access to the upper memory area and uses extended memory to simulate expanded memory

EMM386.EXE is also where you configure, with I=nnnn and X=nnnn directives, which UMBs are available or not for DOS use.

However, I recently read eXtended Memory Specification (XMS), ver 2.0, which contains programming APIs for "Upper Memory Management Functions":

10h) Request Upper Memory Block

11h) Release Upper Memory Block

The document's definition of Upper Memory Block matches my definition above.

The eXtended Memory Manager in MS-DOS is HIMEM.SYS but I had always assumed that it managed the extended memory area (memory beyond 1MiB) only. help himem.sys says:

HIMEM is an extended-memory-manager -- a program that coordinates the use your computer's extended memory, including the high memory area (HMA)

It does not mention managing the UMBs, neither does it describe a mechanism for controlling which UMBs are available are not.

So what is the true story - what manages UMBs in MS-DOS? Has this changed over MS-DOS' lifetime - is the XMS spec doc no longer accurate?

15

The XMS specification is still accurate: functions 0x10 and 0x11 provide access to UMBs. However, the specification doesn’t decide where those functions are implemented.

On its own, HIMEM.SYS does indeed only provide access to memory above 1MiB, i.e. the HMA (so it also controls the A20 line) and extended memory (which it makes available as XMS). If you only load HIMEM.SYS, setting DOS=UMB (in MS-DOS 5 and later) won’t do anything useful; you’ll only be able to use DOS=HIGH.

In typical setups on 386+ systems, EMM386.EXE implements the UMB functions 0x10 and 0x11, and fulfills them by mapping extended memory to addresses in the UMA. To do this, it needs to run the system in V86 mode, which causes compatibility problems with some programs which expect to run in real mode (and take over ring 0).

Other tools also implement those functions. For example, UMBPCI can provide UMBs by activating the corresponding shadow RAM, using chipset-specific features. This was common on 286s, where chipset-specific drivers could activate shadow RAM to provide memory between 640K and 1M. The Last Byte Memory Manager was a shareware memory manager which included lots of chipset-specific drivers to do this. Another approach, on 8086s and 286s, was to use EMS 4.0 features to map expanded memory into the UMA; QRAM can do this (as well as use shadow RAM on C&T-based 286 systems). All these memory managers are capable of providing UMBs without leaving real mode... 386-specific memory managers such as QEMM386 use the same techniques as EMM386 (and the grandfather of them all, Compaq’s CEMM).

In all cases, memory managers which work with HIMEM.SYS need to piggy-back on top of it, which is why you always load HIMEM.SYS first. On its own, HIMEM.SYS responds to interrupt 0x2F functions 0x4300 and 0x4310. Subsequent memory managers call those functions, find HIMEM.SYS, then hook interrupt 0x2F themselves, and either take over function 0x4310 in particular to point to their own entry point, or overwrite the code at the start of the existing entry point with a far jump to their own entry point (see the XMS specification for details). Having stored HIMEM.SYS’s entry point somewhere, they can then pass on appropriate calls to HIMEM.SYS. QEMM386 and other “high-end” memory managers replace HIMEM.SYS entirely so it shouldn’t be loaded at all.

As far as programs running on top of DOS are concerned, UMBs are managed by DOS. If a program wants to allocate memory in the UMA, it should try to do so using the usual DOS memory allocation functions, after setting the allocation strategy using interrupt 0x21 function 0x58.

Microsoft’s knowledge base entry 95555, “Overview of Memory-Management Functionality in MS-DOS”, provides a good introduction to the whole topic.

(This answer describes MS-DOS; I can’t remember the details for DR DOS and Novell DOS, but at least on OpenDOS, HIMEM.SYS also manages the UMA in some cases.)

  • 1
    I don't know about Shadow RAM but I've used Quarterdeck's QRAM to turn LIM EMS into UMBs on a '286 at some point. – Neil Nov 1 at 0:53
  • Thanks @Neil, I’d forgotten that QRAM could do that! – Stephen Kitt Nov 1 at 13:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.