release
dev builds
extras
themes manual
wiki
device status forums
mailing lists
IRC bugs
patches
dev guide
translations



Search | Go
Wiki > Main > PluginMemoryLayout

Rockbox plugin memory layout

A plugin contains following segments:

.header The plugin header structure (see apps/plugin.h)
.text Executable code
.rodata Initialised read only data (e.g. string constants or const structs)
.data Initialised data (e.g. global variables with assignment)
.bss Not initialised data (e.g. global variables without assignment)

There are also some special segments that contain data that are eventually loaded to IRAM:

.iram Consists of .icode (executable code in IRAM), .irodata (initialised read only data in IRAM), .idata (initialised data in IRAM)
.ibss Not initialised data in IRAM

IRAM is a special memory area (fixed addresses) that can be accessed by the CPU very quickly. If a variable must be read or modified very often it should be placed to IRAM. This can be made by adding the following attributes to the declaration:

  • For a variable: IDATA_ATTR
  • For a function: ICODE_ATTR

Examples:

  • static struct dsp_config *dsp IDATA_ATTR = audio_dsp;
  • static void pcmbuf_callback(unsigned char** start, size_t* size) ICODE_ATTR;

Following symbols are declared during the linkage (see plugins/plugin.lds):

plugin_start_addr Start address of the .header section. Since .header is the first section (see below) this is also the address where the plugin is loaded
iramcopy Address where the .iram section of the plugin is loaded into memory. This is iimediately after the end of the .data section
iramstart Start address of the plugin's .iram section (relocation address).
iramend End address of the plugin's .iram section (relocation address). iramend-iramstart will give the size of the plugin's read only data (including code and vars).
iedata Start address of the plugin's .ibss section (relocation address)
iend End address of the plugin's .ibss section (relocation address). iend-iedata will give the size of the plugin's .ibss section
plugin_bss_start Start address of the plugin's .bss section
plugin_end_addr End address of the plugin's .bss section. plugin_end_addr- plugin_bss_start will give the size of the plugin's .bss section. Since .bss is the last section (see below) this is also the address where plugin ends when it's loaded into the RAM

The relocation address of the .iram section is the start of the IRAM area in the RAM. But when the plugin is loaded, its .iram section is loaded to another address (iramcopy).

The sections described above are laid out in memory as follows (this is how the RAM area into which the plugin is loaded looks like after the plugin has been loaded to RAM; this RAM area is actually the buffer pluginbuf, see apps/plugin.c):

.header ← plugin_start_addr
.text
.rodata
.data
.iram
← iramcopy
.ibss
.bss
← plugin_bss_start
← plugin_bss_end

If the plugin makes use of IRAM (code or data), one of the first actions in the plugin code should be a call to PLUGIN_IRAM_INIT(api). This copies the contents of the plugin's .iram section (which is pointed to by iramcopy) to the IRAM area and then zeroes out the area of RAM that contained the plugin's .iram and .ibss sections. After the call, the arrays iramcopy (its size is iramend-iramstart) and iedata (its size is iend-iedata) can be used by the plugin at will. If the plugin doesn’t make use of IRAM, iramend will be equal to iramstart and iend will be equal to iedata.

After the call to PLUGIN_IRAM_INIT(api), the RAM looks as follows:

Lower addresses
IRAM
Contents of the plugin's .iram section
Not initialised area, size=size of plugin's .ibss
... (Rest of IRAM)
"Normal" memory
... (Rockbox code, etc.)
.header (here the pluginbuf starts)
.text
.rodata
.data
Zeroed out area, size=size of .iram (contained .iram before the call, can now be used at will)
Zeroed out area, size=size of .ibss (contained .ibss before the call, can now be used at will)
.bss
... (Rest of RAM)

The call to PLUGIN_IRAM_INIT(api) is not made by the plugin loader but must be made by the plugin itself because if the plugin uses IRAM the music playback must be stopped (music playback also uses IRAM). So the plugin has a chance e.g. to ask the user whether it would be OK to stop the playback and start the plugin. If the call would be made by the plugin loader, music playback would unconditionally stopped. It's assumed that a programmer who's advanced enough to use IRAM in the plugin will be also careful enough and will not forget to call PLUGIN_IRAM_INIT(api).

r2 - 02 Apr 2021 - 20:46:07 - UnknownUser

Copyright © by the contributing authors.