QNX RTOS v4 Knowledge Base
QNX RTOS v4 Knowledge Base
Title |
Accessing physical memory addresses in QNX4 |
Ref. No. |
QNX.000000744 |
Category(ies) |
Development |
Issue |
A function needs to be called at a specific physical memory address. This function has the following requirements:
1) it is called in 32-bit protected mode (i.e. CS is a selector for a segment with 32-bit default addresses/operands)
2) parameters are in specific general purpose registers
3) CS and DS both have the same base and both encompass a range that include the physical memory used by the function. They can have any base, but must be the same -- that is all 32-bit addresses (offsets) refer to the same memory whether relative to CS or DS.
4) the function returns with a far call.
We have used shm_open() and mmap() for data access to some physical memory. This works fine. We know about the PROT_EXEC attribute to the mmap feature to map the memory in as executable. We mapped the same range twice, once for execution and once for read access, but got two different logical addresses back (i.e. the offsets are different). Can you tell me what we need to do? Specifically:
1) are there any specific memory model requirements for making this work?
2) do we need to call mmap twice (once for read and once for exec) or can we specificy PROT_READ|PROT_EXEC in one call?
3) mmap returns a 32-bit offset. Assuming this offset is relative to both CS and DS, we should be able to push cs and issue a (near) call to the function -- simulating a far call. In other compilers (assuming flat model with CS and DS at the same base) we could:
unsigned long eaxParm, ebxParm, eaxReturn, ebxReturn;
myPtr = mmap(....);
asm { mov eax,eaxParm mov ebx,ebxParm //ds already at same base as cs push cs //simulate far call to current cs call [myPtr] mov eaxReturn,eax mov ebxReturn,ebx }
Will this work in QNX/Watcom C? If not, can you tell me what we need to change?
|
Solution |
This can be done if you set the map type to MAP_FIXED when using the mmap() funtion. Also have a look at the shmem.txt file in the /etc/readme/technote directory on any QNX 4.XX system. Note there are pitfalls to this such as it is not portable (POSIX) and you will have to make sure you link with the offset greater than where you are mapping into(use cc -@address, this is undocumented). You will want a memory model which looks like:
4K Your stuff 4k stack* code |______|____________|_____|________|__________| ^ |address starts here(cc -@)
*the stack will start from the address you give and grow down. The 4k page will give you a SIGSEGV if you go into this unmapped area, which will be easier to see than if your stack grows out of the area which you allocated. The first 4k of unallocated memory will take care of Null pointers. |
|