Search code examples
embeddedmicrocontrollerriscvlinker-scriptsriscv32

Access rights in RISC-V linkerscripts


When programming ARM-based microcontrollers, I'm used to see a MEMORY{..} segment in the linkerscript like this:

MEMORY
{ 
    FLASH (rx): ORIGIN = 0x08000000, LENGTH = 128K
    RAM (xrw): ORIGIN = 0x20000000, LENGTH = 32K
}

The access rights are easy to understand:

  • r: read
  • w: write
  • x: execute

I'm making my first steps in the world of RISC-V based microcontrollers. The GD32VF103CBT6 microcontroller from GigaDevice has the following MEMORY{..} segment in its linkerscript:

MEMORY
{ 
    /* Run in FLASH */ 
    flash (rxai!w) : ORIGIN = 0x08000000, LENGTH = 64k
    ram   (wxa!ri) : ORIGIN = 0x20000000, LENGTH = 20k 

    /* Run in RAM */ 
    /* flash (rxai!w) : ORIGIN = 0x20000000, LENGTH = 15k */
    /* ram   (wxa!ri) : ORIGIN = 0x20003C00, LENGTH = 5K  */
}

How should I interpret these access rights?


Solution

  • They're not really "access rights", but rather "what kind of sections may be placed here".

    From the GNU LD documentation (with some formatting mangled in the process of quotint :

    The attr string must consist only of the following characters:

    • ‘R’
      Read-only section
    • ‘W’
      Read/write section
    • ‘X’
      Executable section
    • ‘A’
      Allocatable section
    • ‘I’
      Initialized section
    • ‘L’
      Same as ‘I’
    • ‘!’
      Invert the sense of any of the attributes that follow

    If an unmapped section matches any of the listed attributes other than ‘!’, it will be placed in the memory region. The ‘!’ attribute reverses the test for the characters that follow, so that an unmapped section will be placed in the memory region only if it does not match any of the attributes listed afterwards. Thus an attribute string of ‘RW!X’ will match any unmapped section that has either or both of the ‘R’ and ‘W’ attributes, but only as long as the section does not also have the ‘X’ attribute.

    With that background, I would interpret your config as follows:

    flash (rxai!w) : ORIGIN = 0x08000000, LENGTH = 64k
    

    ...means that the "flash" region may contain anything except writeable sections, and

    ram   (wxa!ri) : ORIGIN = 0x20000000, LENGTH = 20k 
    

    ...means that the "ram" region may contain anything except read-only and initialized sections.