Tock: an embedded OS that isolates untrusted apps on Cortex-M and RISC-V
A secure embedded operating system for microcontrollers
At a glance
- What is it?
- Tock runs multiple mutually distrustful applications on microcontrollers, using Rust for kernel and driver isolation and an MPU for application isolation. Here is what the repository shows about building it, what it costs to adopt, and where it stops being the right answer.
- Who is it for?
- Tock fits teams that must run several mutually distrustful applications on one Cortex-M or RISC-V part and are willing to write or port those applications against its system call interface. It does not fit projects that need POSIX, a large prebuilt package ecosystem, or a single superloop firmware with no isolation requirement.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem Tock solves: several distrustful programs on one small MCU
A microcontroller normally runs one firmware image. If you want two functions on the same chip, you link them into the same binary, and a bug or a compromised component in one can reach the other's memory. Tock's stated design centers on protection, both from potentially malicious applications and from device drivers. The README describes the target as running multiple concurrent, mutually distrustful applications on Cortex-M and RISC-V based embedded platforms. The intended audience is therefore narrow and specific: people building devices where the software mix is not fully trusted, where one component might be updated or supplied by a different party than another, and where the hardware has a memory protection unit. The SOSP'17 paper title in the README, Multiprogramming a 64kB Computer Safely and Efficiently, sets the scale: this is not a Linux replacement, it is an operating system for parts measured in tens or hundreds of kilobytes of RAM.
Two isolation mechanisms: Rust inside the kernel, the MPU around applications
Tock uses two mechanisms, and they operate at different boundaries. The first is the language. The kernel and device drivers are written in Rust, which the README describes as providing compile-time memory safety and type safety. Tock uses Rust to protect the kernel, meaning the scheduler and hardware abstraction layer, from platform-specific device drivers, and to isolate device drivers from each other. That is a compile-time and module-boundary argument, not a runtime sandbox. The second mechanism is hardware: memory protection units isolate applications from each other and from the kernel. So the trust split is kernel and drivers on one side, applications on the other, with the MPU enforcing the application side at runtime.
The repository layout reflects this split directly. kernel/ holds the core, capsules/ holds reusable driver logic, chips/ holds per-chip implementations, arch/ holds the architecture ports, and boards/ holds one directory per supported board. The Cargo.toml workspace lists those board directories as members, which means a board is not a configuration file but a Rust crate that composes the kernel, the chips and the capsules it needs. Adding support for a new part means writing code in chips/ and a board crate, not editing a device tree.
Building Tock for a board: make in the board directory
The top-level Makefile is a dispatcher. Running plain make prints a welcome message, points at doc/Getting_Started for prerequisites, and then lists the boards that mainline Tock supports by shelling out to tools/build/list_boards.sh. The instruction it gives is explicit: run make in a board directory to build Tock for that board, and make install to load it onto hardware. It also notes that each board folder has its own README with more information, and that cargobloat and stack-analysis are available as per-board targets.
So the first real use is two commands, run from the board directory rather than the repository root:
cd boards/nordic/nrf52840dk
makeA successful build produces the board's kernel image in that directory. The exact artifact name and the flashing step are board-specific; the top-level Makefile does not describe them, and defers to the board README. To put it on hardware:
make installThat is the whole documented loop: pick a board, build, install. Note that the Makefile forces bash as the shell, with a comment that some systems have strange default shells, so running these under a different shell is not the tested path. The toolchain is pinned in rust-toolchain.toml at the repository root, so rustup will select the expected compiler version rather than whatever is installed globally. If you want to see which boards exist before choosing, the usage target prints the list:
make usageWhere Tock is the wrong tool
Tock's isolation model assumes a memory protection unit. On a part without an MPU, the second of the two protection mechanisms is unavailable, and the application isolation argument does not hold; the Rust-side argument about kernel and driver separation still applies, but that is a different and weaker claim. If your chip has no MPU, the design premise does not transfer.
The second limitation is the application model itself. Tock applications are not Linux processes. They are built against Tock's own system call interface and loaded separately from the kernel. If your existing firmware is a single binary using vendor HALs and a real-time loop, adopting Tock means restructuring it into a kernel plus one or more applications, or writing capsules that expose the hardware you need. The README does not describe a compatibility shim for POSIX or for an existing RTOS API, and none appears in the top-level repository entries.
The third is board coverage. The workspace member list is long, but it is a list of specific boards: nrf52840dk, raspberry_pi_pico, stm32f429idiscovery, hifive1, imix, and so on. A chip family being supported does not mean your board is. If your exact board is absent, you are writing a board crate before you write any application. For a one-off product with a single trusted firmware image and no isolation requirement, that work buys nothing.
Finally, the top-level Makefile documents no rollback path. It describes make install, and the README does not cover reverting a board to its previous firmware. Treat the first flash of a new board as a step to plan separately.
How Tock differs from Zephyr and from a bare-metal superloop
Zephyr is the closest widely used alternative, and the difference is in what gets isolated. Zephyr is a configurable RTOS built around Kconfig and devicetree, with a large driver and subsystem tree and a broad board list; its typical deployment is one trusted application image, with threads inside it sharing an address space. Tock inverts that. The kernel is small and written in Rust, drivers are capsules, and the unit of deployment is an application that the MPU keeps away from the kernel and from other applications. If your requirement is a rich set of middleware and a build system configured by Kconfig, Zephyr answers it more directly. If your requirement is that two pieces of software on the same chip cannot read each other's memory, Tock's model is the one built for that.
The other alternative is the bare-metal superloop with a vendor HAL. It has no isolation, no scheduler and no system call boundary, and for a single-purpose device that is often correct. Tock only earns its complexity when the multi-application, mutually distrustful premise is real.
Maintenance, release cadence and licence
The repository is not archived, and the last push was on 2026-09-19, three days before this writing. Recent releases are release-2.2 on 2025-01-06, preceded by release-2.2-rc1 on 2024-12-18 and release-2.1.1 on 2023-01-06. The README states that Tock is on its second major release and points at CHANGELOG.md for the summary of new features. The gap between 2.1.1 and 2.2 is roughly two years, which is the realistic upgrade rhythm to plan around: this is not a project that ships a tagged release every month.
Upgrade cost has two parts. The first is the pinned toolchain in rust-toolchain.toml; a Rust version bump can require changes across kernel, chips and capsules at once. The second is the application interface. Applications are built against Tock's system call interface, so a kernel upgrade is not automatically transparent to the applications already deployed. The CHANGELOG.md at the repository root is the place to check what a given release changes before moving a deployed board.
On licensing, the file headers state SPDX-License-Identifier: Apache-2.0 OR MIT, and LICENSE-APACHE and LICENSE-MIT are both present at the top level. The dual licence means you choose either. The repository's licence metadata is reported as NOASSERTION, which is a metadata classification rather than a statement about the files themselves; read LICENSE-APACHE, LICENSE-MIT and COPYRIGHT directly, and get your own advice if the distinction matters for your product.
Editorial conclusion
Tock fits teams that must run several mutually distrustful applications on one Cortex-M or RISC-V part and are willing to write or port those applications against its system call interface. It does not fit projects that need POSIX, a large prebuilt package ecosystem, or a single superloop firmware with no isolation requirement. Before committing, verify three things in the repository: that a board directory exists for your exact part in the Cargo.toml workspace members list, that the kernel and your chosen capsules compile under the pinned rust-toolchain.toml, and what your board's README says about the flashing and debug steps, since those differ per board and the top-level Makefile only prints the list.
Frequently asked questions
Which boards does Tock support?
The board list is the Cargo.toml workspace members under boards/, and the top-level Makefile prints it via tools/build/list_boards.sh. It includes entries such as boards/nordic/nrf52840dk, boards/raspberry_pi_pico, boards/hifive1 and boards/imix. A supported chip family does not imply your specific board is present.
How do I build and install Tock on a board?
Run make inside the board directory to build it, and make install to load it onto hardware, as the top-level Makefile usage text states. Each board folder has its own README covering the specifics.
Is Tock written in Rust, and what does that buy?
The kernel and device drivers are written in Rust, which the README says provides compile-time memory safety and type safety. Tock uses that to protect the kernel from platform-specific device drivers and to isolate drivers from each other.
What licence is Tock under?
The file headers carry SPDX-License-Identifier: Apache-2.0 OR MIT, and LICENSE-APACHE and LICENSE-MIT both sit at the top level. The choice between them is yours.
Does Tock need a memory protection unit?
The README describes MPUs as the mechanism that isolates applications from each other and from the kernel, which is one of Tock's two protection mechanisms. Without an MPU that half of the model is unavailable.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/tock-tock)