Skip to content
Getting Started

Start Building with
EmbeddedOS

No hardware required to get started. Every command on the simulator path was run as written before it was published.

Boot the real EoS kernel on QEMU with ebuild sim — no hardware needed

The EmbeddedOS Ecosystem

8 tools that work together — understand what each one does before you start

ebuild
Build Tool

Creates, builds and simulates EoS projects, analyzes KiCad schematics, and drives flash tools.

EoSim
Simulator

Registry of 150 platform descriptors and simulation engines. Cortex-M apps run on QEMU through ebuild sim.

EoS Kernel
RTOS Kernel

The real-time OS kernel. Provides HAL, scheduler, IPC, drivers, and POSIX subset.

eBoot
Bootloader

Secure bootloader with verified boot, OTA A/B updates, and hardware root of trust.

eFlow
Visual Programming

Drag-and-drop block editor that generates production C code. No assembly needed for common patterns.

EAI / ENI
Edge AI

On-device TFLite/ONNX inference and neural interface adapter for BCI devices.

eApps
App Ecosystem

60+ apps including eOffice Suite, eBrowser, eDB, and eBot AI assistant.

EoStudio
IDE

Universal IDE with AI tutor, 3D modeler, game editor, and UI designer.

Choose Your Path

Pick the option that matches where you are right now

Run EoS on a Simulated Board (QEMU)

~10 minutes

ebuild creates an EoS project and `ebuild sim` builds it with the EoS kernel for QEMU's Arm Cortex-M3 machine, then boots it and shows the program's output. Every command and output on this page was run on Ubuntu 20.04 (WSL2) with Python 3.12, arm-none-eabi-gcc 9.2.1 and QEMU 4.2.1.

Prerequisites: Linux or WSL2 (verified: Ubuntu 20.04). Python 3.10+, Git, the Arm GNU toolchain and QEMU. Ubuntu 20.04's own python3 is 3.8, which is too old, so step 2 fetches a current Python without root. macOS should work with the same tools but has not been verified for this guide.
1

Install the Toolchain and QEMU

sudo apt install git python3-venv gcc-arm-none-eabi qemu-system-arm
2

Install ebuild and EoSim

ebuild is the EmbeddedOS build tool. EoSim provides the platform registry that `ebuild platforms list` reads. Neither is on PyPI yet, so install them from GitHub. uv supplies Python 3.12 for the virtual environment, with no root needed, so this works on Ubuntu 20.04 too.

curl -LsSf https://astral.sh/uv/install.sh | sh && source $HOME/.local/bin/env
uv venv -p 3.12 .venv && . .venv/bin/activate
uv pip install "embeddedos-ebuild @ git+https://github.com/embeddedos-org/ebuild" \
               "embeddedos-eosim @ git+https://github.com/embeddedos-org/EoSim"

ebuild --version
# ebuild, version 3.0.1
Tip: Already on Python 3.10+ (Ubuntu 22.04 or later)? python3 -m venv .venv works in place of uv. With Ubuntu 20.04's python3 (3.8), the install fails with: requires a different Python: 3.8.10 not in '>=3.9'. Do not run `pip install ebuild`: that name on PyPI belongs to an unrelated project.
3

Fetch the EoS Sources

ebuild builds your application against the EoS kernel and bootloader sources. It keeps them in ~/.ebuild/repos.

ebuild setup
# [ok]   eos: ~/.ebuild/repos/eos
# [ok]   eboot: ~/.ebuild/repos/eboot
# [ok] Setup complete. Repos are ready.

ebuild doctor     # checks compilers, cmake, ninja and the repos
Tip: Ran ebuild setup on this machine before? It never pulls an existing clone, so run `ebuild repos update` to bring eos and eboot up to date. An older eos checkout makes `ebuild sim` stop with: sim.yaml not found.
4

Create Your First Project

ebuild init my-blink --template rtos --target stm32f4
cd my-blink

# my-blink/
#   src/main.c          <- your application
#   tests/test_main.c   <- unit test target
#   build.yaml          <- ebuild build configuration
#   eos.yaml            <- EoS project configuration (board, kind)
#   README.md
Tip: `ebuild init` is the guide's name for `ebuild new`. The rtos template maps to `ebuild new --template rtos-app`.
5

The Generated main.c

The rtos template is a producer/consumer program. It uses an EoS queue, a mutex and two tasks:

static void producer_task(void *arg) {
    uint32_t seq = 0;
    while (1) {
        message_t msg = { .id = seq++, .value = (int32_t)(seq * 10) };
        eos_queue_send(g_queue, &msg, EOS_WAIT_FOREVER);
        eos_task_delay_ms(500);
    }
}

static void consumer_task(void *arg) {
    message_t msg;
    while (1) {
        if (eos_queue_receive(g_queue, &msg, EOS_WAIT_FOREVER) == EOS_KERN_OK)
            printf("[consumer] id=%lu value=%ld\n", msg.id, msg.value);
    }
}
6

Simulate It

ebuild sim compiles your sources and the EoS kernel for QEMU's lm3s6965evb (Cortex-M3), boots the image and prints its output. The kernel's SysTick and PendSV scheduling are real. The board's peripherals are not modelled.

ebuild sim --timeout 4

# Building stm32f4 application for qemu_cortex_m3 (lm3s6965evb)...
# [ok] Image: .../my-blink/_build/sim/firmware.elf
# Running on lm3s6965evb (timeout 4s)...
# [my-blink] Starting kernel...
# [consumer] id=0 value=10
# [consumer] id=1 value=20
# ...
# [consumer] id=8 value=90
# [ok] Simulation ran: 10 line(s) of output, stopped after 4s
Tip: For CI, assert on output: ebuild sim --expect 'id=3 value=40'. It exits non-zero if the text never appears, if the guest exits with an error, or if the image prints nothing.
7

Which Boards Can Be Simulated

ebuild sim runs Arm Cortex-M targets: stm32f4, stm32h7, stm32l4, nrf52, nrf52840, rp2040 and raspi-pico, all on the same QEMU Cortex-M3 machine. Other boards, such as esp32, are refused with a message instead of being faked.

ebuild platforms list
# 153 EoSim platforms (* = runnable with `ebuild sim`):
#    adi-aducm4050            arm      Analog Devices
#    ...

ebuild sim --platform esp32
# Error: no simulation target for board 'esp32' yet. Boards ebuild sim can run: ...
8

Debug with GDB

Run the image under QEMU's GDB stub yourself. ebuild does not wrap this step yet.

qemu-system-arm -M lm3s6965evb -nographic -semihosting \
  -kernel _build/sim/firmware.elf -gdb unix:/tmp/eos.sock,server,nowait -S &

gdb-multiarch _build/sim/firmware.elf \
  -ex "target remote /tmp/eos.sock" -ex "break consumer_task" -ex continue
# Breakpoint 1, consumer_task (arg=0x0) at src/main.c:39