OS/2 codes: DosAliasMem(), mapping an address to another address
Many modern OSes support memory mapping. For example, mmap() family of POSIX. However OS/2 has no such APIs supporting it fully. Instead, OS/2 provides an API supporting it partially, which maps an address to another address. It's DosAliasMem().
DosAliasMem() has not been known until Toolkit 4.5. You can see the explanation about DosAliasMem() in <OS/2 Programming
Guide and Reference Addendum> Toolkit 4.5, or http://cyberkinetica.homeunix.net/os2tk45/addendum/022_L2_DosAliasMem.html.
Here is a brief explanation.
Remember that cbSize is rounded up to 4K, and ppAlias is always allocated in low-memory area. That is, OBJ_TILE is implied. That's too bad
Generally, it's enough to set flags to 0.
The allocated memory by DosAliasMem() should be freed by DosFreeMem().
The usage of DosAliasMem() may be two ways. One is to map an address to another address. This may be used to mimic mmap(). See https://github.com/komh/os2compat/blob/master/memory/mmap.c. The other one is to find LDT for high-memory objects. As I said above, DosAliasMem() always allocates an alias in low-memory area. In addition, this alias is 64K aligned. That is, it's possible to calculate LDT from an alias memory with following formula.
Finally, here is the example to use DosAliasMem().
DosAliasMem() has not been known until Toolkit 4.5. You can see the explanation about DosAliasMem() in <OS/2 Programming
Guide and Reference Addendum> Toolkit 4.5, or http://cyberkinetica.homeunix.net/os2tk45/addendum/022_L2_DosAliasMem.html.
Here is a brief explanation.
#define INCL_DOSMEMMGRYou can see more details in the mentioned documents.
#include <os2.h>
APIRET APIENTRY DosAliasMem (PVOID pMem, ULONG cbSize, PPVOID ppAlias, ULONG flags)
Parameters
pMem input
Contains the address of the memory to be aliased. It must be on a page boundary (that is, 4K aligned), but may specify an address within a memory object.
cbSize input
Specifies the size in bytes for the memory to alias.
ppAlias output
Address of a location in which the address of the aliased memory is returned.
flags input
Flags are defined as follows
Remember that cbSize is rounded up to 4K, and ppAlias is always allocated in low-memory area. That is, OBJ_TILE is implied. That's too bad
Generally, it's enough to set flags to 0.
The allocated memory by DosAliasMem() should be freed by DosFreeMem().
The usage of DosAliasMem() may be two ways. One is to map an address to another address. This may be used to mimic mmap(). See https://github.com/komh/os2compat/blob/master/memory/mmap.c. The other one is to find LDT for high-memory objects. As I said above, DosAliasMem() always allocates an alias in low-memory area. In addition, this alias is 64K aligned. That is, it's possible to calculate LDT from an alias memory with following formula.
sel = (SEL) ((ULONG) (*ppAlias) >> 13 | 7)
Finally, here is the example to use DosAliasMem().
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | #define INCL_DOS #include <os2.h> #include <stdio.h> int main( void ) { PBYTE p; PBYTE pAlias; ULONG cb = 64 * 1024; ULONG flag; ULONG rc; rc = DosAllocMem( &p, cb, fPERM | PAG_COMMIT | OBJ_ANY ); if( rc ) { fprintf( stderr, "DosAllocMem : rc = %ld\n", rc ); return 1; } printf("p = %p\n", p ); rc = DosAliasMem( p + 4096, 8, &pAlias, 0 ); if( rc ) { fprintf( stderr, "DosAliasMem : rc = %ld\n", rc ); return 1; } printf("pAlias = %p, p + 4096 = %p\n", pAlias, p + 4096 ); *pAlias = 10; printf("*pAlias = %d, p[4096] = %d\n", *pAlias, p[ 4096 ]); rc = DosQueryMem( pAlias, &cb, &flag ); if( rc ) { fprintf( stderr, "DosQueryMem : rc = %ld\n", rc ); return 1; } printf("pAlias: cb = %ld, flag = %lX\n", cb, flag ); rc = DosFreeMem( pAlias ); if( rc ) { fprintf( stderr, "DosFreeMem(Alias) : rc = %ld\n", rc ); return 1; } rc = DosFreeMem( p ); if( rc ) { fprintf( stderr, "DosFreeMem : rc = %ld\n", rc ); return 1; } return 0; } |
댓글
댓글 쓰기