Workflow Overviews¶
styx
is a “composable emulation framework,” meaning that the overarching purpose is to provide the
necessary building blocks that create a straightforward avenue to emulate your target device, provided
it’s actually possible (worst-case you’ll need to have access to the CPU manual, but hopefully not). A
“target” is just the representative term for “the thing you need to emulate.”
While styx
is technically a “composable emulation framework,” and can technically perform an arbitrary
amount of emulation tasks, styx
was designed with a few different workflows in mind which are (hopefully)
reflected in the developed extensions and libraries that are a part of styx
, as they should all attempt
to adhere to one or more of the intended workflows. Because the term “emulation” itself is pretty overloaded,
and the usecases can vary wildly, we instead try to frame the usecases as what styx
can do, as opposed to
“emulation”.
The main use cases we try to fulfill are:
One of the big goals in maintaining a “composable emulation framework” is that all of the workflows can
work off of the same interfaces / infrastructure created for the framework, meaning that all tracing or
debugging capability added to support one target can work for all targets. At the cost of some start-up
development time in the micro-scale, this gives styx
the ability to rapidly advance the feature-set
of the entire project at once.
Want to add gdb
support? Create a plugin that connects our Architecture
interface with the
CpuBackend
trait, and now all targets can utilize the new plugin. Want to add a new GPS
device
that talks over UART
? Now any machine can also import that created peripheral. styx
seeks to
advance the state of the art of emulation through common interfaces, “write-once” peripherals, and
a shared Rust
core that creates a solid architecture driven by our main workflows:
Traceable Emulation¶
One of the most common questions when running software under emulation is “what is happening”, via
styx-trace
and the intrinsic target tracing capabilities, all targets should have first-class
support for retrieving an exact ordered record of events of emulation, down to the instruction,
memory, register, DMA, and interrupt level.
Currently supported frontends for tracing:
command line tool to filter on events as they occur
Currently incubating frontends for tracing:
web application to control, monitor, and analyze executing emulator
Potential frontends for tracing:
Ghidra integration
IDE integration
Debuggable Emulation¶
While tracing is a great approach to figuring out “what happened,” it often requires a lot of tooling and infrastructure to create the filtering layers necessary to get useful information out of it, and sometimes you want to be able to debug your code running on an emulated target and step through code. While this behavior can be replicated via tracing, debugging implies the ability to manually tweak execution as it happens, which can be instrumental in reasoning about target behavior.
Currently supported frontends for debugging include:
gdb
plugin supportinggdb-remote
serial protocol over TCP + Unix Domain Socket
Potential frontends for debugging:
Web application
Debug adapter protocol (DAP)
IDE integration plugins
Interactive Emulation¶
Sometimes the need for emulation is to test and verify that the tool you’re making can correctly
interoperate with another. Interactive emulation is a little more complicated in that real life
nuances can affect the development and behavior of developed emulator. Interactive emulation can
be as simple as a console that pong
’s to your ping
message, or emulates an entire vehicle
based on artificial stimuli.
Each Interactive Emulation project has largely application specific frontends, but many core utilities are shared across the developed tools.
Fuzzable Emulation¶
The concept of “fuzzable emulation” is emulation that is accurate and fast enough to reasonably execute many iterations of target software while being able to find inputs that crash the system under test.
Potential frontends for fuzzing:
Make a
styx
AFL++
backendMake a
styx
libAFL
backendAutomatically generate fuzzing harnesses for devices and peripheral interfaces
Testable Emulation¶
One of the lesser-publicized but more “useful” use-cases for emulation is to verify the code you wrote did what is was supposed to. By creating a library around the remote emulation control API’s and the tracing API’s you can create a library for use in development or CI that can provide a way to create temporal unit tests to “make sure this thing happened”, or “make sure this thing happened after I executed this code that did something else”
Potential frontends for testing:
styx
as a CI-harness to emulate firmwarestyx
as a python script to quickly test your binary patches still maintain the same behaviors as before, and the the patch corrected the previous mistakes or correctly performs its new task
Integrated Emulation¶
The purpose of creating an integrated emulation tool is to embed the target emulator in something else. In general this usually ends up being connecting and interacting with another emulator (here being arbitrarily referred to as Connected Emulation), or creating a cycle-accurate emulator that can be embedded or hooked up to a higher level multi-physics simulation (here being arbitrarily referred to as Simulation Embedding).
Connected Emulation¶
In many cases the smaller DSP or microcontroller is a sub-component of a larger system, which has
an already supported emulation for something like AARCH64
or PowerPC 64
etc., instead of needing
to scrap all your work using one emulation platform or another, use each emulation framework where they
excel, and implement the communication + synchronization between them.
Potential frontends for connected emulation libraries:
Integrate
styx
ethernet PHY peripherals with host PHY layerIntegrate
styx
serial PHY peripherals with host PHY layerCreate a
QEMU
IPC library that communicates to theQEMU
emulators
Simulation Embedding¶
Largely explored in academia and hardware development / verification, creating cycle-accurate emulation that can be integrated into a larger simulation framework. This requires great attention to correctness of event controller emulation and instruction cycle annotation, and orchestrating the inputs to attached peripherals and devices for the systems being emulated.
Potential frontends for simulated embedding of emulation:
Simulink plugin models to interface with
styx
emulatorsAutomatically generate
SystemC
component libraries forstyx-peripheral
devicesCreate custom interface modules between simulation libraries and
styx
emulators to verify emulated target behavior