I have been working on MMU support with task stack protection for the Cortex A5, and have the MMU working as intended on my part. However, I am running into this issue, that the vListInsert(and probably more) create a list that writes into a different task space, which causes a permission fault.
I don’t know how you have set up the MPU on the Cortex-A, but in the
Cortex-M MPU port we run the kernel code in privileged mode, then it can
access the memory allocated to unprivileged tasks.
When does it switch? Is the kernel code started yet after you call vTaskDelay() which ends up calling vListInsert?
The Cortex A5 doesn’t have an MPU, rather an MMU, which takes a bit different thinking. So the createtask allocates out of a page aligned pool, then each allocated pool is set to be protected from other asid’s.
On the A port, it would appear that tasks are running in SYS mode, I’m not sure about the thinking behind that.
I’m afraid it is not clear to me what you are trying to achieve. Our
MPU (noting that you have MMU, which in the past we have used as a kind
of MPU just without virtual memory) port is used to enable different
tasks to run at different privilege levels, and to isolate different
memory regions. A task can run unprivileged, with a switch to privilege
being effected using an SVC instruction each time it calls a FreeRTOS
API function. I think in all memory protected cases the OS has to run
with privileges (kernel mode) otherwise you are going to get the issue
you are reporting - the kernel is isolated from the memory it needs to
access.
Elevation should happen prior to calling vTaskDelay(). This is normally
done by having the API function not a direct C subroutine call, but an
SVC call, SVC being the only way to programmatically raise privilege.
We take a slightly simpler approach though by wrapping vTaskDelay() in a
function called MPU_vTaskDelay() that raises privilege then calls the
standard vTaskDelay(). The standard vTaskDelay() must be in a memory
areas that is marked as privileged execution only, and the raising of
the privilege must check that the source of the SVC was one of the
MPU_nnn() function wrappers.
Thank you, this is making sense now. I don’t see anywhere in the present code where the source of the SVC is checked though.
So is this whole MPU thing just a leftover from someone elses project, or is this active?
I suppose MMU support is too outside of what average FreeRTOS applications need. For me, it is more about developing a complex program and reducing development time.
Anyway, I suppose it was done this way as to keep code uncluttered, but it seems it would be cleaner if it was something like this.
Thank you, this is making sense now. I don’t see anywhere in the present
code where the source of the SVC is checked though.
That may be the case in the code in SVN, which was created with safety
in mind rather than security. Our Cortex-M33 code on the other hand is
more security focused, so does not permit any code other than the API
function to use an SVC instruction.