Added third stage bootloader

This commit is contained in:
Dreaded_X 2023-09-02 05:28:51 +02:00
parent ff40ad796f
commit 831f180046
Signed by: Dreaded_X
GPG Key ID: FA5F485356B0D2D4
9 changed files with 272 additions and 67 deletions

View File

@ -1,3 +1,7 @@
[unstable]
build-std = ["core"]
build-std-features = ["panic_immediate_abort"]
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
runner = "probe-rs run --chip RP2040"

153
Cargo.lock generated
View File

@ -4,9 +4,9 @@ version = 3
[[package]]
name = "aho-corasick"
version = "1.0.4"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6748e8def348ed4d14996fa801f4122cd763fff530258cdc03f64b25f89d3a5a"
checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783"
dependencies = [
"memchr",
]
@ -131,6 +131,31 @@ version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
[[package]]
name = "block-buffer"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
"generic-array 0.14.7",
]
[[package]]
name = "bootloader"
version = "0.1.0"
dependencies = [
"cortex-m",
"cortex-m-rt",
"defmt",
"defmt-rtt",
"embassy-boot-rp",
"embassy-rp",
"embassy-sync",
"embassy-time",
"embedded-storage",
"embedded-storage-async",
]
[[package]]
name = "bytemuck"
version = "1.13.1"
@ -176,6 +201,7 @@ checksum = "8ec610d8f49840a5b376c69663b6369e71f4b34484b9b2eb29fb918d92516cb9"
dependencies = [
"bare-metal",
"bitfield",
"critical-section",
"embedded-hal 0.2.7",
"volatile-register",
]
@ -227,10 +253,20 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
[[package]]
name = "crypto-common"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [
"generic-array 0.14.7",
"typenum",
]
[[package]]
name = "cyw43"
version = "0.1.0"
source = "git+https://github.com/embassy-rs/embassy#f8299d10f7c0387416989e00acc02d99661537fb"
source = "git+https://github.com/embassy-rs/embassy#9d8c527308522698bfb6596bdb67bec826e0fb5a"
dependencies = [
"atomic-polyfill 0.1.11",
"cortex-m",
@ -248,7 +284,7 @@ dependencies = [
[[package]]
name = "cyw43-pio"
version = "0.1.0"
source = "git+https://github.com/embassy-rs/embassy#f8299d10f7c0387416989e00acc02d99661537fb"
source = "git+https://github.com/embassy-rs/embassy#9d8c527308522698bfb6596bdb67bec826e0fb5a"
dependencies = [
"cyw43",
"defmt",
@ -347,6 +383,16 @@ version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"crypto-common",
]
[[package]]
name = "dirs-next"
version = "2.0.0"
@ -390,10 +436,39 @@ version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
[[package]]
name = "embassy-boot"
version = "0.1.1"
source = "git+https://github.com/embassy-rs/embassy#9d8c527308522698bfb6596bdb67bec826e0fb5a"
dependencies = [
"defmt",
"digest",
"embassy-embedded-hal",
"embassy-sync",
"embedded-storage",
"signature",
]
[[package]]
name = "embassy-boot-rp"
version = "0.1.0"
source = "git+https://github.com/embassy-rs/embassy#9d8c527308522698bfb6596bdb67bec826e0fb5a"
dependencies = [
"cfg-if",
"cortex-m",
"cortex-m-rt",
"defmt",
"embassy-boot",
"embassy-rp",
"embassy-sync",
"embassy-time",
"embedded-storage",
]
[[package]]
name = "embassy-embedded-hal"
version = "0.1.0"
source = "git+https://github.com/embassy-rs/embassy#f8299d10f7c0387416989e00acc02d99661537fb"
source = "git+https://github.com/embassy-rs/embassy#9d8c527308522698bfb6596bdb67bec826e0fb5a"
dependencies = [
"embassy-futures",
"embassy-sync",
@ -409,7 +484,7 @@ dependencies = [
[[package]]
name = "embassy-executor"
version = "0.3.0"
source = "git+https://github.com/embassy-rs/embassy#f8299d10f7c0387416989e00acc02d99661537fb"
source = "git+https://github.com/embassy-rs/embassy#9d8c527308522698bfb6596bdb67bec826e0fb5a"
dependencies = [
"atomic-polyfill 1.0.3",
"cortex-m",
@ -424,7 +499,7 @@ dependencies = [
[[package]]
name = "embassy-futures"
version = "0.1.0"
source = "git+https://github.com/embassy-rs/embassy#f8299d10f7c0387416989e00acc02d99661537fb"
source = "git+https://github.com/embassy-rs/embassy#9d8c527308522698bfb6596bdb67bec826e0fb5a"
dependencies = [
"defmt",
]
@ -432,7 +507,7 @@ dependencies = [
[[package]]
name = "embassy-hal-internal"
version = "0.1.0"
source = "git+https://github.com/embassy-rs/embassy#f8299d10f7c0387416989e00acc02d99661537fb"
source = "git+https://github.com/embassy-rs/embassy#9d8c527308522698bfb6596bdb67bec826e0fb5a"
dependencies = [
"cortex-m",
"critical-section",
@ -443,7 +518,7 @@ dependencies = [
[[package]]
name = "embassy-macros"
version = "0.2.1"
source = "git+https://github.com/embassy-rs/embassy#f8299d10f7c0387416989e00acc02d99661537fb"
source = "git+https://github.com/embassy-rs/embassy#9d8c527308522698bfb6596bdb67bec826e0fb5a"
dependencies = [
"darling",
"proc-macro2",
@ -454,7 +529,7 @@ dependencies = [
[[package]]
name = "embassy-net"
version = "0.1.0"
source = "git+https://github.com/embassy-rs/embassy#f8299d10f7c0387416989e00acc02d99661537fb"
source = "git+https://github.com/embassy-rs/embassy#9d8c527308522698bfb6596bdb67bec826e0fb5a"
dependencies = [
"as-slice 0.2.1",
"atomic-polyfill 1.0.3",
@ -476,7 +551,7 @@ dependencies = [
[[package]]
name = "embassy-net-driver"
version = "0.1.0"
source = "git+https://github.com/embassy-rs/embassy#f8299d10f7c0387416989e00acc02d99661537fb"
source = "git+https://github.com/embassy-rs/embassy#9d8c527308522698bfb6596bdb67bec826e0fb5a"
dependencies = [
"defmt",
]
@ -484,7 +559,7 @@ dependencies = [
[[package]]
name = "embassy-net-driver-channel"
version = "0.1.0"
source = "git+https://github.com/embassy-rs/embassy#f8299d10f7c0387416989e00acc02d99661537fb"
source = "git+https://github.com/embassy-rs/embassy#9d8c527308522698bfb6596bdb67bec826e0fb5a"
dependencies = [
"embassy-futures",
"embassy-net-driver",
@ -494,7 +569,7 @@ dependencies = [
[[package]]
name = "embassy-rp"
version = "0.1.0"
source = "git+https://github.com/embassy-rs/embassy#f8299d10f7c0387416989e00acc02d99661537fb"
source = "git+https://github.com/embassy-rs/embassy#9d8c527308522698bfb6596bdb67bec826e0fb5a"
dependencies = [
"atomic-polyfill 1.0.3",
"cfg-if",
@ -530,7 +605,7 @@ dependencies = [
[[package]]
name = "embassy-sync"
version = "0.2.0"
source = "git+https://github.com/embassy-rs/embassy#f8299d10f7c0387416989e00acc02d99661537fb"
source = "git+https://github.com/embassy-rs/embassy#9d8c527308522698bfb6596bdb67bec826e0fb5a"
dependencies = [
"cfg-if",
"critical-section",
@ -541,8 +616,8 @@ dependencies = [
[[package]]
name = "embassy-time"
version = "0.1.2"
source = "git+https://github.com/embassy-rs/embassy#f8299d10f7c0387416989e00acc02d99661537fb"
version = "0.1.3"
source = "git+https://github.com/embassy-rs/embassy#9d8c527308522698bfb6596bdb67bec826e0fb5a"
dependencies = [
"atomic-polyfill 1.0.3",
"cfg-if",
@ -558,7 +633,7 @@ dependencies = [
[[package]]
name = "embassy-usb"
version = "0.1.0"
source = "git+https://github.com/embassy-rs/embassy#f8299d10f7c0387416989e00acc02d99661537fb"
source = "git+https://github.com/embassy-rs/embassy#9d8c527308522698bfb6596bdb67bec826e0fb5a"
dependencies = [
"defmt",
"embassy-futures",
@ -573,7 +648,7 @@ dependencies = [
[[package]]
name = "embassy-usb-driver"
version = "0.1.0"
source = "git+https://github.com/embassy-rs/embassy#f8299d10f7c0387416989e00acc02d99661537fb"
source = "git+https://github.com/embassy-rs/embassy#9d8c527308522698bfb6596bdb67bec826e0fb5a"
dependencies = [
"defmt",
]
@ -693,9 +768,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "errno"
version = "0.3.2"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f"
checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd"
dependencies = [
"errno-dragonfly",
"libc",
@ -996,9 +1071,9 @@ checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d"
[[package]]
name = "memchr"
version = "2.5.0"
version = "2.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
checksum = "5486aed0026218e61b8a01d5fbd5a0a134649abb71a0e53b7bc088529dced86e"
[[package]]
name = "nb"
@ -1283,25 +1358,25 @@ dependencies = [
[[package]]
name = "regex"
version = "1.9.3"
version = "1.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81bc1d4caf89fac26a70747fe603c130093b53c773888797a6329091246d651a"
checksum = "12de2eff854e5fa4b1295edd650e227e9d8fb0c9e90b12e7f36d6a6811791a29"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax 0.7.4",
"regex-syntax 0.7.5",
]
[[package]]
name = "regex-automata"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69"
checksum = "49530408a136e16e5b486e883fbb6ba058e8e4e8ae6621a77b048b314336e629"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax 0.7.4",
"regex-syntax 0.7.5",
]
[[package]]
@ -1312,9 +1387,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
[[package]]
name = "regex-syntax"
version = "0.7.4"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2"
checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
[[package]]
name = "rp"
@ -1396,9 +1471,9 @@ dependencies = [
[[package]]
name = "rustix"
version = "0.38.9"
version = "0.38.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9bfe0f2582b4931a45d1fa608f8a8722e8b3c7ac54dd6d5f3b3212791fedef49"
checksum = "c0c3dde1fc030af041adc40e79c0e7fbcf431dd24870053d187d7c66e4b87453"
dependencies = [
"bitflags 2.4.0",
"errno",
@ -1448,9 +1523,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "serde"
version = "1.0.187"
version = "1.0.188"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30a7fe14252655bd1e578af19f5fa00fe02fd0013b100ca6b49fde31c41bae4c"
checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e"
dependencies = [
"serde_derive",
]
@ -1468,15 +1543,21 @@ dependencies = [
[[package]]
name = "serde_derive"
version = "1.0.187"
version = "1.0.188"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e46b2a6ca578b3f1d4501b12f78ed4692006d79d82a1a7c561c12dbc3d625eb8"
checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.29",
]
[[package]]
name = "signature"
version = "1.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c"
[[package]]
name = "siphasher"
version = "0.3.11"

View File

@ -3,7 +3,8 @@ name = "rp"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[workspace]
members = ["bootloader"]
[dependencies]
cortex-m = { version = "0.7", features = ["inline-asm"] }
@ -78,6 +79,8 @@ embassy-net = { git = "https://github.com/embassy-rs/embassy" }
embassy-sync = { git = "https://github.com/embassy-rs/embassy" }
embassy-futures = { git = "https://github.com/embassy-rs/embassy" }
embassy-boot-rp = { git = "https://github.com/embassy-rs/embassy" }
rust-mqtt = { path = "../rust-mqtt" }
[build-dependencies]
@ -90,3 +93,4 @@ exclude_firmwares = []
[profile.release]
debug = true
opt-level = 's'

25
bootloader/Cargo.toml Normal file
View File

@ -0,0 +1,25 @@
[package]
name = "bootloader"
version = "0.1.0"
edition = "2021"
[dependencies]
defmt = { version = "0.3", optional = true }
defmt-rtt = { version = "0.4", optional = true }
embassy-rp = { version = "0.1", features = ["nightly"] }
embassy-boot-rp = { version = "0.1" }
embassy-sync = { version = "0.2" }
embassy-time = { version = "0.1", features = ["nightly"] }
cortex-m = { version = "0.7", features = [
"inline-asm",
"critical-section-single-core",
] }
cortex-m-rt = { version = "0.7" }
embedded-storage = "0.3.0"
embedded-storage-async = "0.4.0"
[features]
defmt = ["dep:defmt", "embassy-boot-rp/defmt", "embassy-rp/defmt"]
debug = ["defmt-rtt", "defmt"]

36
bootloader/build.rs Normal file
View File

@ -0,0 +1,36 @@
use std::env;
use std::fs::File;
use std::io::Write;
use std::path::PathBuf;
fn main() {
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
// By default cortex-m-rt expects memory.x, however this causes issues with workspaces as it
// will pick the first file that is found.
// In order to get around this we make a dummy memory.x file
File::create(out.join("memory.x")).unwrap();
// Use memory.x.in as a template for the actual memory.x
let memory = include_str!("../memory.x.in")
.replace("{BOOTLOADER}", "FLASH")
.replace("{ACTIVE}", "ACTIVE");
// And then include it with a unique name
File::create(out.join("memory_boot.x"))
.unwrap()
.write_all(memory.as_bytes())
.unwrap();
println!("cargo:rustc-link-search={}", out.display());
println!("cargo:rerun-if-changed=../memory.x.in");
// And link with that one
println!("cargo:rustc-link-arg-bins=-Tmemory_boot.x");
println!("cargo:rustc-link-arg-bins=--nmagic");
println!("cargo:rustc-link-arg-bins=-Tlink.x");
println!("cargo:rustc-link-arg-bins=-Tlink-rp.x");
if env::var("CARGO_FEATURE_DEFMT").is_ok() {
println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
}
}

46
bootloader/src/main.rs Normal file
View File

@ -0,0 +1,46 @@
#![no_std]
#![no_main]
use core::cell::RefCell;
use cortex_m_rt::{entry, exception};
#[cfg(feature = "defmt")]
use defmt_rtt as _;
use embassy_boot_rp::*;
use embassy_rp::flash::{Blocking, Flash};
use embassy_sync::blocking_mutex::Mutex;
const FLASH_SIZE: usize = 2 * 1024 * 1024;
#[entry]
fn main() -> ! {
let p = embassy_rp::init(Default::default());
let flash = Flash::<_, Blocking, FLASH_SIZE>::new_blocking(p.FLASH);
let flash = Mutex::new(RefCell::new(flash));
let config = BootLoaderConfig::from_linkerfile_blocking(&flash);
let active_offset = config.active.offset();
let bl: BootLoader = BootLoader::prepare(config);
unsafe { bl.load(embassy_rp::flash::FLASH_BASE as u32 + active_offset) }
}
#[no_mangle]
#[cfg_attr(target_os = "none", link_section = ".HardFault.user")]
unsafe extern "C" fn HardFault() {
cortex_m::peripheral::SCB::sys_reset();
}
#[exception]
unsafe fn DefaultHandler(_: i16) -> ! {
const SCB_ICSR: *const u32 = 0xE000_ED04 as *const u32;
let irqn = core::ptr::read_volatile(SCB_ICSR) as u8 as i16 - 16;
panic!("DefaultHandler #{:?}", irqn);
}
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
cortex_m::asm::udf();
}

View File

@ -1,37 +1,34 @@
//! This build script copies the `memory.x` file from the crate root into
//! a directory where the linker can always find it at build time.
//! For many projects this is optional, as the linker always searches the
//! project root directory -- wherever `Cargo.toml` is. However, if you
//! are using a workspace or have a more complicated build setup, this
//! build script becomes required. Additionally, by requesting that
//! Cargo re-run the build script whenever `memory.x` is changed,
//! updating `memory.x` ensures a rebuild of the application with the
//! new memory settings.
use std::env;
use std::fs::File;
use std::io::Write;
use std::path::PathBuf;
fn main() {
// Put `memory.x` in our output directory and ensure it's
// on the linker search path.
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
File::create(out.join("memory.x"))
// By default cortex-m-rt expects memory.x, however this causes issues with workspaces as it
// will pick the first file that is found.
// In order to get around this we make a dummy memory.x file
File::create(out.join("memory.x")).unwrap();
// Use memory.x.in as a template for the actual memory.x
let memory = include_str!("memory.x.in")
.replace("{BOOTLOADER}", "BOOTLOADER")
.replace("{ACTIVE}", "FLASH");
// And then include it with a unique name
File::create(out.join("memory_app.x"))
.unwrap()
.write_all(include_bytes!("memory.x"))
.write_all(memory.as_bytes())
.unwrap();
println!("cargo:rustc-link-search={}", out.display());
println!("cargo:rerun-if-changed=memory.x.in");
// By default, Cargo will re-run a build script whenever
// any file in the project changes. By specifying `memory.x`
// here, we ensure the build script is only re-run when
// `memory.x` is changed.
println!("cargo:rerun-if-changed=memory.x");
// And link with that one
println!("cargo:rustc-link-arg-bins=-Tmemory_app.x");
println!("cargo:rustc-link-arg-bins=--nmagic");
println!("cargo:rustc-link-arg-bins=-Tlink.x");
println!("cargo:rustc-link-arg-bins=-Tlink-rp.x");
println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
if let Ok(dotenv_path) = dotenvy::dotenv() {

View File

@ -1,10 +0,0 @@
MEMORY {
BOOT2 : ORIGIN = 0x10000000, LENGTH = 0x100
FLASH : ORIGIN = 0x10000100, LENGTH = 2048K - 0x100 - 256k -8k
FW : ORIGIN = 0x101BE000, LENGTH = 256k
CLM : ORIGIN = 0x101FE000, LENGTH = 8k
RAM : ORIGIN = 0x20000000, LENGTH = 256K
}
__fw_start = ORIGIN(FW);
__clm_start = ORIGIN(CLM);

22
memory.x.in Normal file
View File

@ -0,0 +1,22 @@
MEMORY {
BOOT2 : ORIGIN = 0x10000000, LENGTH = 0x100
{BOOTLOADER} : ORIGIN = 0x10000100, LENGTH = 24k - 0x100
BOOTLOADER_STATE : ORIGIN = 0x10006000, LENGTH = 4k
{ACTIVE} : ORIGIN = 0x10007000, LENGTH = 876k
DFU : ORIGIN = 0x100E2000, LENGTH = 880k
FW : ORIGIN = 0x101BE000, LENGTH = 256k
CLM : ORIGIN = 0x101FE000, LENGTH = 8k
RAM : ORIGIN = 0x20000000, LENGTH = 264K
}
__bootloader_state_start = ORIGIN(BOOTLOADER_STATE) - ORIGIN(BOOT2);
__bootloader_state_end = ORIGIN(BOOTLOADER_STATE) + LENGTH(BOOTLOADER_STATE) - ORIGIN(BOOT2);
__bootloader_active_start = ORIGIN({ACTIVE}) - ORIGIN(BOOT2);
__bootloader_active_end = ORIGIN({ACTIVE}) + LENGTH({ACTIVE}) - ORIGIN(BOOT2);
__bootloader_dfu_start = ORIGIN(DFU) - ORIGIN(BOOT2);
__bootloader_dfu_end = ORIGIN(DFU) + LENGTH(DFU) - ORIGIN(BOOT2);
__fw_start = ORIGIN(FW);
__clm_start = ORIGIN(CLM);