CHAPTER 3 MEMORY PROTECTION FUNCTIONS
This chapter describes the memory protection functions performed by the RI600PX.
The RI600PX achieves following memory access protection function by using MPU (Memory Protection Unit) found in MCU. Note, handlers can access all address space.
1 ) Detection of illegal access by tasks and task exception handling routines
Tasks and task exception handling routines can access only permitted memory objects. The access exception handler will be invoked if a task or task exception handling routine access the area that has not been permitted.
2 ) Protection of user stack area
The user stack area of each task is inaccessible from other tasks. The access exception handler will be invoked if an user stack overflows or a task accesses an user stack for another task.
3 ) Detection of illegal access by the RI600PX
Some service calls receives pointers as argument. The RI600PX inspects whether the invoking task can access to the area indicated by the pointer. The service call returns E_MACV error when the invoking task does not have the access permission to the area.
And some service calls saves the context registers of the invoking task. If the user stack will overflow at the time, the service call returns E_MACV error.
This feature is available only for service calls issued from task context.
3.2 Domain, Memory object, Access permission vector
The memory protection function is achieved by controlling the following.
- What access is permitted
The one that corresponds to "Who
" is domain. Tasks and task exception handling routines belong to either of domain without fail. Domains are distinguished by domain ID with the value from 1 to 15. Domains is generated statically by the system configuration file.
The one that corresponds to "To where
" is memory object, and the one that corresponds to "What access is permitted
" is
access permission vector.
Usually, memory objects are registered statically by the system configuration file. Memory objects can be registered dynamically by using
ata_mem service call and unregistered by using
det_mem service call. The start address of a memory object must be 16-bytes boundary, and the size must be multiple of 16.
Access permission vector represents whether tasks that belong to each domain can access (operand-read, operand-write,
execution access) to the memory object.
The access exception handler will be invoked if a task accesses to the memory object that has not been permitted, or a task accesses other than memory objects and user stack for itself.
On the other hand, in handlers (interrupt handlers, cyclic handlers, alarm handlers and access exception handler), there is
no concept of belonging domain. Handlers can access all address space.
Figure 3-1 Summary of Memory Protection
Table 3-1 shows the operation concerning memory objects.
Table 3-1 The operation concerning memory objects
|
Static (system configuration file)
|
|
|
|
|
|
|
|
|
|
|
(Other than memory object can be checked.)
|
|
|
|
|
|
3.3 Restriction in the Number of Memory Objects
The number of memory objects to which either of access (operand-read, operand-write and execution access) has been permitted by a certain domain is seven or less. Please design memory map with careful attention to this. The E_OACV error is detected when this restriction are no longer filled by
ata_mem or
sac_mem.
In the system which does not support protection mechanism other than memory protection, for example, the possibility of the following illegal accesses can be considered.
1 ) The task-A with malice does not have access permission for the memory object-M.
2 ) The coder wrote the source code for Task-A to create and start the task-B that belongs to the domain which has access permission for the memory object-M.
3 ) The illegal access is not detected if the task-B accesses the memory object-M.
To prevent such illegal access, the RI600PX supports "trusted domain
". The following service calls that gives the change to the composition of software can be called only from tasks that belongs to trusted domain. TheE_OACV error is detected when a tasks that does not belong to trusted domain calls either of these service calls.
- cre_???, acre_???, del_???, def_tex, ata_mem, det_mem, sac_mem
3.5 Change Access Permission
The access permission for a memory object can be changed dynamically by using
sac_mem.
For instance, the following example showcases the requirement to change the access permission.
In this example, it is required download application into memory that belongs to another domain and execute the application as a task .
1 ) Register the area for downloading as a memory object (
ata_mem). At this time, specify to permit access the memory object from the domain-A that the task to download belongs to. Afterwards, download to the memory object area.
2 ) After downloading, set to be able to access the memory object from the domain-B (
sac_mem). And create and start the downloaded code as the task that belongs to the domain-B.
3.6 Protection of User Stack
The user stack of each task can be accessed only by the task. The access exception handler will be invoked if the user stack overflows or a task accesses the user stack for another task.
When service call invoked from task uses user stack, the RI600PX inspects whether stack pointer points in the range of the user stack for invoking task. If not, the error E_MACV is returned.
3.7 Check Access Permission
In the program called from two or more domains, there is a scene that the program wants to judge whether the program can access the memory. In such a case,
vprb_mem service call is useful. The
vprb_mem inspects whether the specified task can do the specified access to the specified memory area.
The memory protection by MPU (Memory Protection Unit) is effective only at user mode.
In the RI600PX system, task context executes in user mode, and non-task context executes in supervisor mode.
3.9 Enable MPU (Memory Protection Unit)
The RI600PX enables MPU at initiation (
vsta_knl,
ivsta_knl). Do not disable MPU after the RI600PX has been initialized. If the MPU is disabled, the system operation cannot be guaranteed.
3.10 Access Exception Handler (_RI_sys_access_exception( ) )
The access exception handler will be invoked when a task or task exception handling routine accesses the memory that has not been permitted. For such situation, the access exception handler can either remove the factor of illegal access and return to normal program execution or be used for debug purposes.
3.10.1 User-Own Coding Module
The access exception handler must be implemented as user-own coding module.
Note The source file for the access exception handler provided by the RI600PX as a sample file is access_exc.c
".
- Basic form of access exception handler
The following shows the basic form of access exception handler.
#include "kernel.h" // Provided by RI600PX
#include "kernel_id.h" // Generated by cfg600px
////////////////////////////////////////////////////////////
// Access exception handler
////////////////////////////////////////////////////////////
void _RI_sys_access_exception(UW pc ,UW psw, UW sts, UW addr);
void _RI_sys_access_exception(UW pc ,UW psw, UW sts, UW addr)
{
............
............
}
|
Note The function name of access exception handler is "_RI_sys_access_exception
".
|
|
|
|
|
|
|
The instruction address that causes access exception
|
|
|
|
The PSW value at access exception
|
|
|
|
Factor of access exception
Value of MPESTS register in the MPU (Memory Protection Unit)) is passed.
|
|
|
|
In the case of operand access error, the accessed address ( = Value of MPDEA register in the MPU) is passed.
In the case of execution access error, the addr is indeterminate.
|
- Stack
The access exception handler uses the system stack.
- Service call
The access exception handler can issue service calls whose Useful range
" is Non-task
".
- PSW register when processing is started
Table 3-2 PSW Register When Access Exception Handler is Started
|
|
|
|
|
All interrupts are masked.
|
|
|
Do not lower IPL more than the start of processing.
|
|
|
|
|
|
|
|
|
|
|
|
|
3.11 Design of Memory Map
This section explains information required for a design of memory map.
3.11.1 The Restrictions regarding the Address of Memory Objects
The start address of memory objects must be 16-bytes boundary, and the size must be multiple of 16.
When a memory object is registered by the static API "memory_object[]
" in the system configuration file, the start address can be specified by absolute address value or section name.
To specify I/O register area, absolute address value should be used.
When specifying section name, the start section and end section of the memory object should be specified. In this case, the sections must be arranged as assumption at linking. For example, specify "aligned_section
" linker-option for the section specified for "start of memory object
" (memory_object[].start_address) because the start address of memory object must be 16-bytes boundary.
And the size of memory objects must be multiple of 16. In other words, the termination address of memory object must be multiple of 16 + 15. But, the end section (specified for memory_object[].end_address) does not necessary become just like that. When the termination address of the end section is not multiple of 16 + 15, the area from the termination address + 1 to next multiple of 16 + 15 is also treated with a part of the memory object. Therefore, don't arrange any sections in the range from the termination address + 1 to next multiple of 16 + 15.
- Example
When specifying "CU_DOM1
" for "memory_object[].end_address
" and the termination address of CU_DOM1 section is 0xFFFF1003, do not arrange any sections from 0xFFFF1004 to 0xFFFF100F. To achieve this requirement, specify "aligned_section
" linker option to the section which follows "CU_DOM1
".
3.11.2 Area That Should Be the Inside of Memory Objects
1 ) Area that is accessed by tasks
Tasks can access only memory objects to which the permission is appropriately set except it's own user stack. Therefore, it is necessary that program sections, constant sections, uninitialized data sections and initialized data sections accessed by tasks should be allocated to the inside of memory objects. Moreover, when the task accesses I/O area, the I/O area should be the inside of memory objects.
2 ) Message area handled by mailbox
The message must be generated in the memory objects that both transmitting task and receiving task can access.
However, the management table exists in the top of message area. The system operation cannot be guaranteed if the management table is destroyed. For this reason, data queue or message buffer is recommended for message communication.
3 ) Fixed-sized and variable-sized memory pool area
The memory pool area should be the inside of memory object which can be accessed by tasks that use memory blocks.
However, the RI600PX generates management tables in the memory pool area. The system operation cannot be guaranteed if the management table is destroyed.
- A fixed-sized memory pool is created by the system configuration file
The fixed-sized memory pool area is generated in the section indicated by "memorypool[].section
". When "memorypool[].section
" is omitted, the fixed-sized memory pool area is generated in the "BURI_HEAP
" section.
- A fixed-sized memory pool is created by
cre_mpf or
acre_mpf
Application should acquire the fixed-sized memory pool area, and specify the start address for cre_mpf or acre_mpf.
- A variable-sized memory pool is created by the system configuration file
The variable-sized memory pool area is generated in the section indicated by "variable_memorypool[].mpl_section
". When "variable_memorypool[].mpl_section
" is omitted, the variable-sized memory pool area is generated in the "BURI_HEAP
" section.
- A variable-sized memory pool is created by
cre_mpl or
acre_mpl
Application should acquire the variable-sized memory pool area, and specify the start address for cre_mpl or acre_mpl.
3.11.3 Area That Should Be the Outside of Memory Objects
1 ) All the RI600PX sections except BURI_HEAP
The RI600PX sections except BURI_HEAP should be allocated to the outside of memory objects because these sections are accessed only by the RI600PX. Refer to "
2.6.4 Arrangement of section" for the RI600PX sections.
2 ) User stack area for tasks
The user stack area for tasks should be outside of memory objects. The correct system operation cannot be guaranteed if the user stack area overwraps with either all user stacks and memory objects.
- A task is created by the system configuration file
The user stack area is generated in the section indicated by "task[].stack_section
". When "task[].stack_section
" is omitted, the user stack area is generated in the "SURI_STACK
" section.
- A task is created by
cre_tsk or
acre_tsk
Application should acquire the user stack area, and specify the start address for cre_tsk or acre_tsk.
3 ) Data queue area
The data queue area should be outside of memory objects. The correct system operation cannot be guaranteed if the data queue area overwraps with either all user stacks and memory objects.
- A data queue is created by the system configuration file
The data queue area is generated in the "BRI_RAM
" section of the RI600PX.
- A data queue is created by
cre_dtq or
acre_dtq
Application should acquire the data queue area, and specify the start address for cre_dtq or acre_dtq.
4 ) Message buffer area
The message buffer area should be outside of memory objects. The correct system operation cannot be guaranteed if the message buffer area overwraps with either all user stacks and memory objects.
- A message buffer is created by the system configuration file
The message buffer area is generated in the "BRI_RAM
" section of the RI600PX.
- A message buffer is created by
cre_mbf or
acre_mbf
Application should acquire the message buffer area, and specify the start address for cre_mbf or acre_mbf.
5 ) Fixed-sized memory pool management area
The fixed-sized memory pool management area should be outside of memory objects. The correct system operation cannot be guaranteed if the fixed-sized memory pool management area overwraps with either all user stacks and memory objects.
- A fixed-sized memory pool is created by the system configuration file
The data queue area is generated in the "BRI_RAM
" section of the RI600PX.
- A fixed-sized memory pool is created by
cre_mpf or
acre_mpf
Application should acquire the fixed-sized memory pool management area, and specify the start address for cre_mpf or acre_mpf.