Tiny Embedded Module System Spec
Feb 4 2022
The Idea: Create a memory efficient alternative to ELF thatis less powerful, but good enough for a plugin/module system.
*This specification is a draft, completed version will be published one day.*
The Solution: TEMS (Tiny Embedded Module System)
Modules are loaded via file on SD card/storage device.
Module file is compiled machine code, with the first bytes being
the
_start
function._start
recieves an address to this function:struct ModuleInfo {
// Version of the module API - default is 0
uint32_t version;
// Length of symbols
uint32_t length;
// Variable length struct
struct Symbol {
char *name;
uintptr_t addr;
}sym[];
};
_start
parses this structure. It should onlyload in addresses for symbols that have been compiled
into the module. Excess symbols are ignored. Error is reported
when symbols aren't found.
_start
should have the following header:int _start(struct ModuleInfo *info, int action);
If
action
is 0x0
:Load symbols, run a "startup" code if needed.
Return
0x0
on success. Return 0x1
on symbol error.Return
0x3
on startup error.If
action
is 0x1
:Run the main module code. Returns
0x0
on success.Returns
0x1
on error.How this is done isn't crucial, here are some of the top of my head:
- The module file has a local copy of
struct ModuleInfo
.- It includes the required functions, and
addr
stores an address toan assembly variable.
-
version
is checked between both structs, to ensure compatibility.Basic trampoline:
Here,
ModuleInfo.sym[x].addr
would refer to the address of sprintf_addr
..global sprintf
.global sprintf_addr
sprintf:
adr r9, sprintf_addr
ldr r9, [r9]
bx r9
sprintf_addr: .long 0
Here is a generic lazy way:
if (!strcmp(info.funcs[0].type, "sprintf") {
sprintf_addr = info.funcs[0].addr;
} ...
Generating the structures and code could be done in the following ways:
- Write a linker script
- Write a python script
- Write a C "script"
(Writing a Python script is the most readable choice.)
With this spec, writing cross platform modules could be
possible, assuming the device provides POSIX functions.