Update libtock's build script to not conflict with libtock_runtime's build script and remove the broken empty_main example.

I made changes to libtock_runtime's linker scripts and the changes were not having any effect.

Explanation: According to the cargo reference, build scripts should only write to OUT_DIR [1]. This is not enforced, and libtock's build script wrote `layout.ld` directly in `libtock`'s source directory. This works for libtock because rust-lld is executed in the cargo workspace directory, which is libtock's source directory, so the linker was able to find layout.ld. However, after libtock has been build once, when the linker runs for libtock_runtime, there are two layout.ld files present: the file in OUT_DIR from libtock_runtime's build script and a leftover layout.ld file from the last time libtock was compiled. The linker selected the layout.ld file in the libtock package, which is not the one we wanted it to select. There isn't a way to change this behavior by the linker.

To avoid this, I changed libtock's build script to copy its layout.ld into OUT_DIR, isolating it from libtock_runtime. I also removed layout.ld from .gitignore. So that the include from layout.ld to layout_generic.ld works, I also made it copy layout_generic.ld into OUT_DIR (the same way libtock_runtime's new build script works).

This then broke libtock_core's example, `empty_main`. libtock_core does not have a linker script mechanism, and its build was relying on the presence of layout.ld from libtock's build script. This is a bug, and was never caught.

I added the `empty_main` example before I redirected my libtock_platform efforts at Tock 2.0. At that time, I was planning to add libtock_runtime to libtock_core. However, when I changed my libtock_platform efforts to the Tock 2.0 ABI, it was no longer possible to add libtock_runtime to libtock_core. It also means that empty_main isn't very useful (it measures the size of code I'm replacing rather than refactoring), so I deleted it.

[1] https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script
3 files changed
tree: 248468aa7eb37585f4c33fdd7f82ec7153511ccd
  1. .cargo/
  2. .github/
  3. .vscode/
  4. boards/
  5. codegen/
  6. core/
  7. doc/
  8. examples/
  9. examples-features/
  10. src/
  11. test_runner/
  12. tools/
  13. .gitignore
  14. .gitmodules
  15. bors.toml
  16. build.rs
  17. Cargo.toml
  18. CHANGELOG.md
  20. layout_generic.ld
  23. Makefile
  24. README.md
  25. rust-toolchain
  26. rustfmt.toml

Build Status


Rust userland library for Tock (WIP)

Generally this library was tested with tock Release 1.5. Since then changes have been made that might not work with the Tock release 1.5, but instead target Tock master. For example this library might support newer boards (Apollo3), changed boards (HiFive1 revB) or new drivers (HMAC).

The library works in principle on most boards, but there is currently the showstopper bug #28 that prevents the generation of relocatable code. This means that all applications must be installed at the flash address they are compiled with, which usually means that they must be compiled especially for your board and that there can only be one application written in rust at a time and it must be installed as the first application on the board, unless you want to play games with linker scripts. There are some boards/layout_*.ld files provided that allow to run the examples on common boards. Due to MPU region alignment issues they may not work for applications that use a lot of RAM, in that case you may have to change the SRAM start address to fit your application.

Getting Started

This project is nascent and still under heavy development, but first steps:

  1. Ensure you have rustup installed.

  2. Clone the repository:

    git clone --recursive https://github.com/tock/libtock-rs
    cd libtock-rs
  3. Install the dependencies:

    make setup
  4. Use make to build examples

    make nrf52 # Builds all examples for the nrf52 platform
    make opentitan # Builds all examples for the OpenTitan platform
    make opentitan FEATURES=alloc # Builds all examples for the OpenTitan platform, with alloc feature enabled
    make flash-hail EXAMPLE=blink # Flash the example 'blink' program to the hail platform

    For an unknown platform, you may have to create your own memory layout definition. Place the layout definition file at boards/layout_<platform>.ld and do not forget to enhance the tockloader_flags dispatching section in tools/flash.sh. You are welcome to create a PR, s.t. the number of supported platforms grows.

Using libtock-rs

The easiest way to start using libtock-rs is adding an example to the examples folder. The boiler plate code you would write is


use libtock::result::TockResult;

async fn main() -> TockResult<()> {
  // Your code

If you want to use heap based allocation you will have to add

extern crate alloc;

to the preamble and store your example in the examples-alloc folder.

To build the examples for your board you can use

make <platform> [FEATURES=alloc]

An example can be flashed to your board after the build process by running:

make flash-<platform> EXAMPLE=<example>

This script does the following steps for you:

  • cross-compile your program
  • create a TAB (tock application bundle)
  • if you have a J-Link compatible board connected: flash this TAB to your board (using tockloader)


libtock-rs is licensed under either of

at your option.

Submodules have their own licenses.


Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

The contribution guidelines can be found here: contribution guidelines