[Front] [Prev chapter] [Next Chapter]

Chapter 1 DOS Protected Mode Services


The original IBM* PC standard, for which DOS became the standard operating system, was based around the 8088 processor which had a memory address space of one megabyte. Compatibility with this standard now limits the memory available in standard DOS systems. More and more demand has been put upon DOS systems since the original PC, and supporting this demand means that a typical DOS configuration today loads several device drivers and other resident system extensions, which all reduce the conventional memory available to standard DOS applications.

The 80286 and later processors descended from the 8088 and compatible 8086 provide an alternative mode of operation, called protected mode. Protected mode provides programs with access to much more memory space than the single megabyte of the 8088. The extra memory space provided is called extended memory. Unfortunately standard DOS programs cannot run in protected mode, and therefore cannot access extended memory directly. Many DOS applications have been adapted or written to run in protected mode, but there are memory and other overheads in doing this, so few resident system extensions run in protected mode.

DOS Protected Mode Services (DPMS) is a set of services that is designed for DOS resident system extensions to run in protected mode. DPMS provides all the benefits of protected mode operation without the headaches. DOS compatibility is not compromised, and it is easy to create resident system extensions that can adapt at initialization time to DPMS and non-DPMS configurations.

This document describes the DPMS 1.0 specification and issues raised by programming for DPMS using the DPMS 1.0 System Developers Kit (SDK). It is assumed that the reader is familiar with the Intel* x86 range of processors.

Protected Mode

It is beyond the scope of this manual to describe protected mode programming in full but this introduction is included so that programmers familiar with standard DOS programming, but not protected mode, can get an idea of what is required to program for DPMS. It also defines some terms used in the document.

Introduction to Protected Mode

In a standard DOS system, there are no restrictions upon what memory and other hardware a program can access. Therefore it is possible for a faulty or malicious piece of software to bring down the whole system. Protected mode, as the name implies, provides an operating system with the processor hardware features necessary to have complete control over the memory and other hardware and software resources that programs can access.

For compatibility with earlier processors such as the 8088, processors that support protected mode can also run in a mode that is compatible with those processors, and this is called real mode. 386* and later processors also provide a third mode called virtual-8086 mode in which standard DOS programs can run in a semi-protected environment. For the purposes of this introduction virtual-8086 mode can be treated the same as real mode.

NOTE: The term real mode is used throughout this document to refer to both true real mode and virtual-8086 mode. DPMS clients running on a 386 or later typically run in virtual-8086 mode rather than real mode.

For most software, protected mode operation is very similar to real mode. The major difference lies in the way segments are defined and used. It is possible to write software that can operate in either mode but most standard DOS programs cannot run in protected mode. Therefore standard DOS systems must run in real or virtual-8086 mode.

It is possible to mix real and protected mode software in a system by switching modes. Transitions from real to protected mode are referred to as up, transitions in the opposite direction are down. A call-up is a call that originates in real mode, executes some code in protected mode, and returns to the real mode code. A call-down is the opposite.

Segments, Descriptors, and Selectors

Segments are defined and used differently in protected mode than they are in real mode. In real mode, segment registers contain a value which is directly related to the base address; all segments are 64 KB in size and can be used by any software for code or data without restriction. In protected mode, on the other hand, segment registers contain values which are used to locate entries in tables which describe the segments and how they may be used. The tables are in memory and have one entry, called a descriptor, per segment. Each descriptor consists of eight bytes which describe the segment's base address, size, and how it may be used.

Segment size is described by the maximum offset that may be accessed within the segment, which is the size minus one, and this is called the limit of the segment. Protected mode segments can be larger than 64 KB on 386 and later processors.

The values loaded into segment registers which act as offsets into descriptor tables are called selectors.

In protected mode, different segments must be used for code and data, and code segments cannot be written to.

There are two descriptor tables at any time: the Global Descriptor Table (GDT) and Local Descriptor Table (LDT). Normally the GDT would be fixed while there would be a different LDT for each task if in a multitasking system. Bit 2 of a selector determines whether the corresponding descriptor is in the GDT or LDT.

Descriptors and selectors are assigned privilege levels, from zero to three. Zero is the most privileged level and three is the least. Programs running at lesser privilege levels are prevented by the processor from loading segment registers with selectors for higher privilege segments, and so those higher level segments are protected.


· Code segments cannot be written to. This means that the CS:override prefix cannot be used for writes, a practice which is common in real mode programming. MASM and compatible assemblers provide a command line switch (/p) to check for such overrides.

· Memory can only be accessed via descriptors. For example, real mode software might access a byte in the PC BIOS data area by loading a segment register with 00040h, but in protected mode it must first set up a descriptor for the required segment and then load the corresponding selector.

· Segment arithmetic cannot be used. If real mode software overruns the end of a segment, it can access the memory following it by simply adding 01000h to the segment register. That cannot be done in protected mode as there is no relationship between the selector and base address values. Either the base address of the descriptor must be updated or a new descriptor must be set up to access the required memory.

Memory Mapping

386 and later processors support memory mapping while in protected and virtual-8086 modes. This means that any 4 KB physical block of memory can be mapped at any linear address within the entire 4 GB address space.

By convention, addresses that may be mapped are referred to as linear addresses even when they have not been mapped. The addresses of the underlying physical blocks are referred to as physical addresses.

Protected Mode Environments

Protected mode programming in general is not just a matter of using segments differently to real mode, but also involves the construction and management of an entire protected mode system, which is especially complicated if the protected mode system is based upon DOS. Many applications that have been written or adapted to run in protected mode use DOS extenders, which are sets of tools and libraries that enable standard DOS programs to be easily ported to protected mode operation. A DOS extender runs applications in a protected mode environment which emulates that of DOS so that, for example, a DOS function call (INT 021h instruction) in protected mode is transparently passed down to the real mode DOS.

If a system is already running in protected mode then it is impossible for any other piece of software to get control of the processor. Therefore in order for protected mode applications to run, a number of standard interfaces have developed which enable protected mode software to run in an existing protected environment. The main interfaces are the Virtual Control Program Interface (VCPI) and the DOS Protected Mode Interface (DPMI).

DPMS Features

The main functions of DPMS are to manage protected mode system resources and to handle transitions between real (or virtual-8086) and protected modes.

DPMS is not a DOS extender. Although it has a similar acronym and some similarities, it is not the same as DPMI. It is a minimal suite of services tailored to the needs of resident system extensions. It is possible to run such software in protected mode using one or more other interfaces, but DPMS is usually more appropriate because

· DPMS provides a consistent interface, independent of environment. It insulates its clients from environment changes caused when MS Windows runs.

· DPMS uses very little standard DOS memory.

· You can supply the DPMS server with your software for low royalty payments.

DPMS API functions include

· Calls from real to protected mode and vice-versa

· Descriptor management

· Memory management

The DPMS interface is fully re-entrant.

DPMS Clients

The following sections introduce client structure and initialization.

Client Structure

Clients are initially loaded and run as standard DOS programs, and can be either device drivers or TSRs or both. You can therefore use standard tools to create them.

Clients typically have three parts

· Initialization code and data which is discarded when the client becomes resident.

· Real mode code and data which is the minimum that must stay in real mode memory.

· Relocatable code and data which, if DPMS is present, is moved into extended memory and runs in protected mode. This code and data may use 386-specific features such as 32-bit segments, but normally it will not, so that it can run in real mode without DPMS or in protected mode using DPMS on 80286 processors.


Client initialization includes the following steps:

· Find any DPMS server.

· Allocate protected mode descriptors.

· Allocate extended memory.

· Set the descriptors' base addresses, limits, and types.

· Relocate the code and data into extended memory.

· Fix up any calls in the real mode segment whose destination isin the code that now executes in protected mode. Replace them with callsto DPMS call-ups.

· Perform functions specific to particular clients, such asregistering as a device driver with DOS, hooking real mode interrupts,and initializing data structures.

· Free any real mode memory that is no longer required.

· Call DOS to terminate and stay resident.

The client is now resident, and either DOS or an interrupt can call it through entry points in the real mode portion. Because the client does its work in protected mode, the real mode portion may consist of little more than a DPMS call up to the protected mode portion.

In order to call any real mode function, for example to call DOS, the protected mode code must go via one of the DPMS call down functions. The call down sets all real mode registers, but any data that is passed in memory, for example, a buffer, must reside in memory that is accessible in real mode.

Some clients require DPMS, and fail to install if no server is present. Others can operate entirely in real mode if there is no DPMS server.

Overview of DPMS Functions

The following sections give an overview of the DPMS functions. Chapter 2, "DPMS Function Reference," contains detailed descriptions of all the DPMS functions.

Descriptor Management

Reuse descriptors where possible, because descriptor tables have a finite size, and relinquish them when no longer needed. Although the only way to address memory in protected mode is via a descriptor, you must explicitly initialize each descriptor to refer to an allocated memory area before you can use it.

Clients should try to reuse the same descriptor to address different objects at different times, because it takes time to allocate descriptors and because there is a finite number of descriptors available.

Clients usually need to allocate and initialize descriptors before they enter protected mode. Use the DPMS_D_ALLOC, DPMS_D_ALIAS and DPMS_M_RELOC functions to allocate descriptors. Refer to the description of DPMS_D_ALLOC on page 2-39, DPMS_D_ALIAS on page 2-43, and DPMS_M_RELOC on page 2-66 in Chapter 2, "DPMS Function Reference." Descriptors allocated via DPMS_D_ALLOC must be initialized after allocation. Depending upon what the descriptor is to be used for, initialization is done in one of the following ways:

· Allocating linear memory via DPMS_M_ALLOC (see page 2-54) or otherwise, then calling DPMS_D_SET_BASE (see page 2-47), DPMS_D_SET_LIMIT(see page 2-48), and DPMS_D_SET_TYPE (see page 2-50) to set the descriptor to refer to that memory.

· Calling DPMS_D_ALIAS_REAL (see page 2-45) to create an alias to a real mode segment.

· Passing the descriptor to DPMS_M_RELOC (see page 2-66).

If the client terminates, it must explicitly free up descriptors using DPMS_D_FREE (see page 2-41) before terminating.

Memory Mapping Functions

On systems which implement linear-to-physical memory mapping, DPMS offers the functions DPMS_M_MAP and DPMS_M_UNMAP, which allow clients to map and unmap any physical memory, which may be non-contiguous, into DPMS linear address space. Refer to the description of DPMS_M_MAP on page 2-57, and DPMS_M_UNMAP on page 2-60 in Chapter 2, "DPMS Function Reference," for more details.

If these functions are supported, then clients must use them if they need to access extended memory other than that allocated via DPMS.

For example, consider a disk cache that must run both with and without DPMS. When running without DPMS, it would typically use XMS memory. When running with DPMS, it could use memory allocated via DPMS but this would mean that the memory interface would be completely different between the DPMS and non-DPMS installations, and would also make memory lending more difficult. The cache could still use XMS memory with DPMS, but this would mean that calls to the XMS driver to do block moves to and from the memory would involve mode transitions and would therefore be slower than without DPMS. Instead, the client could lock the XMS memory it had allocated, get the physical address(es) of that memory, and call DPMS_M_MAP to map the physical memory into DPMS linear address space. It could then access the memory directly instead of via XMS block moves, meaning that the cache could be faster with DPMS than without.

Extended memory allocated or mapped via DPMS may only be accessed by the DPMS client while it is in protected mode under DPMS. Access may fail if attempted via any other interface.

Mode Transitions

DPMS provides a number of functions for calling protected mode from real mode and vice-versa. These fall into two categories. The first set of functions take a parameter block which contains values for all registers to be used in the opposite mode. The parameter block has the same format for all calls. Refer to the description of the DPMS_CALL_PROT function on page 2-18, in Chapter 2, "DPMS Function Reference," for the structure of the parameter block and a full description of that type of function.

The parameter block includes CS and (E)IP register values. These are the addresses of the client procedure to be called. When the called procedure returns, using a RETF or an IRET, the return goes via DPMS which performs the inverse mode change, copies the new register values back into the parameter block, and returns to the original mode code.

Most calls from real or virtual-8086 to protected mode and vice-versa are to addresses that are determined at initialization time. Furthermore, many calls require parameters to be passed in registers that would have to be stored in a DPMS register structure, if calling via the call-up or -down functions already described. There is therefore an alternative, more convenient way of making inter-mode calls.

Using the alternative method, the client registers a default procedure to be called, together with default values for certain registers, including the segment registers. This is done by passing the address of a default register structure to the server. The server fills in part of the structure with the code necessary to effect the inter-mode call, and this code also contains a client ID. The client can register almost any number of default procedures in this way; each procedure is called via the code in the corresponding default register structure.

Refer to the description of the DPMS_REG_DEF_PROT function on page 2-29, in Chapter 2, "DPMS Function Reference," for the default register structure and a full description of that type of function.

Protected mode has several advantages over real mode, only one of which is the ability to execute code in extended memory. It is feasible to switch into protected mode to execute code within the first megabyte. If the code is quite small, you may not want to relocate it.

MS Windows 3.n Restrictions

When MS Windows starts up in either standard or enhanced mode, all DPMS services should continue normally. However, MS Windows normally allocates all available memory and replaces extended and expanded memory interfaces with its own. All memory allocations made while MS Windows is running are temporary and will disappear when MS Windows terminates. This applies both to memory allocated via the native extended or expanded memory interface and that allocated via DPMS, as the DPMS server normally calls down to the underlying memory manager to allocate the physical memory required.

To avoid this problem, clients should allocate all memory they need before Windows loads. If the client needs to co-operate with other programs, including MS Windows, that may occasionally want memory owned by the client, hook the memory manager interface and lend memory as appropriate.

API Implementation

Constants and structures for the DPMS API are defined symbolically in include files: DPMS.INC for assembly language and DPMS.H for the `C' language.

The only code you need to use DPMS is the code you write yourself. DPMS does not require a run-time library.

DPMS clients typically perform low-level functions, so the API is created primarily for assembly language. You can write parts of a client in a high level language, but use run-time library functions with caution as they may not be compatible with protected mode.

Sample Client Source Code

To help you understand what a DPMS client might look like, the SDK includes VDISK.ASM, which is the complete source code for a virtual disk driver that uses DPMS to relocate and execute much of its resident code.

This program has extensive comments to guide you through its operation. It uses all the main DPMS features. After installation when running under DPMS, less than 400 bytes of code and data remain in real mode memory.

The sample VDISK requires XMS to run.

Server Source Code

The SDK includes the full source code for the DPMS server (DPMS.EXE) to help you debug clients and to optimize the server for use on either 286 or 386 (and above) platforms. The following tools are required in order to build the server. Caldera do not supply these tools.

· Borland Turbo Assembler (TASM) v2.51
· Borland Turbo Link (TLINK) v5.1
· MS Macro Assembler v5.10b
· MS Linear Executable Linker (LINK386.EXE) v1.00.056

In the \SOURCE\DPMS directory, edit the MAKE.BAT files so that the paths point to the correct tools on your computer. Run MAKE to build the server (DPMS.EXE). This is copied into the \SOURCE\DPMS\BIN directory.

You need at least 600 Kb of TPA to build DPMS.EXE. We therefore recommend that you use DR-DOS because of the extra TPA available. You can build the server into the DR-DOS kernel if you need an embedded solution and the DR-DOS source code is available from Caldera's web site.


DPMSTEST is a test program for DPMS servers. It is included in the SDK so that developers of DPMS servers can test their servers. The program exercises every DPMS function and outputs the results. While it is fairly thorough, it is not guaranteed to find every possible fault.

The test program is straightforward to use. Enter DPMSTEST /? for a summary of its use.

DPMS Limitations

DPMS 1.0 has the following known behavior and limitations:

· DPMI, if present, is not available to DPMS clients in protected mode as protected mode INT 031h instructions are reflected to real mode.

· There is no API for hooking interrupts in protected mode. You must hook all hardware and software interrupts in real mode, and use call-ups to pass control to a protected mode handler if required.

· Most DPMS calls from real mode are processed by the server in protected mode, and therefore the server must switch modes twice for each call. These mode switches are not required for DPMS calls originating in protected mode. This gives a performance advantage for protected mode over real mode. It is therefore recommended that you make any frequent API calls, such as setting up descriptors, from protected mode wherever possible.

[Front] [Prev Chapter][Next Chapter]

Copyright © 1994, 1997 Caldera, Inc. All rightsreserved.