// Moved from docs/src/platform-integration/L4RE_INTEGRATION.adoc to docs/working/scratch/src/platform-integration/L4RE_INTEGRATION.adoc on 2026-06-16 (docs reorg Phase 2) == StarForth L4Re Integration Guide :toc: left :toc-title: Contents :toclevels: 3 xref:../README.adoc[← Back to Documentation Index] === Overview This guide covers integrating StarForth into the L4Re Operating System Framework, including: * Building as an L4Re package * Memory management with L4Re dataspaces * IPC communication between VMs * Integration with StarshipOS * Kernel-level integration (if needed) === Table of Contents [arabic] . link:#l4re-basics[L4Re Basics] . link:#package-structure[Package Structure] . link:#build-system-integration[Build System Integration] . link:#memory-management[Memory Management] . link:#ipc-communication[IPC Communication] . link:#multi-vm-architecture[Multi-VM Architecture] . link:#kernel-integration[Kernel Integration] . link:#starshipos-specifics[StarshipOS Specifics] === L4Re Basics ==== What is L4Re? L4Re (L4 Runtime Environment) is a user-level infrastructure for building systems on top of the L4 microkernel ( Fiasco.OC). It provides: * Memory management (dataspaces) * Task/thread management * Inter-Process Communication (IPC) * Device drivers * Runtime libraries ==== Key Concepts [width="100%",cols="27%,73%",options="header",] |=== |Concept |Description |*Task* |Address space + threads |*Dataspace* |Memory object (like file or anonymous memory) |*Capability* |Reference to kernel object (task, dataspace, IPC gate) |*IPC Gate* |Communication endpoint |*Region Manager* |Virtual memory management |*Name Server* |Service discovery |=== === Package Structure ==== Directory Layout Create this structure in your L4Re source tree: .... l4/pkg/starforth/ ├── Control # Package metadata ├── Makefile # Top-level build ├── server/ # Main StarForth server │ ├── Makefile │ └── src/ │ ├── main.cc # L4Re entry point │ ├── l4_vm.cc # L4Re-specific VM wrapper │ └── l4_vm.h ├── lib/ # StarForth as library │ ├── Makefile │ └── src/ # Your existing src/ files ├── include/ # Your existing include/ files └── examples/ # Example clients ├── Makefile └── forth_client.cc .... ==== Control File Create `+l4/pkg/starforth/Control+`: .... provides: starforth requires: libc libstdc++ l4re-core maintainer: rajames description: StarForth VM for L4Re license: CC0 .... === Build System Integration ==== Top-Level Makefile Create `+l4/pkg/starforth/Makefile+`: [source,makefile] ---- PKGDIR ?= . L4DIR ?= $(PKGDIR)/../.. # Subdirectories to build TARGET = lib server examples include $(L4DIR)/mk/subdir.mk ---- ==== Library Makefile Create `+l4/pkg/starforth/lib/Makefile+`: [source,makefile] ---- PKGDIR ?= .. L4DIR ?= $(PKGDIR)/../.. TARGET = libstarforth.a libstarforth.so PC_FILENAME = libstarforth # Architecture detection ifeq ($(ARCH),amd64) ARCH_FLAGS = -march=x86-64-v2 ARCH_DEFINES = -DARCH_X86_64=1 else ifeq ($(ARCH),arm64) ARCH_FLAGS = -march=armv8-a+crc+simd ARCH_DEFINES = -DARCH_ARM64=1 endif # Compiler flags CFLAGS = -std=c99 -O3 $(ARCH_FLAGS) $(ARCH_DEFINES) \ -DUSE_ASM_OPT=1 -DUSE_DIRECT_THREADING=1 \ -DL4RE_BUILD=1 CXXFLAGS = -std=c++17 -O3 $(ARCH_FLAGS) # Include paths PRIVATE_INCDIR = $(PKGDIR)/include $(PKGDIR)/lib/src # Source files (adapt to your structure) SRC_C = vm.c stack_management.c memory_management.c \ dictionary_management.c io.c log.c profiler.c \ repl.c vm_api.c vm_debug.c word_registry.c \ word_source/arithmetic_words.c \ word_source/stack_words.c \ word_source/logical_words.c \ word_source/memory_words.c \ word_source/control_words.c \ word_source/defining_words.c \ word_source/dictionary_words.c \ word_source/double_words.c \ word_source/mixed_arithmetic_words.c \ word_source/return_stack_words.c \ word_source/string_words.c \ word_source/system_words.c \ word_source/vocabulary_words.c \ word_source/io_words.c \ word_source/format_words.c \ word_source/block_words.c \ word_source/editor_words.c \ word_source/starforth_words.c # L4Re-specific wrapper SRC_CC = l4_vm.cc # Dependencies REQUIRES_LIBS = libc libstdc++ include $(L4DIR)/mk/lib.mk ---- ==== Server Makefile Create `+l4/pkg/starforth/server/Makefile+`: [source,makefile] ---- PKGDIR ?= .. L4DIR ?= $(PKGDIR)/../.. TARGET = starforth_server MODE = static # Architecture detection ifeq ($(ARCH),amd64) ARCH_FLAGS = -march=x86-64-v2 ARCH_DEFINES = -DARCH_X86_64=1 else ifeq ($(ARCH),arm64) ARCH_FLAGS = -march=armv8-a+crc+simd ARCH_DEFINES = -DARCH_ARM64=1 endif CXXFLAGS = -std=c++17 -O3 $(ARCH_FLAGS) $(ARCH_DEFINES) PRIVATE_INCDIR = $(PKGDIR)/include SRC_CC = main.cc l4_vm.cc REQUIRES_LIBS = libstarforth l4re_c l4re_c-util libstdc++ libc include $(L4DIR)/mk/prog.mk ---- === Memory Management ==== L4Re Dataspace Integration Create `+l4/pkg/starforth/server/src/l4_vm.h+`: [source,cpp] ---- #pragma once #include #include #include #include extern "C" { #include "vm.h" } namespace StarForth { /** * L4Re-specific VM wrapper * * Uses L4Re dataspaces for memory management instead of malloc() */ class L4VM { public: L4VM(); ~L4VM(); // Initialize VM with L4Re dataspaces bool init(size_t memory_size = VM_MEMORY_SIZE); // Get underlying VM structure VM* get_vm() { return &vm_; } // Cleanup void cleanup(); // Memory management void* map_dataspace(l4_cap_idx_t ds, size_t size); bool unmap_dataspace(void* addr, size_t size); private: VM vm_; l4_cap_idx_t memory_ds_; // Dataspace for VM memory void* memory_addr_; // Mapped address size_t memory_size_; bool initialized_; }; } // namespace StarForth ---- Create `+l4/pkg/starforth/server/src/l4_vm.cc+`: [source,cpp] ---- #include "l4_vm.h" #include #include #include #include extern "C" { #include "log.h" } namespace StarForth { L4VM::L4VM() : memory_ds_(L4_INVALID_CAP), memory_addr_(nullptr), memory_size_(0), initialized_(false) { memset(&vm_, 0, sizeof(vm_)); } L4VM::~L4VM() { cleanup(); } bool L4VM::init(size_t memory_size) { if (initialized_) { return false; } memory_size_ = memory_size; // Allocate capability slot memory_ds_ = l4re_util_cap_alloc(); if (l4_is_invalid_cap(memory_ds_)) { log_message(LOG_ERROR, "L4VM: Failed to allocate capability"); return false; } // Allocate dataspace long ret = l4re_ma_alloc(memory_size_, memory_ds_, 0); if (ret) { log_message(LOG_ERROR, "L4VM: Failed to allocate dataspace: %ld", ret); l4re_util_cap_free(memory_ds_); return false; } // Map dataspace into our address space ret = l4re_rm_attach((void**)&memory_addr_, memory_size_, L4RE_RM_F_SEARCH_ADDR | L4RE_RM_F_RW, memory_ds_, 0, L4_PAGESHIFT); if (ret) { log_message(LOG_ERROR, "L4VM: Failed to map dataspace: %ld", ret); l4re_util_cap_free(memory_ds_); return false; } log_message(LOG_INFO, "L4VM: Allocated %zu bytes at %p", memory_size_, memory_addr_); // Initialize VM structure vm_.memory = static_cast(memory_addr_); vm_.dsp = -1; vm_.rsp = -1; vm_.here = 0; vm_.exit_colon = 0; vm_.error = 0; vm_.halted = 0; // Initialize VM subsystems (from your vm_init function) vm_align(&vm_); // Allocate SCR void *p = vm_allot(&vm_, sizeof(cell_t)); if (!p) { log_message(LOG_ERROR, "L4VM: SCR allot failed"); cleanup(); return false; } vm_.scr_addr = (vaddr_t)((uint8_t*)p - vm_.memory); vm_store_cell(&vm_, vm_.scr_addr, 0); // Allocate STATE p = vm_allot(&vm_, sizeof(cell_t)); if (!p) { log_message(LOG_ERROR, "L4VM: STATE allot failed"); cleanup(); return false; } vm_.state_addr = (vaddr_t)((uint8_t*)p - vm_.memory); vm_store_cell(&vm_, vm_.state_addr, 0); vm_.state_var = 0; // Allocate BASE p = vm_allot(&vm_, sizeof(cell_t)); if (!p) { log_message(LOG_ERROR, "L4VM: BASE allot failed"); cleanup(); return false; } vm_.base_addr = (vaddr_t)((uint8_t*)p - vm_.memory); vm_store_cell(&vm_, vm_.base_addr, 10); vm_.base = 10; initialized_ = true; log_message(LOG_INFO, "L4VM: Initialization complete"); return true; } void L4VM::cleanup() { if (memory_addr_) { l4re_rm_detach(memory_addr_); memory_addr_ = nullptr; } if (l4_is_valid_cap(memory_ds_)) { // Note: dataspace will be freed when capability is released l4re_util_cap_free(memory_ds_); memory_ds_ = L4_INVALID_CAP; } initialized_ = false; } void* L4VM::map_dataspace(l4_cap_idx_t ds, size_t size) { void* addr = nullptr; long ret = l4re_rm_attach(&addr, size, L4RE_RM_F_SEARCH_ADDR | L4RE_RM_F_RW, ds, 0, L4_PAGESHIFT); if (ret) { log_message(LOG_ERROR, "L4VM: Failed to map dataspace: %ld", ret); return nullptr; } return addr; } bool L4VM::unmap_dataspace(void* addr, size_t size) { (void)size; // L4Re tracks size internally long ret = l4re_rm_detach(addr); if (ret) { log_message(LOG_ERROR, "L4VM: Failed to unmap dataspace: %ld", ret); return false; } return true; } } // namespace StarForth ---- === IPC Communication ==== Server Main Entry Point Create `+l4/pkg/starforth/server/src/main.cc+`: [source,cpp] ---- #include #include #include #include #include #include #include "l4_vm.h" extern "C" { #include "vm.h" #include "log.h" #include "word_registry.h" } // StarForth IPC protocol opcodes enum { OP_INTERPRET = 0, OP_PUSH = 1, OP_POP = 2, OP_GET_STATE = 3, OP_RESET = 4, }; /** * StarForth server implementing IPC interface */ class StarForth_server : public L4::Epiface_t { public: StarForth_server() { if (!l4vm_.init()) { printf("Failed to initialize L4VM\n"); return; } // Register standard Forth words VM* vm = l4vm_.get_vm(); register_stack_words(vm); register_arithmetic_words(vm); register_logical_words(vm); register_memory_words(vm); register_control_words(vm); // ... register other word sets ... printf("StarForth server initialized\n"); } // IPC dispatch - handle incoming messages long op_dispatch(l4_umword_t obj, L4::Ipc::Iostream &ios) { l4_msgtag_t tag; ios >> tag; if (tag.label() == 0) { // Handle our custom protocol l4_umword_t opcode; ios >> opcode; switch (opcode) { case OP_INTERPRET: return handle_interpret(ios); case OP_PUSH: return handle_push(ios); case OP_POP: return handle_pop(ios); case OP_GET_STATE: return handle_get_state(ios); case OP_RESET: return handle_reset(ios); default: return -L4_EINVAL; } } return -L4_ENOSYS; } private: long handle_interpret(L4::Ipc::Iostream &ios) { char buffer[256]; unsigned long len; ios >> L4::Ipc::buf_cp_in(buffer, sizeof(buffer), len); buffer[len < sizeof(buffer) ? len : sizeof(buffer)-1] = '\0'; VM* vm = l4vm_.get_vm(); vm_interpret(vm, buffer); // Send reply with error status ios << L4::Ipc::Small_buf(&vm->error, sizeof(vm->error)); return L4_EOK; } long handle_push(L4::Ipc::Iostream &ios) { cell_t value; ios >> value; VM* vm = l4vm_.get_vm(); vm_push(vm, value); ios << L4::Ipc::Small_buf(&vm->error, sizeof(vm->error)); return L4_EOK; } long handle_pop(L4::Ipc::Iostream &ios) { VM* vm = l4vm_.get_vm(); cell_t value = vm_pop(vm); ios << value; ios << L4::Ipc::Small_buf(&vm->error, sizeof(vm->error)); return L4_EOK; } long handle_get_state(L4::Ipc::Iostream &ios) { VM* vm = l4vm_.get_vm(); struct { int dsp; int rsp; int error; int halted; } state; state.dsp = vm->dsp; state.rsp = vm->rsp; state.error = vm->error; state.halted = vm->halted; ios << L4::Ipc::buf_cp_out(L4::Ipc::Small_buf(&state, sizeof(state))); return L4_EOK; } long handle_reset(L4::Ipc::Iostream &ios) { l4vm_.cleanup(); if (!l4vm_.init()) { int error = 1; ios << error; return -L4_ENOMEM; } int success = 0; ios << success; return L4_EOK; } StarForth::L4VM l4vm_; }; int main() { printf("StarForth L4Re Server starting...\n"); // Create server object static StarForth_server server; // Register with name server L4Re::Env const *env = L4Re::Env::env(); // Get capability to registry L4::Cap registry = env->get_cap("starforth"); if (!registry.is_valid()) { printf("Failed to get starforth capability\n"); return 1; } // Create object registry for IPC static L4Re::Util::Registry_server<> registry_server( L4::cap_reinterpret_cast(env->main_thread()), env->factory()); // Register server if (!registry_server.registry()->register_obj(&server, "starforth").is_valid()) { printf("Failed to register server object\n"); return 1; } printf("StarForth server ready\n"); // Enter server loop registry_server.loop(); return 0; } ---- ==== Client Example Create `+l4/pkg/starforth/examples/forth_client.cc+`: [source,cpp] ---- #include #include #include #include #include extern "C" { #include "vm.h" } // Match server opcodes enum { OP_INTERPRET = 0, OP_PUSH = 1, OP_POP = 2, OP_GET_STATE = 3, OP_RESET = 4, }; class StarForthClient { public: StarForthClient() : server_cap_(L4_INVALID_CAP) { // Get capability to StarForth server L4Re::Env const *env = L4Re::Env::env(); server_cap_ = env->get_cap("starforth"); if (!server_cap_.is_valid()) { printf("Failed to get starforth server capability\n"); } } bool interpret(const char* code) { if (!server_cap_.is_valid()) return false; l4_msgtag_t tag = l4_msgtag(0, 0, 0, 0); l4_msg_regs_t *mr = l4_utcb_mr(); // Send opcode mr->mr[0] = OP_INTERPRET; // Send code string size_t len = strlen(code); memcpy(&mr->mr[1], code, len); tag = l4_msgtag(0, 1 + (len + sizeof(l4_umword_t) - 1) / sizeof(l4_umword_t), 0, 0); tag = l4_ipc_call(server_cap_.cap(), l4_utcb(), tag, L4_IPC_NEVER); if (l4_ipc_error(tag, l4_utcb())) { printf("IPC error: %ld\n", l4_ipc_error(tag, l4_utcb())); return false; } // Get error status from reply int error; memcpy(&error, &mr->mr[0], sizeof(error)); return error == 0; } bool push(cell_t value) { if (!server_cap_.is_valid()) return false; l4_msgtag_t tag = l4_msgtag(0, 2, 0, 0); l4_msg_regs_t *mr = l4_utcb_mr(); mr->mr[0] = OP_PUSH; memcpy(&mr->mr[1], &value, sizeof(value)); tag = l4_ipc_call(server_cap_.cap(), l4_utcb(), tag, L4_IPC_NEVER); if (l4_ipc_error(tag, l4_utcb())) { return false; } int error; memcpy(&error, &mr->mr[0], sizeof(error)); return error == 0; } cell_t pop(bool* success = nullptr) { if (!server_cap_.is_valid()) { if (success) *success = false; return 0; } l4_msgtag_t tag = l4_msgtag(0, 1, 0, 0); l4_msg_regs_t *mr = l4_utcb_mr(); mr->mr[0] = OP_POP; tag = l4_ipc_call(server_cap_.cap(), l4_utcb(), tag, L4_IPC_NEVER); if (l4_ipc_error(tag, l4_utcb())) { if (success) *success = false; return 0; } cell_t value; memcpy(&value, &mr->mr[0], sizeof(value)); int error; memcpy(&error, &mr->mr[1], sizeof(error)); if (success) *success = (error == 0); return value; } private: L4::Cap server_cap_; }; int main() { printf("StarForth Client Example\n"); StarForthClient client; // Test pushing and popping printf("Pushing 42...\n"); if (client.push(42)) { printf("Success\n"); } printf("Pushing 17...\n"); client.push(17); // Pop and print bool success; cell_t val = client.pop(&success); if (success) { printf("Popped: %ld\n", val); } val = client.pop(&success); if (success) { printf("Popped: %ld\n", val); } // Interpret some Forth code printf("\nInterpreting: 10 20 + .\n"); if (client.interpret("10 20 + .")) { printf("Interpretation successful\n"); } printf("\nInterpreting: : SQUARE DUP * ;\n"); client.interpret(": SQUARE DUP * ;"); printf("Interpreting: 5 SQUARE .\n"); client.interpret("5 SQUARE ."); return 0; } ---- === Multi-VM Architecture ==== Design Pattern: Multiple Forth VMs .... ┌─────────────────┐ │ Ned (Root) │ │ - Name Server │ │ - VM Manager │ └────────┬────────┘ │ ┌────┴─────┬─────────────┐ │ │ │ ┌───▼────┐ ┌──▼─────┐ ┌─────▼────┐ │ VM 1 │ │ VM 2 │ │ VM 3 │ │ Forth │ │ Forth │ │ Forth │ │ Tasks │ │ Server │ │ REPL │ └────────┘ └────────┘ └──────────┘ .... ==== VM Manager (Ned Configuration) Create `+l4/conf/modules.list+` entry: [source,lua] ---- -- StarForth VMs entry { name = "starforth-server", cmdline = "rom/starforth_server", caps = { starforth = L4.default_loader:new_channel(), }, } entry { name = "starforth-client", cmdline = "rom/forth_client", caps = { starforth = L4.Env.starforth_server:svr(), }, } ---- === Kernel Integration ==== For StarshipOS: Forth in Kernel Context ⚠️ *Warning*: Running Forth in kernel requires extreme care! ===== Use Cases [arabic] . *Kernel configuration* - Runtime kernel tunables . *Device driver scripting* - Hotpatch device drivers . *Debugging* - Interactive kernel debugging ===== Limitations * No malloc/free (use static memory pools) * No syscalls * Limited stack space * Must be interrupt-safe * Must not block ===== Example: Kernel Module Create `+l4/pkg/starforth/kernel/starforth_kernel.cc+`: [source,cpp] ---- #include #include extern "C" { #include "vm.h" } // Static memory pool for kernel VM static uint8_t kernel_vm_memory[256 * 1024] __attribute__((aligned(4096))); static VM kernel_vm; static bool kernel_vm_initialized = false; /** * Initialize kernel-mode Forth VM * * Called during kernel initialization */ extern "C" void starforth_kernel_init(void) { if (kernel_vm_initialized) return; // Initialize VM with static memory kernel_vm.memory = kernel_vm_memory; kernel_vm.dsp = -1; kernel_vm.rsp = -1; kernel_vm.here = 0; kernel_vm.error = 0; kernel_vm.halted = 0; // Register minimal word set (safe for kernel) // NO I/O words, NO blocking operations register_arithmetic_words(&kernel_vm); register_logical_words(&kernel_vm); register_stack_words(&kernel_vm); // Add kernel-specific words // e.g., words to read/write kernel data structures kernel_vm_initialized = true; } /** * Execute Forth code in kernel context * * DANGEROUS: Only call from trusted sources! */ extern "C" int starforth_kernel_exec(const char* code) { if (!kernel_vm_initialized) return -1; vm_interpret(&kernel_vm, code); return kernel_vm.error; } /** * Kernel debugger integration */ extern "C" void starforth_kernel_repl(void) { // Interactive REPL for kernel debugging // Use polling serial I/O, no interrupts char buffer[256]; while (1) { // Read line from serial (implement polling version) kernel_serial_read_line(buffer, sizeof(buffer)); if (strcmp(buffer, "exit") == 0) break; vm_interpret(&kernel_vm, buffer); if (kernel_vm.error) { kernel_serial_write("Error\n"); kernel_vm.error = 0; } } } ---- === StarshipOS Specifics ==== Integration Points [arabic] . *Boot Service* - Start StarForth server during boot . *System Configuration* - Use Forth for configuration . *Hot-patching* - Runtime system updates . *Interactive Debugging* - REPL for live system ==== Boot Integration Modify StarshipOS boot sequence: [source,cpp] ---- // In your StarshipOS init task void starship_boot() { // ... other initialization ... // Start StarForth server L4Re::Util::Env_ns ns; ns.register_obj("starforth", L4Re::Env::env()->get_cap("starforth_server")); // Load boot scripts starforth_load_script("/boot/init.fth"); // ... continue boot ... } ---- ==== System Configuration Example Create `+/boot/init.fth+`: [source,forth] ---- \ StarshipOS Boot Configuration ." StarshipOS initializing..." CR \ Configure kernel parameters : SET-KERNEL-PARAM ( value param-id -- ) \ ... syscall to set kernel parameter ... ; \ Example: Set scheduler quantum 100 1 SET-KERNEL-PARAM \ Start system services : START-SERVICE ( service-name -- ) \ ... load and start service ... ; " network-stack" START-SERVICE " file-system" START-SERVICE ." Boot complete!" CR ---- === Building and Testing ==== Build Commands [source,bash] ---- # From L4Re source root cd l4/pkg/starforth # Build for x86_64 make ARCH=amd64 O=build_amd64 make ARCH=amd64 O=build_amd64 install # Build for ARM64 make ARCH=arm64 O=build_arm64 make ARCH=arm64 O=build_arm64 install # Cross-build from x86_64 make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- O=build_arm64_cross ---- ==== Creating Boot Image [source,bash] ---- # Create modules list cd l4/conf cat > myconf.list << EOF modaddr 0x02000000 entry starforth_server kernel fiasco -serial_esc roottask moe rom/myconf.cfg module l4re module ned rom/myconf.lua module starforth_server module forth_client EOF # Build image make O=mybuild qemu E=myconf ---- ==== Running in QEMU [source,bash] ---- # x86_64 make O=mybuild qemu E=myconf # ARM64 (for Raspberry Pi 4 testing) make O=mybuild ARCH=arm64 PLATFORM_TYPE=rv_pbx qemu E=myconf ---- === Performance Considerations ==== Memory Layout Optimization [source,cpp] ---- // Align VM memory to huge pages (2MB on x86_64, ARM64) #define VM_MEMORY_SIZE (2 * 1024 * 1024) // Request huge page when allocating dataspace l4re_ds_flags_t flags = L4RE_DS_F_NORMAL | L4RE_DS_F_ALIGN(21); // 2^21 = 2MB long ret = l4re_ma_alloc_align(VM_MEMORY_SIZE, memory_ds_, flags, 21); ---- ==== IPC Optimization [source,cpp] ---- // Use shared memory for large data transfers class FastForthClient { public: bool interpret_large(const char* code, size_t len) { if (len < 1024) { return interpret_small(code, len); // Use IPC } // Use shared dataspace for large code l4_cap_idx_t ds = create_shared_buffer(len); memcpy(shared_addr_, code, len); // Send dataspace capability + offset send_interpret_ds(ds, 0, len); return true; } }; ---- ==== CPU Affinity [source,cpp] ---- // Pin Forth VM to specific CPU for better cache locality l4_sched_param_t sp = l4_sched_param(255, 0); // Priority 255, CPU 0 sp.affinity = l4_sched_cpu_set(0, 0); // CPU 0 only l4_scheduler()->run_thread(L4Re::Env::env()->main_thread(), sp); ---- === Debugging ==== GDB with L4Re [source,bash] ---- # Start QEMU with GDB server make O=mybuild qemu E=myconf QEMU_OPTIONS="-s -S" # In another terminal aarch64-linux-gnu-gdb build_arm64/pkg/starforth/server/starforth_server (gdb) target remote :1234 (gdb) break main (gdb) continue ---- ==== JDB (Fiasco Kernel Debugger) .... # Enter JDB Ctrl+^ (or configured escape sequence) # Show tasks l t # Switch to StarForth server task t # Show threads l T # Backtrace i s .... ==== Logging [source,cpp] ---- // Use L4Re logging #include L4Re::Util::Dbg log(L4Re::Util::Dbg::Info, "starforth"); log.printf("VM state: dsp=%d error=%d\n", vm->dsp, vm->error); ---- === Security Considerations ==== Capability-based Security [source,cpp] ---- // Restrict VM capabilities class RestrictedVM { public: RestrictedVM() { // Only grant specific capabilities vm_grant_cap(CAP_MEMORY_READ); vm_grant_cap(CAP_COMPUTE); // Do NOT grant CAP_MEMORY_WRITE or CAP_IPC } }; ---- ==== Sandboxing [source,lua] ---- -- In Ned configuration local vm = L4.default_loader:start({ caps = { -- Only grant necessary capabilities icu = L4.Env.icu, log = L4.Env.log, -- No scheduler, no memory allocator }, log = {"vm", "yellow"}, }, "rom/starforth_server") ---- === Troubleshooting ==== Common Issues *Problem*: Dataspace allocation fails [source,cpp] ---- // Check quota l4re_ma_query_quota(); // Increase quota in Ned config entry { mem = 8 * 1024 * 1024, -- 8MB quota } ---- *Problem*: IPC timeout [source,cpp] ---- // Increase timeout l4_timeout_t timeout = l4_timeout(L4_IPC_TIMEOUT_NEVER); tag = l4_ipc_call(cap, utcb, tag, timeout); ---- *Problem*: Capability not found [source,lua] ---- -- Check Ned configuration caps = { starforth = L4.default_loader:new_channel(), -- Create channel } ---- === References * https://l4re.org/doc/[L4Re Documentation] * https://l4re.org/fiasco/[Fiasco.OC Reference Manual] * https://l4re.org/doc/tutorial.html[L4Re Tutorial] * https://os.inf.tu-dresden.de/L4/[TU Dresden L4 Research] === Next Steps [arabic] . Port your existing StarForth code to L4Re package structure . Test in QEMU with L4Re . Deploy to actual hardware (x86_64 or Raspberry Pi 4) . Integrate with StarshipOS services . Add security policies and sandboxing . Performance tuning with real workloads Good luck with your L4Re integration! 🚀