Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions docs/Platform.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Ocre Runtime platform requirements

Ocre targets a POSIX-like operating system and makes heavy use of the POSIX API.

We specifically use `pthread(3)` for creating the runtime engine threads (which are used by the runtime engine).

Ocre Runtime also exposes a thread-safe API for managing the runtime engine and the lifecycle of the containers.
This functionality requires `pthread_mutex(3)` and `pthread_cond(3)`.

We explicitly do not make use of `pthread_kill(3)` because it is undefined and unreliable behavior.

This subset of the POSIX API is available in most modern RTOS.

## WAMR

Ocre Runtime by default uses WebAssembly Micro-Runtime (WAMR) for running WASM containers. The integration between WAMR and the underlying platform is done by WAMR and is out of scope of Ocre Runtime.

Check [WAMR porting guide](https://github.com/bytecodealliance/wasm-micro-runtime/blob/main/doc/port_wamr.md) for more information about WAMR platform requirements.

## Container loading

For loading the container into the memory, each platform can provide its own implementation.

The following functions must be available in the platform:

- `void *ocre_load_file(const char *path, size_t *size)`: should make the contents of the file specified in `path` available in a linear memory. This is usually implemented as `mmap(2)` or `open(2)` then `malloc(3)` and `read(2)`
- `int ocre_unload_file(void *buffer, size_t size)`: should release whatever was acquired by `ocre_load_file`. This is usually implemented as `munmap(2)` or `free(3)`

Check the files in `src/platform/posix/file_alloc_*.c` for reference implementations.

## User memory

Ocre Runtime allows the "application memory" (container memory) to be allocated differently depending on the platform.

The following functions must be available in the platform:

- `void *user_malloc(size_t size)`: should allocate memory of the specified size. This is usually implemented as `malloc(3)`
- `void user_free(void *p)`: should release the memory allocated by `user_malloc`. This is usually implemented as `free(3)`
- `void *user_realloc(void *p, size_t size)`: should reallocate the memory allocated by `user_malloc`. This is usually implemented as `realloc(3)`

Check the files in `src/platform/*/memory.c` for reference implementations.

## Logging system

Logging API is inspired by Zephyr's logging API. This requires the following macros to be defined and used by every module that uses logging:

- `LOG_MODULE_REGISTER(module, ...)`: should register the module with the logging system
- `LOG_MODULE_DECLARE(module, ...)`: should declare the module with the logging system

In Zephyr, these functions behave differently. Ocre just expects any one of these to be called exactly once on each module, defining the name of the module, that will be part of the loggin output.

Also, the following macros or functions should be defined:

- `LOG_ERR(fmt, ...)`: should log an error message
- `LOG_WRN(fmt, ...)`: should log a warning message
- `LOG_INF(fmt, ...)`: should log an informational message
- `LOG_DBG(fmt, ...)`: should log a debug message

These functions are expected to behave like `printf(3)`.

Check Zephyr's [Logging](https://docs.zephyrproject.org/latest/services/logging/index.html) documentation for more information.

## config.h

This file, in the platform is required to define the following macro:

- `CONFIG_OCRE_DEFAULT_WORKING_DIRECTORY`: the default working directory for OCRE. This is usually set to `/var/lib/ocre` on POSIX production systems; `src/ocre/var/lib/ocre` for testing; or `/lfs/ocre` in Zephyr.

Additional configuration options and platform overrides can be defined here as well.

This file usually just sets `CONFIG_OCRE_DEFAULT_WORKING_DIRECTORY` and imports some other file (i.e. `autoconf.h`) so that Ocre can be configured and integrated in another build system.

# Current Platform list:

Ocre Runtime currently supports the following platforms:

- [POSIX](PlatformPosix.md)
- [Zephyr](PlatformZephyr.md)

Please refer to the platform-specific documentation for more information about their implementation.
36 changes: 36 additions & 0 deletions docs/PlatformPosix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# POSIX Platform

In Linux, pthreads are enabled by compiling with `-pthread` and linking with `-lpthread`. This might not be required for other POSIX platforms. The required build flags are automatically selected by the cmake build system.

## WAMR

WAMR has built-in support for most POSIX operating systems, including Linux. The WAMR integration is out of scope of the Ocre Posix platform.

Check [WAMR porting guide](https://github.com/bytecodealliance/wasm-micro-runtime/blob/main/doc/port_wamr.md) for more information about WAMR platform requirements.

## container loading

For loading the container into the memory, we use `mmap(2)` by default. This is the recommended way as this can provide XIP functionality.

We also provide other alternative implementations in case the system does not support `mmap(2)`:

- Using POSIX syscalls
- Using file streams

Check the files in `src/platform/posix/file_alloc_*.c` for reference implementations.

## user memory

Since in POSIX or Linux there is no standard tiered memory API, these are implemented as `malloc(3)`, `realloc(3)` and `free(3)`

## logging

`LOG_MODULE_REGISTER(module, ...)` and `LOG_MODULE_DECLARE(module, ...)` will just define some `static const` variable with the module name; while the `LOG_*(fmt, ...)` macros will use `fprintf(3)` to log the message to `stderr`.

## config.h

This file, in the platform is required to define the following macro:

- `CONFIG_OCRE_DEFAULT_WORKING_DIRECTORY` is set to `src/ocre/var/lib/ocre`, since we currently do not build a production build.

All Ocre specific optionals are enabled. Since in Linux the memory impact of these features are negligible, we enable them by default.
31 changes: 31 additions & 0 deletions docs/PlatformZephyr.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Zephyr Platform

In Zephyr, the POSIX API is selected by the `CONFIG_POSIX_API` configuration option.

## WAMR

WAMR has built-in support for Zephyr. The WAMR integration is out of scope of the Ocre Zephyr platform.

Check [WAMR porting guide](https://github.com/bytecodealliance/wasm-micro-runtime/blob/main/doc/port_wamr.md) for more information about WAMR platform requirements.

## container loading

For loading the container into the memory, we use `open(2)`, `malloc(3)` and `read(2)`. Zephyr does not support `mmap(2)` and file streams are currently broken in Zephyr 4.3.0.

Check the files in `src/platform/posix/file_alloc_read.c` for implementation.

## user memory

If `CONFIG_SHARED_MULTI_HEAP` is disabled, there is no tiered memory API, these are implemented as `malloc(3)`, `realloc(3)` and `free(3)`.

If `CONFIG_SHARED_MULTI_HEAP` is enabled, then these are implemented as `shared_multi_heap_aligned_alloc()` with `SMH_REG_ATTR_EXTERNAL` and `shared_multi_heap_free()`.

Check Zephyr's [Shared Multi Heap](https://docs.zephyrproject.org/latest/kernel/memory_management/shared_multi_heap.html) documentation or [Adding a Zephyr board](AddZephyrBoard.md) documentation for more details about shared multi heap.

## logging

`log.h` just includes Zephyr's logging system, as it is transparent.

## config.h

`config.h` does not include anything, as Zephyr's `autoconf.h` is automatically included (by command line) to every `.c` file in Zephyr build.