[Front] [Prev chapter]
[Next Chapter]
Chapter 1 DOS Protected Mode Services
Introduction
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.
Restrictions
· 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.
Initialization
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
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]
info@caldera.comCopyright © 1994, 1997 Caldera, Inc. All rightsreserved.