KitFreeMiNT
Memory protection
- V.1 Four types of memory
- V.2 PRG flags for protection
- V.3 Mxalloc() protection flags
V.1 Four types of memory
Memory protection works on a per-process basis. Unless it uses the special mode bits in Mxalloc(), a process' entire text+data+bss and any memory it allocates will be of the same type. There are four types of memory:
| Type | Description |
|---|---|
| Private | Only the process itself (and the OS) can use the memory. |
| Global | This memory is totally unprotected. |
| Super | This memory can be accessed by anybody from Super mode. |
| Private/readable | Anybody can read, nobody else can write. |
By default, all processes load into private memory. If a program terminates and remains resident with the Ptermres() system call, then its private memory will be converted to Super memory; that's because TSRs won't work in private memory. Some TSRs may in fact need to be set to load into global memory (if they provide services for user mode programs).
There are other programs which need to grant wider access to their memory space: for example, the Gulam CLI is one, because Gulam's children can call Gulam through a pointer found in the system variable space. But Gulam is a bad choice of shell anyway, because you can't run more than one of them. Current versions of STeno also must grant wider access, because it passes data to STalker using shared memory; private/readable is adequate for that. Programs that load before MiNT does (i.e. in the AUTO folder) will find themselves in global memory. This is the easiest way to be sure that your TSRs will go on working: RAMdisks, FOLDR100, CACHE080, etc. all work when loaded that way. Notice that a process can grant wider access to its own address space, but it can't change the access permissions of any other process' space. If you set the PRGFLAGS of some process so it loads into global memory, that doesn't mean it can access anybody else's memory, it just means that anybody can access its memory.
V.2 PRG flags for protection
The second-least-significant nybble of PRGFLAGS field in the program header is the default mode for your program's memory protection. To review, here are all the defined bits in the PRGFLAGS field of PRG file headers, and what they mean:
| Bits | Meaning |
|---|---|
| 31-28 | This number, plus one, times 128K, is the minimum amount of alternative RAM that is acceptable. Used when there is more ST RAM than alternative RAM. |
| 27-13 | Reserved; currently unused. All programs should use 0 here. |
| 12 | Shared text bit. If set, the operating system will allow the TEXT segment of the program to be shared, i.e. if 3 copies of the program are running, there are 3 DATA and BSS areas but only 1 TEXT segment is shared amongst the 3 copies. SET THIS BIT ONLY IF YOUR PROGRAM CONTAINS NO ABSOLUTE REFERENCES TO DATA OR BSS, i.e. if it was compiled to use a base register for DATA and BSS. Very few existing programs can use this. |
| 11-8 | Reserved; currently unused. All programs should use 0 here. |
| 7-4 | This is the default memory-protection mode: 0=private,1=global, 2=super, 3=private/readable. Other values are reserved for Atari use and/or future modes. |
| 3 | Reserved; currently unused. All programs should use 0 here. |
| 2 | When 1, Malloc calls may be satisfied from alternative RAM. |
| 1 | When 1, the program may load into alternative RAM. |
| 0 | When 1, the program loads faster: the heap is not cleared. |
You can use prgflags.prg to change the PRGFLAGS value for any program. From the shell, say (for example)
prgflags 0xf0 0x10 myprog.prg
to set myprog.prg to global (0x10). The way you use PRGFLAGS is to
give it two numbers, then the program name(s) to operate on. The
first number is taken as a mask, and the second as a value: bits
which are one in the mask will be set to the corresponding bits in
the value; bits which are zero in the mask will not be changed. Thus
the example sets bits 4-7 to 0001 and leaves all other bits alone.
V.3 Mxalloc() protection flags
You can specify the protection you want on a region when you Malloc it: call Mxalloc(size,mode), where the least- significant nybble of mode means what it always has, and the next four bits are the desired protection mode.
| Bits | Meaning |
|---|---|
| 0-2 | ALTERNATIVE RAM ELIGIBILITY: |
| 0: ST RAM only | |
| 1: Alternative RAM only | |
| 2: Either, ST RAM preferred | |
| 3: Either, Alternative RAM preferred | |
| 3 | Reserved |
| 4-7 | PROTECTION MODE: |
| 0: Default (from your PRGFLAGS) | |
| 1: Private | |
| 2: Global | |
| 3: Super | |
| 4: World-readable | |
| Other values are undefined and reserved. | |
| 8-13 | Reserved |
| 14 | NO-FREE MODE: |
| When set, this bit means `if the owner of this region terminates, don't free this region. Instead, let MiNT inherit it, so it'll never be freed.' This is a special mode meant for the OS only, and may not remain available to user processes. | |
| 15 | Reserved |