Effects of Changes in Ursula Memory Management on Applications and Testing Strategy
An important part of the changes being made to RISC OS to produce RISC OS 4 comprises modifications to the scheme of memory protection and management;
these changes can have unexpected repercussions for user applications, and may bring bugs to light which have existed unnoticed until this time.
Under RISC OS 3.7 and earlier versions, memory protection was very limited;
broadly speaking, if an application switched the processor into an appropriate mode, it could read almost all of system space (below &8000) and most areas above application space (&1C00000 upwards). It could also write to a number of places outside application space, and outside space occupied by dynamic areas either owned by it or considered to be shared read/write among all applications.
Areas which have been Moved, or which are now Protected The few areas of memory which are effectively protected under RISC OS 3.7 are also protected under RISC OS 4, however a number of additional areas are now protected such that attempting to write to them (or in some cases even read from them) from a user process will cause a data abort. According to RISC OS guidelines a user application should never have need to access these areas under RISC OS >=3.1 anyway,, however it has been known for applications to do so inadvertantly.
Note that the address ranges quoted below are supplied to aid debugging of code initially moved to RISC OS 4. They do not imply that any addresses of OS areas may be assumed for any version of the OS, nor that any areas are necessarily public.
The areas which are affected by protection or reorganisation changes are:
* kernel workspace (&0 - &4000)
This area is private and must not be accessed by third parties in any processor mode. RISC OS 4 protects this area where possible from user mode writes. Address zero may be protected from user mode reads. The symptom of broken behaviour is a data abort with a fault address in the range 0 to &4000; the most likely cause of such a failure is accidental dereferencing of null pointers (eg doing something which collapses to _kernel_swi(number, NULL, NULL) ). .
* SVC stack (&1C00000 - &1C08000)
This area is reserved for privileged mode. RISC OS 4 now protects this from any user access. The symptom of broken behaviour is a data abort with a fault address in the range &1C00000 to &1C08000.
* Environment string returned by OS_GetEnv.
This area should always have been assumed to be read only. Under RISC OS 4, attempting to write to the environment string in user mode will cause a data abort somewhere in kernel space (qv).
* Copy of physical space (&80000000 - &90000000).
This area is private and must not be accessed by third parties in any circumstance. On RISC OS 4, there is no longer a copy of physical DRAM space, and this area of memory has been reassigned for other purposes. The address range of this area is &80000000 to &90000000; although an application data abort will not be produced by accessing this area, unperdictable behaviour will result.
* MMU tables (&2C00000 - &3000000)
This area is private and must not be accessed by third parties in any mode.
This area has moved from its previous location in RISC OS 3.7. The symptom of broken behaviour is a data abort with a fault address in the range &2C00000 to &3000000.
Checking a huge pile of source by eye to find the call which is provoking a data abort is not a simple process. A few ways exist to make the job simpler...
1. Acquire a copy of Dr Smith's Toolkit from Warm Silence (http://www.wss.co.uk/ ). The memory access checker MemCheck is written such that any accesses outside areas permitted under application authoring guidelines will be faulted, so this makes an excellent tool for checking existing code without having to insert additional routines.
2, etc: to be written.