- HARD_REALTIME_EVALUATION.md: full HRT audit - MICROKERNEL_*.md: complete architecture targets and implementation plan - PIKEOS_3LAYER_REPLICATION_PLAN.md: 3-layer replication strategy - PIKEOS_POSIX_AUDIT.md: POSIX compliance audit - RTOS_AUDIT.md: RTOS comparison - XTENSA_AUDIT.md: Xtensa ISA audit - BIBLIOGRAPHY_SAFETY_CRITICAL_HYPERVISOR.md: references
567 lines
22 KiB
Markdown
567 lines
22 KiB
Markdown
# UniversalisOS Microkernel — Implementation Plan
|
|
|
|
**Date:** 2026-07-14
|
|
**Status:** ACTIVE — Implementation Plan
|
|
**Scope:** Universal microkernel for ALL architectures, from AVR to Xeon
|
|
|
|
---
|
|
|
|
## Executive Summary
|
|
|
|
UniversalisOS microkernel is a **single codebase** that compiles for every architecture from 8-bit AVR to 64-bit x86_64 with VT-x. It uses **compile-time tier selection** to scale from a 2KB cooperative task switcher (Cortex-M0, no MPU) to a full type-1 hypervisor with hardware virtualization (x86_64 VT-x).
|
|
|
|
**Core design**: uos_* naming throughout. Agnostic API shell. Personality wrappers for FreeRTOS, ThreadX, Zephyr, POSIX, CMSIS-RTOS v2.
|
|
|
|
**Primary references**: f9-kernel (MPU isolation), ThreadX (port breadth), ChibiOS (port contract), NuttX (no-MMU strategy), RTEMS (context switch HAL).
|
|
|
|
---
|
|
|
|
## Architecture: The Tier System
|
|
|
|
```
|
|
Tier 0: Bare Metal (no MPU, no MMU)
|
|
Targets: Cortex-M0/M0+, AVR, basic RISC-V (RV32I), 8051
|
|
RAM: 4-16KB
|
|
Kernel: ~2KB
|
|
Features: Cooperative scheduling, static alloc, no isolation
|
|
Context switch: Direct register save/restore (PendSV/manual)
|
|
|
|
Tier 1: MPU-Based (Memory Protection Unit)
|
|
Targets: Cortex-M3/M4/M7/M23/M33/M55, Cortex-R4/R5/R7, ESP32
|
|
RAM: 64-512KB
|
|
Kernel: ~8KB
|
|
Features: Preemptive, MPU isolation, stack canary, priority scheduling
|
|
Context switch: PendSV (Cortex-M) / ECALL (RISC-V) / Syscall (Xtensa)
|
|
|
|
Tier 2: MMU-Based (Full Virtual Memory)
|
|
Targets: Cortex-A5/A7/A8/A9/A53/A72/A76, RISC-V Sv39+, x86 protected
|
|
RAM: 1MB-4GB
|
|
Kernel: ~32KB
|
|
Features: Full type-1 hypervisor, partition isolation, guest OS boot
|
|
Context switch: SVC/HVC (ARM) / ECALL (RISC-V) / INT (x86)
|
|
|
|
Tier 3: Hardware Virtualization
|
|
Targets: Cortex-A with VE, RISC-V H-extension, x86 VT-x/AMD-V
|
|
RAM: 4GB+
|
|
Kernel: ~64KB
|
|
Features: Hardware-assisted, nested page tables, device passthrough
|
|
Context switch: VM entry/exit (hardware-managed)
|
|
```
|
|
|
|
### Compile-Time Selection
|
|
|
|
```c
|
|
// kernel/include/uos_config.h
|
|
#if defined(__ARM_ARCH_6M__) // Cortex-M0/M0+
|
|
#define UOS_TIER 0
|
|
#define UOS_HAS_MPU 0
|
|
#define UOS_HAS_MMU 0
|
|
#define UOS_MAX_TASKS 8
|
|
#define UOS_TICK_RATE_HZ 100
|
|
#elif defined(__ARM_ARCH_7M__) // Cortex-M3/M4/M7
|
|
#define UOS_TIER 1
|
|
#define UOS_HAS_MPU 1
|
|
#define UOS_HAS_MMU 0
|
|
#define UOS_MAX_TASKS 32
|
|
#define UOS_MPU_REGIONS 8
|
|
#elif defined(__ARM_ARCH_7A__) // Cortex-A
|
|
#define UOS_TIER 2
|
|
#define UOS_HAS_MPU 0
|
|
#define UOS_HAS_MMU 1
|
|
#define UOS_MAX_TASKS 128
|
|
#elif defined(__riscv)
|
|
#if __riscv_xlen == 32
|
|
#define UOS_TIER 1 // PMP-based
|
|
#define UOS_HAS_PMP 1
|
|
#else
|
|
#define UOS_TIER 2 // Sv39
|
|
#define UOS_HAS_MMU 1
|
|
#endif
|
|
#elif defined(__x86_64__)
|
|
#define UOS_TIER 3
|
|
#define UOS_HAS_VT_X 1
|
|
#define UOS_HAS_MMU 1
|
|
#endif
|
|
```
|
|
|
|
---
|
|
|
|
## Universal Kernel API (`uos_*`)
|
|
|
|
Every function, every type, every constant uses the `uos_` prefix. This is the identity.
|
|
|
|
```c
|
|
// kernel/include/uos_api.h — THE universal API
|
|
|
|
/* === Types === */
|
|
typedef uint32_t uos_tick_t;
|
|
typedef uint8_t uos_prio_t;
|
|
typedef int32_t uos_status_t;
|
|
typedef uint32_t uos_flags_t;
|
|
typedef uint32_t uos_size_t;
|
|
typedef uint32_t uos_count_t;
|
|
|
|
/* Opaque kernel objects (Tier 1+: heap-allocated; Tier 0: static) */
|
|
typedef struct uos_task uos_task_t;
|
|
typedef struct uos_sem uos_sem_t;
|
|
typedef struct uos_mutex uos_mutex_t;
|
|
typedef struct uos_queue uos_queue_t;
|
|
typedef struct uos_event uos_event_t;
|
|
typedef struct uos_timer uos_timer_t;
|
|
|
|
/* Status codes */
|
|
#define UOS_OK 0
|
|
#define UOS_ERR_TIMEOUT -1
|
|
#define UOS_ERR_NOMEM -2
|
|
#define UOS_ERR_PARAM -3
|
|
#define UOS_ERR_STATE -4
|
|
#define UOS_ERR_WOULDBLOCK -5
|
|
#define UOS_ERR_ISR -6
|
|
|
|
/* Special timeout values */
|
|
#define UOS_WAIT_FOREVER 0xFFFFFFFF
|
|
#define UOS_NO_WAIT 0
|
|
|
|
/* === Task Management === */
|
|
uos_task_t* uos_task_create(const char* name, uos_prio_t prio,
|
|
void (*entry)(void*), void* arg,
|
|
void* stack, uos_size_t stack_size);
|
|
uos_status_t uos_task_delete(uos_task_t* task);
|
|
uos_status_t uos_task_yield(void);
|
|
uos_status_t uos_task_suspend(uos_task_t* task);
|
|
uos_status_t uos_task_resume(uos_task_t* task);
|
|
uos_task_t* uos_task_self(void);
|
|
uos_prio_t uos_task_get_priority(uos_task_t* task);
|
|
uos_status_t uos_task_set_priority(uos_task_t* task, uos_prio_t prio);
|
|
|
|
/* === Scheduling === */
|
|
uos_status_t uos_sched_start(void); /* never returns */
|
|
uos_status_t uos_sched_stop(void);
|
|
|
|
/* === Semaphores === */
|
|
uos_status_t uos_sem_init(uos_sem_t* sem, uos_count_t count);
|
|
uos_status_t uos_sem_destroy(uos_sem_t* sem);
|
|
uos_status_t uos_sem_wait(uos_sem_t* sem, uos_tick_t timeout);
|
|
uos_status_t uos_sem_post(uos_sem_t* sem);
|
|
uos_status_t uos_sem_post_from_isr(uos_sem_t* sem);
|
|
|
|
/* === Mutexes === */
|
|
uos_status_t uos_mutex_init(uos_mutex_t* mutex, bool recursive);
|
|
uos_status_t uos_mutex_destroy(uos_mutex_t* mutex);
|
|
uos_status_t uos_mutex_lock(uos_mutex_t* mutex, uos_tick_t timeout);
|
|
uos_status_t uos_mutex_unlock(uos_mutex_t* mutex);
|
|
|
|
/* === Message Queues === */
|
|
uos_queue_t* uos_queue_create(uos_size_t msg_size, uos_count_t max_msgs);
|
|
uos_status_t uos_queue_delete(uos_queue_t* queue);
|
|
uos_status_t uos_queue_send(uos_queue_t* queue, const void* msg, uos_tick_t timeout);
|
|
uos_status_t uos_queue_receive(uos_queue_t* queue, void* msg, uos_tick_t timeout);
|
|
uos_status_t uos_queue_send_from_isr(uos_queue_t* queue, const void* msg);
|
|
|
|
/* === Event Flags === */
|
|
uos_status_t uos_event_init(uos_event_t* event);
|
|
uos_status_t uos_event_set(uos_event_t* event, uos_flags_t flags);
|
|
uos_status_t uos_event_clear(uos_event_t* event, uos_flags_t flags);
|
|
uos_status_t uos_event_wait(uos_event_t* event, uos_flags_t flags,
|
|
uos_flags_t* actual, uos_tick_t timeout);
|
|
|
|
/* === Timers === */
|
|
uos_timer_t* uos_timer_create(const char* name, uos_tick_t period,
|
|
void (*callback)(void*), void* arg, bool periodic);
|
|
uos_status_t uos_timer_start(uos_timer_t* timer);
|
|
uos_status_t uos_timer_stop(uos_timer_t* timer);
|
|
uos_status_t uos_timer_delete(uos_timer_t* timer);
|
|
|
|
/* === Memory (Tier 1+ only; Tier 0 uses static alloc) === */
|
|
void* uos_mem_alloc(uos_size_t size);
|
|
void* uos_mem_aligned_alloc(uos_size_t align, uos_size_t size);
|
|
void uos_mem_free(void* ptr);
|
|
|
|
/* === Time === */
|
|
uos_tick_t uos_tick_get(void);
|
|
uos_status_t uos_tick_delay(uos_tick_t ticks);
|
|
uos_status_t uos_tick_delay_until(uos_tick_t* prev, uos_tick_t increment);
|
|
uos_tick_t uos_ms_to_ticks(uint32_t ms);
|
|
uos_tick_t uos_us_to_ticks(uint32_t us);
|
|
|
|
/* === Interrupt Management (Tier 1+ === */
|
|
typedef void (*uos_isr_t)(void* arg);
|
|
uos_status_t uos_irq_attach(uint32_t irq, uos_isr_t handler, void* arg);
|
|
uos_status_t uos_irq_enable(uint32_t irq);
|
|
uos_status_t uos_irq_disable(uint32_t irq);
|
|
```
|
|
|
|
---
|
|
|
|
## Port Layer (4 files per architecture)
|
|
|
|
Inspired by ThreadX (70+ ports) + ChibiOS (`chcore.h` contract).
|
|
|
|
### Port Directory Structure
|
|
```
|
|
kernel/ports/
|
|
├── armv6m/ ← Cortex-M0/M0+ (Tier 0)
|
|
│ ├── uos_port.h ← Port defines, critical section macros
|
|
│ ├── uos_port_init.c ← NVIC setup, SysTick config
|
|
│ ├── uos_port_context.S ← PendSV handler: save/restore R4-R11
|
|
│ └── uos_port_dispatch.S ← First task launch: load SP, restore context
|
|
│
|
|
├── armv7m/ ← Cortex-M3/M4/M7 (Tier 1)
|
|
│ ├── uos_port.h ← MPU register access, CLZ instruction
|
|
│ ├── uos_port_init.c ← NVIC priority config, MPU setup
|
|
│ ├── uos_port_context.S ← PendSV with lazy FPU stacking
|
|
│ └── uos_port_dispatch.S ← First task with MPU region setup
|
|
│
|
|
├── armv8m/ ← Cortex-M23/M33/M55 (Tier 1, TrustZone)
|
|
│ ├── uos_port.h ← TrustZone SAU/IDAU defines
|
|
│ ├── uos_port_init.c ← Secure/Non-secure partition setup
|
|
│ ├── uos_port_context.S ← Secure context save (8 additional regs)
|
|
│ └── uos_port_dispatch.S ← Non-secure task launch via SG instruction
|
|
│
|
|
├── armv7a/ ← Cortex-A (Tier 2)
|
|
│ ├── uos_port.h ← CP15 register access, cache ops
|
|
│ ├── uos_port_init.c ← MMU setup, GIC init, page table config
|
|
│ ├── uos_port_context.S ← SVC/IRQ handlers: save full register set
|
|
│ └── uos_port_dispatch.S ← First task with MMU context switch
|
|
│
|
|
├── armv8a/ ← Cortex-A53/A72 (Tier 2/3)
|
|
│ ├── uos_port.h ← EL2/EL1 system register access
|
|
│ ├── uos_port_init.c ← VBAR_EL2, HCR_EL2, VTTBR setup
|
|
│ ├── uos_port_context.S ← EL2 exception vectors, context save
|
|
│ └── uos_port_dispatch.S ← ERET into first guest task
|
|
│
|
|
├── riscv32/ ← RV32IMC (Tier 1, PMP)
|
|
│ ├── uos_port.h ← CSR access macros, PMP defines
|
|
│ ├── uos_port_init.c ← PMP configuration, CLINT timer setup
|
|
│ ├── uos_port_context.S ← ECALL/trap handler: save caller-saved regs
|
|
│ └── uos_port_dispatch.S ← MRET into first task
|
|
│
|
|
├── riscv64/ ← RV64GC (Tier 2, Sv39)
|
|
│ ├── uos_port.h ← Sv39 page table defines
|
|
│ ├── uos_port_init.c ← SATP setup, PLIC init
|
|
│ ├── uos_port_context.S ← Trap handler with full context save
|
|
│ └── uos_port_dispatch.S ← SRET into first task
|
|
│
|
|
├── x86/ ← 32-bit protected mode (Tier 2)
|
|
│ ├── uos_port.h ← GDT/TSS/IDT defines
|
|
│ ├── uos_port_init.c ← GDT setup, IDT init, PIT timer
|
|
│ ├── uos_port_context.S ← INT handler: pusha/popa context save
|
|
│ └── uos_port_dispatch.S ← IRET to first task
|
|
│
|
|
├── x86_64/ ← 64-bit long mode (Tier 3)
|
|
│ ├── uos_port.h ← VMX/EPT defines, MSR access
|
|
│ ├── uos_port_init.c ← GDT/IDT, VMX init, HPET timer
|
|
│ ├── uos_port_context.S ← SYSCALL handler: swapgs, full save
|
|
│ └── uos_port_dispatch.S ← SYSRET/IRETQ to first task
|
|
│
|
|
├── xtensa/ ← ESP32/ESP32-S3 (Tier 1)
|
|
│ ├── uos_port.h ← Windowed register defines, EXCSAVE
|
|
│ ├── uos_port_init.c ← Interrupt matrix, timer config
|
|
│ ├── uos_port_context.S ← Level-1 interrupt handler context save
|
|
│ └── uos_port_dispatch.S ← First task via RFI
|
|
│
|
|
└── mips32/ ← PIC32 (Tier 1)
|
|
├── uos_port.h ← CP0 register access
|
|
├── uos_port_init.c ← EBASE setup, timer config
|
|
├── uos_port_context.S ← General exception handler
|
|
└── uos_port_dispatch.S ← ERET to first task
|
|
```
|
|
|
|
### Port Contract (what each port MUST export)
|
|
|
|
```c
|
|
// kernel/ports/<arch>/uos_port.h — REQUIRED exports
|
|
|
|
/* Critical section */
|
|
uos_status_t uos_port_critical_enter(void); /* return previous state */
|
|
void uos_port_critical_exit(uos_status_t prev);
|
|
|
|
/* Context switch trigger */
|
|
void uos_port_yield(void); /* PendSV/ECALL/SVC/syscall */
|
|
|
|
/* First task dispatch (never returns) */
|
|
void uos_port_dispatch_first(void) __attribute__((noreturn));
|
|
|
|
/* Tick timer */
|
|
void uos_port_tick_init(uint32_t freq_hz);
|
|
uint32_t uos_port_tick_get(void);
|
|
|
|
/* MPU/MMU (Tier 1+) */
|
|
#if UOS_HAS_MPU
|
|
void uos_port_mpu_set_region(uint32_t idx, uint32_t base, uint32_t size, uint32_t attrs);
|
|
void uos_port_mpu_enable(void);
|
|
void uos_port_mpu_disable(void);
|
|
#endif
|
|
|
|
#if UOS_HAS_MMU
|
|
void uos_port_mmu_set_table(uint32_t table_phys);
|
|
void uos_port_mmu_invalidate_tlb(void);
|
|
#endif
|
|
|
|
/* Architecture-specific constants */
|
|
#define UOS_PORT_STACK_ALIGN 8 /* or 4 for Cortex-M0, 16 for AArch64 */
|
|
#define UOS_PORT_MIN_STACK_SIZE 256 /* or 128 for Tier 0 */
|
|
```
|
|
|
|
---
|
|
|
|
## Personality Shell Architecture
|
|
|
|
```
|
|
kernel/personality/
|
|
├── freertos/ ← FreeRTOS API → uos_* wrapper
|
|
│ ├── FreeRTOS.h ← Redirects to uos_* internals
|
|
│ ├── task.h ← xTaskCreate → uos_task_create
|
|
│ ├── semphr.h ← xSemaphoreCreateCounting → uos_sem_init
|
|
│ ├── queue.h ← xQueueCreate → uos_queue_create
|
|
│ ├── timers.h ← xTimerCreate → uos_timer_create
|
|
│ └── portable/ ← FreeRTOS port layer (maps to uos_port_*)
|
|
│
|
|
├── threadx/ ← ThreadX API → uos_* wrapper
|
|
│ ├── tx_api.h ← tx_thread_create → uos_task_create
|
|
│ ├── tx_thread.h ← ThreadX thread types → uos_task_t
|
|
│ └── tx_port.h ← Maps ThreadX port macros to uos_port_*
|
|
│
|
|
├── zephyr/ ← Zephyr API → uos_* wrapper
|
|
│ ├── kernel.h ← k_thread_create → uos_task_create
|
|
│ └── zephyr/ ← Zephyr kernel object mapping
|
|
│
|
|
├── posix/ ← POSIX PSE51 → uos_* wrapper
|
|
│ ├── pthread.h ← pthread_create → uos_task_create
|
|
│ ├── semaphore.h ← sem_init → uos_sem_init
|
|
│ ├── mqueue.h ← mq_open → uos_queue_create
|
|
│ └── signal.h ← signal handling (Tier 2+)
|
|
│
|
|
├── cmsis_rtos2/ ← CMSIS-RTOS v2 → uos_* wrapper
|
|
│ ├── cmsis_os2.h ← osThreadNew → uos_task_create
|
|
│ └── cmsis_os.h ← osThreadCreate (v1 compat)
|
|
│
|
|
└── arduino/ ← Arduino API → uos_* wrapper
|
|
└── Arduino.h ← setup()/loop() → uos_task
|
|
```
|
|
|
|
### How a Personality Shell Works
|
|
|
|
```c
|
|
// Example: FreeRTOS personality
|
|
// kernel/personality/freertos/task.h
|
|
|
|
#include "uos_api.h"
|
|
|
|
#define xTaskCreate(entry, name, stack, arg, prio, handle) \
|
|
uos_task_create(name, (uos_prio_t)(prio), (void(*)(void*))(entry), \
|
|
(void*)(arg), NULL, (uos_size_t)(stack))
|
|
|
|
#define vTaskDelete(task) uos_task_delete((uos_task_t*)(task))
|
|
#define vTaskDelay(ticks) uos_tick_delay((uos_tick_t)(ticks))
|
|
#define xTaskGetCurrentTaskHandle() ((TaskHandle_t)uos_task_self())
|
|
```
|
|
|
|
---
|
|
|
|
## Kernel Object System (inspired by RT-Thread)
|
|
|
|
```c
|
|
// kernel/include/uos_object.h — Base kernel object
|
|
|
|
typedef enum {
|
|
UOS_OBJ_TASK = 0x01,
|
|
UOS_OBJ_SEM = 0x02,
|
|
UOS_OBJ_MUTEX = 0x03,
|
|
UOS_OBJ_QUEUE = 0x04,
|
|
UOS_OBJ_EVENT = 0x05,
|
|
UOS_OBJ_TIMER = 0x06,
|
|
} uos_obj_type_t;
|
|
|
|
typedef struct uos_object {
|
|
uos_obj_type_t type;
|
|
const char* name;
|
|
uint8_t flags; /* static/dynamic, allocated/free */
|
|
#if UOS_TIER >= 1
|
|
struct uos_object* next; /* linked list for object registry */
|
|
#endif
|
|
} uos_object_t;
|
|
|
|
/* All kernel objects embed uos_object_t as first member */
|
|
struct uos_task {
|
|
uos_object_t obj; /* must be first */
|
|
uos_prio_t priority;
|
|
uint8_t state;
|
|
void* stack_ptr;
|
|
uos_size_t stack_size;
|
|
/* ... arch-specific context at end ... */
|
|
};
|
|
```
|
|
|
|
---
|
|
|
|
## Context Switch: Cortex-M Example (Tier 0/1)
|
|
|
|
```asm
|
|
@ kernel/ports/armv7m/uos_port_context.S
|
|
@ PendSV handler — the heart of Cortex-M context switching
|
|
|
|
.global PendSV_Handler
|
|
.type PendSV_Handler, %function
|
|
PendSV_Handler:
|
|
@ Save context of current task
|
|
mrs r0, psp @ Get process stack pointer
|
|
tst lr, #0x10 @ Check if FPU context needs saving
|
|
it eq
|
|
vstmdbeq r0!, {s16-s31} @ Save FPU regs if used
|
|
stmdb r0!, {r4-r11, lr} @ Save core regs + EXC_RETURN
|
|
|
|
@ Load uos_task_current pointer
|
|
ldr r1, =uos_task_current
|
|
ldr r2, [r1]
|
|
str r0, [r2] @ Save SP to current task's TCB
|
|
|
|
@ Load next task
|
|
ldr r2, =uos_task_next
|
|
ldr r2, [r2]
|
|
str r2, [r1] @ Update current = next
|
|
ldr r0, [r2] @ Load next task's SP
|
|
|
|
@ Restore context of next task
|
|
ldmia r0!, {r4-r11, lr} @ Restore core regs + EXC_RETURN
|
|
tst lr, #0x10
|
|
it eq
|
|
vldmiaeq r0!, {s16-s31} @ Restore FPU regs if needed
|
|
msr psp, r0 @ Set process stack pointer
|
|
bx lr @ Return to next task (hardware restores R0-R3, PC, LR, xPSR)
|
|
```
|
|
|
|
---
|
|
|
|
## Implementation Phases
|
|
|
|
### Phase 1: Core Microkernel (Tier 0 — Cortex-M0) — Weeks 1-4
|
|
- `uos_task_t` with static allocation (8 tasks max)
|
|
- Cooperative round-robin scheduler
|
|
- PendSV context switch (Cortex-M0: save R4-R11, no FPU)
|
|
- `uos_tick_delay()` via SysTick
|
|
- `uos_sem_init/wait/post` (counting semaphore)
|
|
- `uos_sched_start()` — launch first task
|
|
- **Test**: STM32F0 (real hardware) + QEMU cortex-m0
|
|
|
|
### Phase 2: Preemptive + MPU (Tier 1 — Cortex-M4) — Weeks 5-8
|
|
- Preemptive priority scheduler (32 levels, bitmap)
|
|
- MPU region management (8 regions per task)
|
|
- `uos_mutex_init/lock/unlock` with priority inheritance
|
|
- `uos_queue_create/send/receive` (message passing)
|
|
- `uos_event_init/set/wait` (event flags)
|
|
- `uos_timer_create/start/stop` (periodic + one-shot)
|
|
- Tickless idle for power efficiency
|
|
- **Test**: STM32F4 (real hardware) + QEMU cortex-m3
|
|
|
|
### Phase 3: Additional Ports — Weeks 9-12
|
|
- `armv8m/` — Cortex-M33 with TrustZone (Secure/Non-secure)
|
|
- `riscv32/` — RV32IMC with PMP (f9-kernel pattern)
|
|
- `xtensa/` — ESP32 (windowed registers, level-1 interrupt)
|
|
- `armv7a/` — Cortex-A with MMU (Tier 2)
|
|
- **Test**: nRF5340, ESP32, HiFive1, QEMU arm-virt
|
|
|
|
### Phase 4: Personality Shells — Weeks 13-16
|
|
- FreeRTOS personality: `xTaskCreate`, `xSemaphoreCreate`, `xQueueCreate`
|
|
- ThreadX personality: `tx_thread_create`, `tx_mutex_get`, `tx_queue_send`
|
|
- POSIX personality: `pthread_create`, `sem_wait`, `mq_send`
|
|
- CMSIS-RTOS v2: `osThreadNew`, `osSemaphoreAcquire`
|
|
- **Test**: Run existing FreeRTOS/ThreadX apps unchanged on UniversalisOS
|
|
|
|
### Phase 5: Hypervisor Extensions (Tier 2/3) — Weeks 17-24
|
|
- `armv8a/` — AArch64 EL2 with vGIC, Stage-2 translation
|
|
- `riscv64/` — Sv39 with H-extension (G-stage page tables)
|
|
- `x86_64/` — VT-x with EPT, VMCS management
|
|
- Guest OS boot (Linux, FreeRTOS, bare-metal)
|
|
- Device passthrough (PCI, UART, timer)
|
|
- **Test**: QEMU aarch64-virt, QEMU riscv64-virt, QEMU x86_64
|
|
|
|
---
|
|
|
|
## Target Hardware Matrix (Priority Order)
|
|
|
|
| P0 | STM32F4 (Cortex-M4), QEMU all arches, x86_64 (existing) |
|
|
| P1 | nRF52/53 (Cortex-M4/M33), ESP32 (Xtensa), STM32H7 (M7) |
|
|
| P2 | i.MX RT1060 (M7), HiFive1 (RISC-V), PIC32 (MIPS32) |
|
|
| P3 | STM32MP1 (A7+M4), i.MX 8M (A53), RISC-V boards |
|
|
|
|
---
|
|
|
|
## File Structure (Target)
|
|
|
|
```
|
|
kernel/
|
|
├── include/
|
|
│ ├── uos_api.h ← Universal kernel API
|
|
│ ├── uos_object.h ← Kernel object base type
|
|
│ ├── uos_config.h ← Tier/arch detection
|
|
│ ├── uos_types.h ← uos_tick_t, uos_prio_t, uos_status_t
|
|
│ └── uos_compiler.h ← Compiler abstraction (__attribute__, etc.)
|
|
├── src/
|
|
│ ├── core/
|
|
│ │ ├── uos_task.c ← Task management (universal)
|
|
│ │ ├── uos_sched.c ← Scheduler (universal, tier-scaled)
|
|
│ │ ├── uos_sem.c ← Semaphore (universal)
|
|
│ │ ├── uos_mutex.c ← Mutex with priority inheritance
|
|
│ │ ├── uos_queue.c ← Message queue
|
|
│ │ ├── uos_event.c ← Event flags
|
|
│ │ ├── uos_timer.c ← Software timers
|
|
│ │ ├── uos_mem.c ← Memory allocator (tier-scaled)
|
|
│ │ ├── uos_tick.c ← Tick management
|
|
│ │ ├── uos_irq.c ← Interrupt dispatch
|
|
│ │ └── uos_idle.c ← Idle task (WFI/WFE/HALT)
|
|
│ ├── port/ ← 11 architecture ports (4 files each)
|
|
│ └── personality/ ← 6 RTOS personality shells
|
|
├── platform/ ← Board-specific BSP (pinmux, clock, UART)
|
|
└── test/ ← Kernel test suite
|
|
```
|
|
|
|
---
|
|
|
|
## Key Design Decisions
|
|
|
|
1. **Static allocation for Tier 0**: No malloc, no heap. All kernel objects statically allocated at compile time via `UOS_STATIC_TASK()` macro.
|
|
|
|
2. **PendSV for all Cortex-M**: Hardware saves R0-R3, LR, PC, xPSR on exception entry. Software saves R4-R11 (and optionally S16-S31). This is the most efficient context switch for Cortex-M.
|
|
|
|
3. **Bitmap priority scheduler**: O(1) using CLZ instruction (available on all ARM Cortex). 32 priority levels. Round-robin within same priority.
|
|
|
|
4. **f9-kernel MPU pattern for Tier 1**: Flexible pages (power-of-2, aligned) mapped to MPU regions. LRU eviction when 8 regions insufficient.
|
|
|
|
5. **Object registry for Tier 1+**: All kernel objects linked in a list for debug/monitoring. Tier 0 skips this (no spare RAM).
|
|
|
|
6. **Personality shells are compile-time**: `#define UOS_PERSONALITY_FREERTOS` selects the FreeRTOS wrapper. Multiple personalities can coexist (each gets its own namespace).
|
|
|
|
7. **Port contract is 4 files**: Every architecture port provides exactly `uos_port.h`, `uos_port_init.c`, `uos_port_context.S`, `uos_port_dispatch.S`. No exceptions.
|
|
|
|
---
|
|
|
|
## Success Criteria
|
|
|
|
### Phase 1 (Week 4)
|
|
- [ ] Cooperative scheduling on Cortex-M0 (QEMU + STM32F0)
|
|
- [ ] 8 tasks running with semaphores and delays
|
|
- [ ] Context switch < 5μs on 48MHz Cortex-M0
|
|
- [ ] Kernel binary < 2KB
|
|
|
|
### Phase 2 (Week 8)
|
|
- [ ] Preemptive scheduling on Cortex-M4 (QEMU + STM32F4)
|
|
- [ ] MPU isolation: task A cannot access task B's memory
|
|
- [ ] Mutex with priority inheritance
|
|
- [ ] Message queues, event flags, software timers
|
|
- [ ] Context switch < 2μs on 168MHz Cortex-M4
|
|
|
|
### Phase 3 (Week 12)
|
|
- [ ] ESP32 port boots and runs tasks
|
|
- [ ] RISC-V PMP port boots on HiFive1
|
|
- [ ] TrustZone Secure/Non-secure split on Cortex-M33
|
|
|
|
### Phase 4 (Week 16)
|
|
- [ ] FreeRTOS app compiles and runs unchanged on UniversalisOS
|
|
- [ ] ThreadX app compiles and runs unchanged on UniversalisOS
|
|
- [ ] POSIX pthread app compiles and runs on UniversalisOS
|
|
|
|
### Phase 5 (Week 24)
|
|
- [ ] Linux boots as guest on AArch64 Tier 3
|
|
- [ ] FreeRTOS runs as guest inside UniversalisOS hypervisor on x86_64
|
|
- [ ] Same kernel binary runs on Cortex-M0 AND Cortex-A72 (different tiers)
|