Logical, Linear, & Physical Addresses

I don't know if this is the right forum to post this question, but I think it may be the one with the most knowledgable users. I'm going to explain what I'm trying to do and what I've discovered so far before I actually ask the questions.

I'm trying to write some programs in DOS that interact with PCI hardware. The PCI hardware, because it bypasses the CPU and controls the Address Bus directly, always requires a physical address for memory manipulation. Of course, when you're writing a program, you always use a logical or linear address for memory amnipulation. When you want to read/write something to/from the "shared" memory space, you have to know both the logical/linear address (for the "CPU side" to use) and the physical address (for the "PCI side" to use).

In real mode, of course, the linear and physical address are the same, so the conversion is trivial. In most modern situations, though, you're usually not in real mode even when at a DOS prompt. You're either in protected mode under VCPI (using "real DOS" and a memory manager like EMM386), or in protected mode under DPMI (with Windows or some other DPMI server).

Under DPMI, I cannot figure out a good way to perform the conversion between linear and physical addresses. DPMI has INT 31h, Function 0800h, which is supposed to convert a physical address to a linear address, but not all DPMI servers support it. There is no DPMI function at all that I can find to convert a linear address to a physical address. Also, at least under Windows, Paging always seems to be enabled so it's not possible to just assume that the linear address and physical address are the same.

I've figured out how to do the conversions under VCPI, but there are some "quirky" things going on that I don't understand. To convert a Segment:Offset (logical) address to a linear address, you just multiply the Segment by 16 and add the Offset. I've also seen it declared in several places that "If Paging is disabled in the CPU, the linear address and physical address are the same", or words to that effect. Under VCPI (at least from what I've seen), Paging is always disabled. So, theoretically, it should be trivial to convert a linear address anywhere in memory to a physical address under VCPI, but it doesn't work that way.

VCPI has a service (INT 67h, Function DE06h) that will convert an address in the first MB of memory to a physical address for you. If you do this, you will find that some of the addresses in upper memory (the space between 640K and 1MB) are not in physical memory where the statement "If Paging is disabled in the CPU, the linear address and physical address are the same" tells you they should be. So, either the statement is not true, or there's some "missing piece" that I don't understand. Under VPCI, from what I can tell, all addresses above 1MB are linear address = physical address.

So, basically, here are my questions:

1) Under DMPI how can I convert a linear address to a physical address and vice-versa? I would like to do this without switching to protected mode, but will if there's no other way.

2) What's going on under VCPI where some of the upper memory addresses do not map linearly to physical addresses, even when Paging is disabled in the CPU? I suspect VCPI might be using some sort of memory-access exception trap, but why would they even bother?

Thanks in advance for any help provided!

Comments

  • Sorry to not be much of a help, but I don't think you'll be able to get to the memory mapped PCI stuff from a DOS box running under any sort of windows system. Even requesting memory pages that are in the range of where PCI stores stuff (up near 4 gig) windows probably will only serve you stuff from its own stash, and those might not even be physical pages.

    Windows is going to fight you to the end to keep you from reading and certainly from writing to those protected and reserved areas of memory. I think your best bet is to have a windows based driver that can get to ring 0, that can somehow(?) be called from a DOS app to go fetch those memory addresses for you, you might even have to use a file as a temporary swapping area for DOS and your windows driver to communicate.

    The only way I have ever dos PCI stuff (and I've done a lot of it) is via unreal mode in a clean DOS environment.

    -jeff!
  • : Sorry to not be much of a help, but I don't think you'll be able to
    : get to the memory mapped PCI stuff from a DOS box running under any
    : sort of windows system. Even requesting memory pages that are in
    : the range of where PCI stores stuff (up near 4 gig) windows probably
    : will only serve you stuff from its own stash, and those might not
    : even be physical pages.
    :
    : Windows is going to fight you to the end to keep you from reading
    : and certainly from writing to those protected and reserved areas of
    : memory. I think your best bet is to have a windows based driver
    : that can get to ring 0, that can somehow(?) be called from a DOS app
    : to go fetch those memory addresses for you, you might even have to
    : use a file as a temporary swapping area for DOS and your windows
    : driver to communicate.
    :
    : The only way I have ever dos PCI stuff (and I've done a lot of it)
    : is via unreal mode in a clean DOS environment.
    :
    : -jeff!

    I figured as much. I was hoping somebody might have a "back-door" method that might work. At least for now, all I'm interested in doing is reading, not writing.
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

In this Discussion