Privilege function memory section start address shall always at the start of the flash?

Hi Guys

I noticed that in STM32 demos, it states that we need to start the privilege function from the beginning of the flash, e.g. 0x0800 0000 for Armv7 series like cortex-M3,M4. And it also says to include ISR into the privilege function memory section.

However, it doesn’t say why or what is the benefit doing like that, what might be consequence if not doing that.

In my test project, I have put privileged function memory section somewhere in the middle of the flash without including the ISR. It seems working fine. So why do we need to put privilege function memory section at the beginning of the flash and put privilege functions right after the ISR ?

Thanks for your help.

code from stm32 demo

/* The startup code and FreeRTOS kernel code are placed into privileged
   * flash. */
  .privileged_functions :
  {
    . = ALIGN(4);
    _start_address = .;
    KEEP(*(.isr_vector)) /* Startup code. */
    . = ALIGN(4);
    *(privileged_functions)
    . = ALIGN(4);
    FILL(0xDEAD);
    /* Ensure that non-privileged code is placed after the region reserved for
     * privileged kernel code. */
    /* Note that dot (.) actually refers to the byte offset from the start of
     * the current section (.privileged_functions in this case). As a result,
     * setting dot (.) to a value sets the size of the section. */
    /* . = __privileged_functions_region_size__; */
    _end_address = .;
    mysize = _end_address - _start_address;
    . = ALIGN(0x8000);


  } >FLASH

Hi @pasu

In ARM Cortex-M architectures, placing the privileged section at the beginning of flash has some benefits:

  1. The ARM Cortex-M processors expect the interrupt vector table (which contains the reset vector and exception handlers) to be at address 0x00000000 by default. This is the start address of the flash memory.
  2. Placing privileged code at the start ensures fast and direct access to the critical routines
    ( ISRs and fault handlers ).
  3. The MPU often requires memory regions to be aligned to power-of-two boundaries and to start at specific addresses. Placing the privileged section at the beginning of flash simplifies the configuration of memory protection, as the start of flash aligns naturally.

Technically, you can place the privileged section elsewhere in flash if:

  • You have to adjust the vector table offset register (VTOR) to point to the new location of your vector table.
  • You should configure the MPU regions correctly to protect and partition privileged/unprivileged memory spaces.
  1. Placing both the ISR vector table and the privileged functions together ensures they are stored in the same memory region, often the fastest part of flash (like sector 0 in STM32). This leads to faster memory access and slight improvement in performance.
  2. Simplified MPU configuration and Security considerations :-
  • Placing ISRs and privileged functions together creates a single continuous privileged memory region. This simplifies MPU configuration since you can protect the entire block with one region setting.
  • Having privileged code in scattered locations would require more complex MPU configurations, increasing the chance of misconfiguration and accidental exposure.

You can place .privileged_functions elsewhere in flash, provided you correctly configure the MPU and ensure the vector table points to the correct location.
That is why, your changes work , but it is not recommended.

An MPU region is used to grant privileged code Read and Execute permissions to the .privileged_functions section. The only requirement is that the .privileged_functions section satisfies MPU requirements which for ARMv7-M are the following:

  1. The size is a power of 2.
  2. The region start address is a multiple of size.

If these 2 requirements are not satisfied, the MPU configuration will be WRONG. Putting the privileged section first in the flash makes it easier to satisfy these requirements. Putting ISRs in this region grants privileged code Read and Execute permissions to them as well. Because we use background region, even if you do not explicitly put ISR code in .privileged_functions, privileged code will have all the access (Read, Write and Execute) to them.

Hi @karahulx and @aggarg
Thanks for your explanation.

How to understand the following statement from the stm32 mpu demo project?
/* Ensure that non-privileged code is placed after the region reserved for
* privileged kernel code. */

What might be the consequence if I put some non-privileged code before the privileged code ?

Cheers

If the non-privileged region comes first, it may inadvertently allow access to privileged regions due to misalignment or overlapping configurations.
By placing privileged code first, the MPU ensures that unauthorized access from non-privileged tasks is blocked.

The flash layout for the demo looks like the following:

Assuming Cortex-M4, we use 2 MPU regions:

  1. Flash Start to Flash End - Grant unprivileged code Read and Execute access.
  2. Privileged Code Start to Privileged Code End - Grant privileged code Read and Execute access.

Because ARMv7-M allows overlapping regions, privileged code region is accessible only to privileged code.

As long as your privileged code region satisfies MPU hardware requirements, you should be good. What problem are you trying to solve by putting the privileged code in the middle of flash?