The Multi-Sandbox capability of the MicroEJ Core Engine allows a main application (called Standalone Application) to install and execute at runtime additional applications (called Sandboxed Applications).
The MicroEJ Core Engine implements the [KF] specification. A Kernel is a Standalone Application generated on a Multi-Sandbox-enabled platform. A Feature is a Sandboxed Application generated against a specific Kernel.
A Sandboxed Application may be dynamically downloaded at runtime or integrated at build-time within the executable application.
The Multi-Sandbox process extends the overall process described in the overview of the platform process.
Once a Kernel has been generated, additional Sandboxed Application code
(Feature) can be built against the Kernel .
The binary application file produced (
application.fo) is compatible only
for the Kernel on which it was generated. Generating a new Kernel
requires that you generate the Features again on this Kernel.
Multi-Sandbox memory overhead of Core Engine runtime elements are described in Memory Considerations table.
Multi-Sandbox capability is an additional Core Engine module, disabled by default.
To enable the Multi-Sandbox capability of the MicroEJ Core Engine, in the platform configuration file, check Multi Applications.
<dependency org="ej.api" name="kf" rev="1.4.4"/>
This library provides a set of options. Refer to the chapter Standalone Application Options which lists all available options.
Feature installation is triggered by a call to the Kernel.install(InputStream) method. It consists of the following steps:
- loading Feature’s content from
- linking Feature’s code with the Kernel,
- storing Feature’s content into the target memory.
.fo file is composed of the following elements:
- Code: Application code (methods, types, …) as well as built-in objects (strings and immutables),
- RO Data: Application Resources that do not require content modification,
- RW Data: Reserved memory for Feature execution (Application static fields and Feature internal structures),
- Metadata: Temporary information required during the installation phase, such as code relocations.
LLKERNEL_impl.h Abstraction Layer interface provides Low Level APIs for allocating and transferring Feature content in different memory areas.
There are two kinds of installation:
- In-place installation: The Feature content is allocated in RAM.
- Custom installation: The Feature content is copied to any byte-addressable memory, including ROM.
Installation kinds are not exclusive. It is possible to link a Feature using In-place installation and another one using Custom installation. In all cases, a certain amount of RAM is required:
- Metadata is allocated in the Java heap,
- Code is first allocated in a memory area called the Kernel Working Buffer (see more details below).
This is the fastest way to go with Feature installation since it only requires connecting a
Feature content is installed in RAM. The required memory is allocated in the Kernel Working Buffer. This includes code, resources, static fields, and internal structures. When the Feature is uninstalled, allocated memory is reclaimed. When the Core Engine or the device restarts, the Kernel Working Buffer is reset; thus there is no persistent Feature.
The In-Place installation flow is described in the following sequence diagram:
The In-Place uninstallation flow is described in the following sequence diagram:
Custom Feature Installation allows to install a Feature in any byte-addressable memory, including ROM. The Code is temporarily allocated to the Kernel Working Buffer before being linked. Then it is transferred to the target location. RO Data (Application Resources) is directly transferred to the target location.
The Abstraction Layer implementation is responsible for providing the following elements:
- the address location where the Feature will be installed,
- the implementation to copy a chunk of bytes to the target location.
The custom installation flow is described in the following sequence diagram:
The custom uninstallation flow is described in the following sequence diagram:
If the Abstraction Layer implementation installs a Feature in a Read-Only memory, it will be available after the Core Engine or the device restarts.
InputStream Buffer Size¶
.fo InputStream is read in a temporary byte array allocated in the Java Heap.
The buffer size can be configured with the following option:
Relocation Process Yield¶
When a Feature file has a large amount of code, it may appear that the Core Engine blocks while applying relocations during the Feature installation. The number of relocations to apply in batch can be configured with the following option:
Once the Core Engine has processed the given number of relocations, the thread that called the Kernel.install(InputStream) method yields the execution to other threads. A small number will give more smooth execution for threads but a slowest installation execution. A large number will make the Core Engine block for applying relocations but a faster installation execution.
Determining the Amount of Required Memory¶
The amount of memory required for installing a
.fo file is determined by analyzing the sizes of the ELF sections.
Sections can be dumped using the standard binutils
readelf -WS application.fo There are 8 section headers, starting at offset 0x34: Section Headers: [Nr] Name Type Addr Off Size ES Flg Lk Inf Al [ 0] NULL 00000000 000000 000000 00 0 0 0 [ 1] .soar.rel LOPROC+0 00000000 000174 000bcc 00 6 0 4 [ 2] .strtab STRTAB 00000000 000d40 000063 00 0 0 1 [ 3] .symtab SYMTAB 00000000 000da4 000050 10 2 1 4 [ 4] .bss.soar.feature NOBITS 00000000 000df4 000050 00 A 0 0 4 [ 5] .rodata.microej.resources PROGBITS 00000000 000e00 079080 00 A 0 0 64 [ 6] .rodata PROGBITS 00000000 079e80 001974 00 A 0 0 16 [ 7] .shstrtab STRTAB 00000000 07b7f4 000059 00 0 0 1
The following table summarizes the sections and their content:
|Section||Description||Temporary Memory Location||Target Memory Location|
||RW Data||None||Features RAM area|
||RO Data||None||Features ROM area|
||Code||Kernel Working Buffer||Features ROM area|