Node:Above 1MB, Next:, Previous:Fat DS, Up:Low-level

18.7 Accessing absolute address above 1MB

Q: How can I access memory-mapped peripheral devices (or any other absolute address) above 1 MByte mark?

A: You should use DPMI functions to allocate an LDT descriptor, and map it to an absolute physical address. This maps the physical address of the memory on the device to a linear address, and returns that linear address to you. You then create a selector to access the span of linear addresses on the device.

Here are the DPMI calls that you will have to use:

All of these DPMI calls have __dpmi_XXX wrappers in the DJGPP library. Here's a somewhat schematic example:

 #include <dpmi.h>
 .
 .
 __dpmi_meminfo mi;
 int selector;
 .
 .
 /* Map the physical device address to linear memory.  */
 mi.address = physical_address;
 mi.size    = physical_address_size;
 __dpmi_physical_address_mapping (&mi);
 /* Now mi.address holds the linear address.  */
 .
 .
 /* Allocate an LDT descriptor and set it up to span the entire
    device on-board memory.  */
 selector = __dpmi_allocate_ldt_descriptor (1);
 __dpmi_set_segment_base_address (selector, mi.address);
 __dpmi_set_segment_limit (selector, mi.size - 1);

Note that the segment limit should be one less than the size. Also, segments over 1MB in length must be a multiple of 4KB, otherwise the DPMI server might fail the call, or silently change the limit.

You can then use the functions from the sys/farptr.h header file to access that device. See accessing memory-mapped devices, for more details about accessing memory-mapped devices given their linear address.

The DPMI function that is issued by __dpmi_physical_address_mapping only works reliably for addresses above 1MB mark. If you call it with a physical address in the first Megabyte, it might fail, depending on the DPMI server (e.g., CWSDPMI fails such calls). (The DPMI spec explicitly says that programs should not call this function to access memory below the 1MB boundary.) This failure usually means that the offending address is already mapped into the page tables, so you shouldn't worry about it; and most DPMI servers map the first Megabyte 1:1 anyway.