Silicon Validation Guide

Silicon Validation with LightOS

LightOS was designed from the ground up to accelerate silicon validation workflows. Traditional RTOS platforms require millions of simulation cycles just to boot—LightOS boots in under 1000 cycles.

Why Boot Time Matters

In RTL simulation, every cycle counts. A typical validation regression runs thousands of test cases:

RTOSBoot Cycles10,000 TestsTime @ 100kHz Sim
FreeRTOS~500,0005 billion13.9 hours
Zephyr~1,000,00010 billion27.8 hours
LightOS~8008 million1.3 minutes

Key Features for Validation

Near-Instant Boot

// Boot sequence completes in microseconds
void main() {
    lightos::Kernel::init();  // ~5μs on real hardware
    // Your validation test starts immediately
}

Simulation-Aware Tick System

LightOS detects when running in RTL simulation and adjusts its tick source:

// In RTL simulation: memory-mapped tick register
// On real silicon: hardware timer
auto ticks = lightos::Kernel::current_tick();

Minimal Memory Footprint

Deterministic Behavior

Measured ISR-period jitter (Cortex-R52 @ 600 MHz, 100 Hz tick)

LightOS ships an in-tree TRACE32 capture harness that samples the timer ISR-period delta via PMCCNTR_EL0 for 16,384 consecutive periods in a single uninterrupted run (no debugger halts during capture). Numbers below are the median over the full window.

PathVariantMedianIQRPeak-to-peakP99.9 − median
FIQ-driven tick (m01)default build6,000,002 cyc / 10 ms1 cyc21 cyc / 35 ns+1 cyc
FIQ-driven tick (m01-FIQ-nohook)benchmark build²6,000,002 cyc / 10 ms1 cyc3 cyc / 5 ns+1 cyc
IRQ-driven tick (m01)default build6,000,002 cyc / 10 ms1 cyc32 cyc / 53 ns¹+1 cyc
IRQ-driven tick (m01-IRQ-nohook)benchmark, steady state²³6,000,002 cyc / 10 ms1 cyc1 cyc / 1.7 ns+1 cyc
Coop ctx-switch (m02), Scheduler::yield()n=1024182.5 cyc / 304 ns / switch (median)
Coop ctx-switch (m02), yield_to(target)n=102485.5 cyc / 143 ns / switch (median, 2.33× vs ThreadX)
Coop ctx-switch under 100 kHz IRQ load (m04), yield_to(target)n=1024 (13 M IRQs serviced)90 cyc / 150 ns / switch (median, +5.3 % vs floor); P99 357 cyc, max 397 cyc — bounded by one IRQ-service window
Coop ctx-switch under 1 kHz IRQ load (m04b cadence sweep), yield_to(target)n=1024 (39,612 IRQs serviced)90 cyc / 150 ns / switch (median, P99 90, max 90); jitter 15 cyc / 25 ns — zero in-window collisions — collapses to m02 floor
App-thread wake via sleep_until (m03)default6,000,002 cyc4 cyc31 cyc / 52 ns+5 cyc

¹ raw window peak-to-peak; one operator-perturbed sample excluded.
² benchmark build sets -DLIGHTOS_FIQ_HOOK_DISABLED=ON and/or -DLIGHTOS_IRQ_HOOK_DISABLED=ON, eliding the default weak-symbol bring-up hooks from the ISR entry path.
³ steady state excludes the first 256 warmup samples (I-cache cold-fill) and TRACE32-halt-correlated paired outliers; the underlying handler is deterministic at 1-cycle resolution.

On the same silicon, same compiler, and same tick rate, LightOS now leads ThreadX 6.4 on every measured axis:

The full report, raw .bin captures, CSV exports, and reproduction recipe live under lightos/measurements/ in the repository.

Continuous Fuzzing of Firmware Parsers

LightOS ships with a libFuzzer + ASan/UBSan harness set that exercises the attack surfaces most likely to hide memory-safety bugs on real silicon:

Each harness runs with AddressSanitizer and UndefinedBehaviorSanitizer, keeps its seed corpus in git, and stores mutated inputs out-of-tree. Enable with:

cmake -S . -B build-fuzz -G Ninja \
    -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ \
    -DLIGHTOS_FUZZ=ON
cmake --build build-fuzz --target lightos_fuzz_all
bash scripts/run_fuzz.sh fuzz_aecmd_protocol 60

The first campaign found and fixed two real memory-safety defects before any external release.

Validation-Specific APIs

Test Harness Integration

#include <lightos/validation/test_harness.hpp>

int main() {
    lightos::Kernel::init();

    // Report test status to simulation environment
    lightos::validation::test_start("flash_write_test");

    // Run your test
    bool passed = run_flash_write_test();

    // Signal completion (terminates simulation)
    lightos::validation::test_end(passed ? 0 : 1);
    return 0;
}

Memory-Mapped Register Access

#include <lightos/hw/register.hpp>

// Type-safe register access
auto status = hw::read32(FLASH_STATUS_REG);
hw::write32(FLASH_CMD_REG, FLASH_CMD_ERASE);

// Wait for completion with timeout
bool ok = hw::poll_until(FLASH_STATUS_REG, FLASH_BUSY_BIT, 0,
                          lightos::ms(100));

Semihosting Support

For simulation environments with semihosting:

#include <lightos/semihosting.hpp>

// Print to simulation console
lightos::semihosting::printf("Test iteration %d\n", i);

// Read test parameters from host
uint32_t seed = lightos::semihosting::read_param("RANDOM_SEED");

// Exit simulation with status
lightos::semihosting::exit(test_passed ? 0 : 1);

Supported Simulation Environments

EnvironmentStatusNotes
QEMU (ARM)✅ FullCortex-R52, Cortex-A53
QEMU (RISC-V)✅ FullRV32/RV64, virt machine
VCS/Synopsys✅ FullVia PLI/DPI interface
Xcelium/Cadence✅ FullVia PLI/DPI interface
Verilator✅ FullSystemC wrapper
FPGA Emulation✅ FullZCU102, Arty A7

Example: Flash Controller Validation

#include <lightos/kernel.hpp>
#include <lightos/validation/test_harness.hpp>

// Test flash write/read cycle
void test_flash_basic() {
    constexpr uint32_t TEST_ADDR = 0x1000;
    constexpr uint32_t TEST_DATA = 0xDEADBEEF;

    // Erase sector
    flash_erase_sector(TEST_ADDR);
    LIGHTOS_ASSERT(flash_is_erased(TEST_ADDR));

    // Program
    flash_program(TEST_ADDR, &TEST_DATA, sizeof(TEST_DATA));

    // Verify
    uint32_t readback;
    flash_read(TEST_ADDR, &readback, sizeof(readback));
    LIGHTOS_ASSERT(readback == TEST_DATA);
}

int main() {
    lightos::Kernel::init();

    lightos::validation::test_start("flash_basic");
    test_flash_basic();
    lightos::validation::test_end(0);  // Success

    return 0;
}

Build Configuration for Validation

# CMakeLists.txt
set(LIGHTOS_VALIDATION_MODE ON)    # Enable validation features
set(LIGHTOS_SEMIHOSTING ON)        # Enable semihosting
set(LIGHTOS_MINIMAL_BOOT ON)       # Fastest boot sequence
set(LIGHTOS_TICK_SOURCE "memory")  # Use memory-mapped tick

QEMU Quick Start

# Build for Cortex-R52
cmake -B build-qemu -DLIGHTOS_TARGET=cortex-r52 \
      -DLIGHTOS_VALIDATION_MODE=ON

cmake --build build-qemu --target val_flash_test

# Run in QEMU
qemu-system-arm -M mps3-an536 -cpu cortex-r52 \
    -kernel build-qemu/val_flash_test.elf \
    -nographic -semihosting

Next Steps