Multi-Sandbox

Principle

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.

Functional Description

The Multi-Sandbox process extends the overall process described in the overview of the platform process.

Multi-Sandbox Process

Multi-Sandbox 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.

For more details on the build flow, please refer to Multi-Sandbox Kernel link and Sandboxed Application link sections.

Memory Considerations

Multi-Sandbox memory overhead of Core Engine runtime elements are described in Memory Considerations table.

Dependencies

Installation

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.

Use

The KF API Module must be added to the module.ivy of the MicroEJ Application project to use [KF] library.

<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

Introduction

Feature installation is triggered by a call to the Kernel.install(InputStream) method. It consists of the following steps:

  • loading Feature’s content from .fo file,
  • linking Feature’s code with the Kernel,
  • storing Feature’s content into the target memory.

A Feature .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.
Feature ``.fo`` File Content

Feature .fo File Content

The 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).

In-Place Installation

This is the fastest way to go with Feature installation since it only requires connecting a malloc/free implementation.

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.

In-Place Feature Installation Overview

In-Place Feature Installation Overview

The In-Place installation flow is described in the following sequence diagram:

In-Place Feature Installation Flow

In-Place Feature Installation Flow

The In-Place uninstallation flow is described in the following sequence diagram:

In-Place Feature Uninstallation Flow

In-Place Feature Uninstallation Flow

Custom Installation

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.

Custom Feature Installation Overview

Custom Feature Installation Steps

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:

Custom Feature Installation Overview

Custom Feature Installation Flow

The custom uninstallation flow is described in the following sequence diagram:

Custom Feature Uninstallation Flow

Custom Feature Uninstallation Flow

Feature Persistency

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.

Feature Installation Boot Flow

Feature Installation Boot Flow

Advanced Options

InputStream Buffer Size

Feature .fo InputStream is read in a temporary byte array allocated in the Java Heap. The buffer size can be configured with the following option:

Option Name: com.microej.runtime.kf.link.transferbuffer.size

Default Value: 512 (bytes)

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:

Option Name: com.microej.runtime.kf.link.chunk.relocations.count

Default Value: 128

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 tool:

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
.soar.rel Metadata Java Heap None
.strtab Metadata Java Heap None
.symbtab Metadata Java Heap None
.bss.soar.feature RW Data None Features RAM area
.rodata.microej.resources RO Data None Features ROM area
.rodata Code Kernel Working Buffer Features ROM area
.shstrtab Metadata Java Heap None