Address Space

Memory address space is divided into system space (shared space) or task space (user space). The system space can be accessed from any task in the same way, and the task space can be accessed only from tasks that belong to that task space [Figure 8]. Multiple tasks may in some cases belong to the same task space.

The logical address space of task space and system space depends on the CPU (and MMU) limitations and is therefore implementation-dependent, but in principle task space should be assigned to low addresses and system space to high addresses.

Figure 8. Address Space

Since interrupt handlers and other task-independent software are not tasks, they do not have a task space of their own. Instead, while in a task-independent portion they belong to the task executing just before entering the task-independent portion. This is the same as the task space of the currently running task returned by tk_get_tid . When there is no task in RUNNING state, task space is undefined.

As for the system space and task space, other related explanations are available in tk_cre_tsk, Memory Pool Management Functions, and System Memory Management Functions.

In a system with no MMU (or not using an MMU), essentially task space does not exist.

Nonresident Memory

Memory may be resident or nonresident.

When nonresident memory is accessed, data is copied to that memory from a disk or other storage. It therefore requires complicated processing such as disk access by a device driver. Accordingly, when nonresident memory is accessed, the device driver, etc., must be in operational state. Access is not possible during dispatch disabled or interrupts disabled state, or while a task-independent portion is executing.

Similarly, in OS internal processing, it is necessary to avoid accessing nonresident memory in a critical section. One such case would be when the memory address passed in a system call parameter points to nonresident memory. Whether or not system call parameters are allowed to reference nonresident memory is an implementation-dependent matter.

Data transfer from a disk or the like due to nonresident memory access is not performed by μT-Kernel. Normally μT-Kernel is used along with subsystems that handle virtual memory management and other such processing.

In a system that does not use virtual memory, system call parameters or the like pointing to nonresident memory can be ignored, treating all memory as resident.

Protection Levels

μT-Kernel assumes four levels of memory protection, from 0 to 3.

The uses of each protection level are as follows.

Protection LevelsUsage
0Kernel, subsystems, device drivers, etc.
1System application tasks
3User application tasks

A non-task portion (task-independent portion, quasi-task portion, etc.) runs at protection level 0. Only a task portion can run at protection levels 1 to 3. A task portion can also run at protection level 0.

Some MMUs support only two protection levels, privileged and user level. In such a case protection levels 0 to 2 are assigned to privileged level, and protection level 3 to the user level, as if there were 4 levels. In a system with no MMU, all protection levels 0 to 3 are treated as identical.