This is a 100% Rust bootloader for the nRF9160 microcontroller written for Dutch IoT Solutions

Overview

nRF9160 Bootloader for Dutch IoT Solutions

This is a 100% Rust bootloader for the nRF9160 microcontroller written for Dutch IoT Solutions.

Currently, building this project requires a recent nightly compile because is relies on Embassy for the serial output.

Structure

The project is split in two:

  • shared: Exposes all types that both the bootloader and application needs to be able to access.
  • bootloader: The binary part of the project

Workings

The bootloader has four special memory regions which are defined in the memory.x file. There are two firmware slots, A & B, as well as a bootloader state area and some scratch space.

The bootloader will jump to the application in firmware slot A.

The application can fill slot B with an updated firmware. Then it needs to set the bootloader goal to either StartSwap or StartTestSwap and reboot. When the bootloader sees that it should swap the two firmware slots it will do that in a way so that any cut in power or reset will not lead to a currupt device.

+--------+          2.         +--------+
| Slot A |<--------------------+ Slot B |
|        |                     |        |
|        +-------+     +------>|        |
+--------+       |     |       +--------+
|        |    1. |     | 3.    |        |
|        |       |     |       |        |
|        |       |     |       |        |
+--------+       |     |       +--------+
|        |       |     |       |        |
|        |       |     |       |        |
|        |       |     |       |        |
+--------+       |     |       +--------+
|        |       |     |       |        |
|        |       |     |       |        |
|        |       |     |       |        |
+--------+       |     |       +--------+
|        |       |     |       |        |
|        |       |     |       |        |
|        |       |     |       |        |
+--------+       |     |       +--------+
|        |       |     |       |        |
|        |       |     |       |        |
|        |       |     |       |        |
+--------+       |     |       +--------+
                 v     |
               +-------+-+
               | Scratch |
               |         |
               +---------+
               |         |
               |         |
               +---------+
               |         |
               |         |
               +---------+

First a page of slot A is written to a scratch page. There are multiple scratch pages because flash will wear out when erased. The second step is to move the B page to the A slot. The third and final step is to move the page in scratch to the B slot.

The state of each page is written in the bootloader state without doing an erase. At every step of the way we know where each page is so that we can resume the swap at any point.

When the bootloader is done with everything it needs to jump to the application.

The address of the application is unknown still so it needs to be searched for. The bootloader will go through the memory of the firmware A slot word by word in search of the vector table.

If a word is 0xFFFF_FFFF or 0x0000_0000 then it is ignored because the assumption is that it is some kind of padding. The first word that is not ignored should be the initial stack pointer and the value is checked to see if it is located somewhere in RAM. If it is not, then the bootloader will panic and restart. The second word (the one after the initial stack pointer) should be the reset vector. It is checked that the reset vector lies somewhere in slot A. If it is not, the bootloader will panic and reboot.

So as long as the application has 'clean' padding, the application can be put anywhere in its slot. After the vector table, the image may have arbitrary data. There is no image header or trailer.

With the knowledge that the initial stack pointer and reset vector are ther, we can be quite sure that we've found a vector table.

All peripherals are reset and then the bootloader performs the bootload operation as part of the cortex-m crate.

Comments
  • application using embassy_time not working

    application using embassy_time not working

    An application using embassy_time and "time-driver-rtc1" from embassy-nrf crashes.

    (HOST) INFO  flashing program (8.71 KiB)
    (HOST) INFO  success!
    ────────────────────────────────────────────────────────────────────────────────
    ────────────────────────────────────────────────────────────────────────────────
    stack backtrace:
       0: HardFaultTrampoline
          <exception entry>
       1: _ZN4core3ptr13read_volatile17hd3f8821b78d6920fE
            at /rustc/8b705839cd656d202e920efa8769cbe43a5ee269/library/core/src/ptr/mod.rs:1474:9
       2: _ZN5vcell21VolatileCell$LT$T$GT$3get17h846ed7bb76a64525E
            at /Users/martin/.cargo/registry/src/github.com-1ecc6299db9ec823/vcell-0.1.3/src/lib.rs:33:18
       3: _ZN11nrf9160_pac7generic14Reg$LT$REG$GT$4read17h781ecf172b477ff2E
            at /Users/martin/.cargo/registry/src/github.com-1ecc6299db9ec823/nrf9160-pac-0.11.0/src/generic.rs:65:19
       4: _ZN84_$LT$embassy_nrf..time_driver..RtcDriver$u20$as$u20$embassy_time..driver..Driver$GT$3now17h4e33ced8e698ee26E
            at /Users/martin/.cargo/git/checkouts/embassy-9312dcb0ed774b29/d49d1b6/embassy-nrf/src/time_driver.rs:218:23
       5: _embassy_time_now
            at /Users/martin/.cargo/git/checkouts/embassy-9312dcb0ed774b29/d49d1b6/embassy-time/src/driver.rs:156:13
       6: _ZN12embassy_time6driver3now17hf91ab4d33d5c6c11E
            at /Users/martin/.cargo/git/checkouts/embassy-9312dcb0ed774b29/d49d1b6/embassy-time/src/driver.rs:126:14
       7: _ZN12embassy_time7instant7Instant3now17h0483671508ea8743E
            at /Users/martin/.cargo/git/checkouts/embassy-9312dcb0ed774b29/d49d1b6/embassy-time/src/instant.rs:21:26
       8: _ZN16embassy_executor3raw8Executor4poll17h42b4164cf3414afbE
            at /Users/martin/.cargo/git/checkouts/embassy-9312dcb0ed774b29/d49d1b6/embassy-executor/src/raw/mod.rs:358:42
       9: _ZN16embassy_executor4arch8Executor3run17hb54781054eaf4739E
            at /Users/martin/.cargo/git/checkouts/embassy-9312dcb0ed774b29/d49d1b6/embassy-executor/src/arch/cortex_m.rs:54:17
      10: _ZN7bateman18__cortex_m_rt_main17hf74310984f680484E
            at src/main.rs:12:1
      11: main
            at src/main.rs:12:1
      12: Reset
    (HOST) ERROR the program panicked
    

    If I run it without any time features it works.

    opened by macthestack 5
  • Update nightly version, update embassy

    Update nightly version, update embassy

    For now, this yields some linker issues. The produced binary is too large to fit into the FLASH region. Temporarily increasing its size to 100K in order to be able to run cargo size, the linker gives:

    [...]
    rust-lld: error: undefined symbol: _critical_section_1_0_acquire
    [...]
    rust-lld: error: undefined symbol: _critical_section_1_0_release
    [..]
    
    opened by hdoordt 2
  • Vector table is not changed

    Vector table is not changed

    We use the cortex m bootload function: https://github.com/tweedegolf/dis-bootloader/blob/4741e294239b370745c81ddd9afb08da6a9a7ba3/bootloader/src/main.rs#L371 But that doesn't change the vector table. We should do that.

    opened by diondokter 2
  • Project doesn't build anymore on newer compiler versions

    Project doesn't build anymore on newer compiler versions

    We're getting:

    error: opaque type's hidden type cannot be another opaque type from the same scope
      --> bootloader/src/main.rs:34:1
       |
    34 | #[embassy::main]
       | ^^^^^^^^^^^^^^^^ one of the two opaque types used here has to be outside its defining scope
       |
    note: opaque type whose hidden type is being assigned
      --> bootloader/src/main.rs:34:1
       |
    34 | #[embassy::main]
       | ^^^^^^^^^^^^^^^^
    note: opaque type being used as hidden type
      --> bootloader/src/main.rs:34:1
       |
    34 | #[embassy::main]
       | ^^^^^^^^^^^^^^^^
       = note: this error originates in the attribute macro `::embassy::task` (in Nightly builds, run with -Z macro-backtrace for more info)
    

    Probably need to update to a newer version of Embassy

    opened by diondokter 0
  • Update the page swapping so no scratch space is required

    Update the page swapping so no scratch space is required

    Suggestion by Dirbaio:

    There's one trick to swap without needing scratch space, just needs slot B to be 1 page bigger.

    [ABC] [abc.]
    [ABC] [abcC]
    [ABc] [abcC]
    [ABc] [abBC]
    [Abc] [abBC]
    [Abc] [aABC]
    [abc] [aABC]
    [abc] [.ABC]
    

    Needs "moving" each page just once, and each page gets written just once (so if your flash can do 10k erases you can do 10k swaps, with scratch you can do less because you're "concentrating" many erases into the scratch pages). After swap slot B is "shifted" by 1, so you need to do the "unswap" in the reverse order to account for that.

    opened by diondokter 0
Owner
Tweede golf
Tweede golf
Write Cloudflare Workers in 100% Rust via WebAssembly. (A fork of workers-rs)

Note: This is a fork to workers-rs. Work-in-progress ergonomic Rust bindings to Cloudflare Workers environment. Write your entire worker in Rust! Read

Abid Omar 7 Jan 11, 2023
Solutions of Advent of Code 2021 in Rust, and some other languages.

advent-of-rust Solutions of Advent of Code 2021 in Rust, and some other languages. Puzzles Puzzle Stars Languages Day 1: Sonar Sweep ⭐ ⭐ Rust Python D

rene-d 6 Jan 7, 2023
A highly modular Bitcoin Lightning library written in Rust. Its Rust-Lightning, not Rusty's Lightning!

Rust-Lightning is a Bitcoin Lightning library written in Rust. The main crate, lightning, does not handle networking, persistence, or any other I/O. Thus, it is runtime-agnostic, but users must implement basic networking logic, chain interactions, and disk storage. More information is available in the About section.

Lightning Dev Kit 850 Jan 3, 2023
A language server for lua written in rust

lua-analyzer lua-analyzer is a lsp server for lua. This is mostly for me to learn the lsp protocol and language analysis so suggestions are helpful. T

null 61 Dec 11, 2022
Opensource diagnostic software for Daimler vehicles, inspired by Xentry and DAS, written in Rust

OPENSTAR An opensource diagnostic application for Daimler vehicles inspired by DAS and Xentry. Some of the work here is based on OpenVehicleDiag If yo

Ashcon Mohseninia 21 Nov 20, 2022
Benchmarking web frameworks written in rust with rewrk tool.

Web Framework Benchmarks Benchmarking web frameworks written in rust with rewrk tool.

null 103 Dec 8, 2022
Yet another ROS2 client library written in Rust

RclRust Target CI Status Document Foxy (Ubuntu 20.04) Introduction This is yet another ROS2 client library written in Rust. I have implemented it inde

rclrust 42 Dec 1, 2022
A little bit fast and modern Ruby version manager written in Rust

A little bit fast and modern Ruby version manager written in Rust Features Pure Rust implementation not using ruby-build Cross-platform support (macOS

Takayuki Maeda 510 Jan 5, 2023
Music bot written in Rust

Akasuki What is Akasuki? Akasuki is a simple discord music bot written in rust. Highlights Select your music using discord's new select menu feature,

Forbidden A 0 Dec 19, 2021
A Discord bot for sending GeoGuessr challenge links that uses the GeoGuessr API written in rust.

GeoGuessr-bot-rs This is a simple implementation of a discord bot that send GeoGuessr-challenge links on demand. Features: Slash-commands Lightning-fa

Luukas Pörtfors 6 Nov 18, 2022
Some tools for streaming frames to rpi-rgb-led-matrix using ZeroMQ, written in Rust.

led_matrix_zmq Some tools for streaming frames to rpi-rgb-led-matrix using ZeroMQ, written in Rust. This repository includes: Rust client and server l

Dan 2 Sep 6, 2022
A gui api explorer written in Rust.

Zzz - GUI Api platform Pronounced "Zees"; as in "catching some Z's". A pun on RESTful APIs. example URL: https://jsonplaceholder.typicode.com/todos/ T

Ryan Blecher 0 Nov 11, 2021
Cross-platform GUI written in Rust using ADB to debloat non-rooted android devices

Cross-platform GUI written in Rust using ADB to debloat non-rooted android devices. Improve your privacy, the security and battery life of your device.

w1nst0n 6.8k Jan 2, 2023
A variation of the solana helloworld program example with a client written in Rust instead of Typescript

Simple Solana Smart Contract Example This repository demonstrates how to create and invoke a program on the Solana blockchain. In Solana the word prog

zeke 56 Dec 26, 2022
A powerful minecraft bedrock software written in Rust with a powerful Typescript plugin API.

Netrex A powerful minecraft bedrock software written in RustLang. Why Netrex? It's written in Rust. Unique and straight to the point. Typescript Plugi

Netrex 51 Dec 26, 2022
Unofficial Bitwarden compatible server written in Rust, formerly known as bitwarden_rs

Alternative implementation of the Bitwarden server API written in Rust and compatible with upstream Bitwarden clients*, perfect for self-hosted deploy

Daniel García 21.5k Jan 8, 2023
oreboot is a fork of coreboot, with C removed, written in Rust.

oreboot is a downstream fork of coreboot, i.e. oreboot is coreboot without 'c'.

null 1.2k Jan 2, 2023
s3d is an S3 daemon for the Edge written in Rust

s3d is an S3 daemon for the Edge written in Rust The goal of s3d is to provide a daemon for edge platforms (e.g. factory servers ?? planes ?? ships ??

null 36 Dec 27, 2022
TAT agent is an agent written in Rust, which run in CVM or Lighthouse instances.

TAT agent is an agent written in Rust, which run in CVM, Lighthouse or CPM 2.0 instances. Its role is to run commands remotely without ssh login, invoked from TencentCloud Console/API. Commands include but not limited to: Shell, PowerShell, Python. TAT stands for TencentCloud Automation Tools. See more info at https://cloud.tencent.com/product/tat.

Tencent 97 Dec 21, 2022