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.

#define INCL_DOSMEMMGR
#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  

You can see more details in the mentioned documents.

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;
}

댓글

이 블로그의 인기 게시물

토렌트: < 왕좌의 게임 > 시즌 1 ~ 시즌 8 완결편 마그넷

토렌트: NGC < 코스모스 > 우리말 더빙 전편(1편~13편) 마그넷

토렌트: < 스타워즈 > Ep.1 ~ Ep.6 마그넷