From 8e18068d783bebed9908d1a6707073d3698ca40a Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Mon, 31 Jul 2023 18:43:14 -0400 Subject: [PATCH 01/31] build.rs: pass FLASH and RAM to create .ld --- runtime/build.rs | 43 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/runtime/build.rs b/runtime/build.rs index 0e3561e0..3861c1e5 100644 --- a/runtime/build.rs +++ b/runtime/build.rs @@ -5,14 +5,17 @@ #[cfg(not(feature = "no_auto_layout"))] fn auto_layout() { use std::fs::copy; + use std::fs::File; + use std::io::Write; use std::path::PathBuf; - const PLATFORM_CFG_VAR: &str = "LIBTOCK_PLATFORM"; + const LINKER_FLASH_CFG_VAR: &str = "LINKER_FLASH"; + const LINKER_RAM_CFG_VAR: &str = "LINKER_RAM"; const LAYOUT_GENERIC_FILENAME: &str = "libtock_layout.ld"; // Note: we need to print these rerun-if commands before using the variable // or file, so that if the build script fails cargo knows when to re-run it. - println!("cargo:rerun-if-env-changed={}", PLATFORM_CFG_VAR); + // println!("cargo:rerun-if-env-changed={}", PLATFORM_CFG_VAR); // Read configuration from environment variables. @@ -28,15 +31,37 @@ fn auto_layout() { // Read the platform environment variable as a String (our platform names // should all be valid UTF-8). - let platform = std::env::var(PLATFORM_CFG_VAR).expect("Please specify LIBTOCK_PLATFORM"); + let linker_flash = std::env::var(LINKER_FLASH_CFG_VAR).expect("Please specify LINKER_FLASH"); + let linker_ram = std::env::var(LINKER_RAM_CFG_VAR).expect("Please specify LINKER_RAM"); - // Copy the platform-specific layout file into OUT_DIR. - let platform_filename = format!("{}.ld", platform); - let platform_path: PathBuf = ["layouts", &platform_filename].iter().collect(); - println!("cargo:rerun-if-changed={}", platform_path.display()); - assert!(platform_path.exists(), "Unknown platform {}", platform); + // Create a valid linker file with the specified flash and ram locations. + // + // ``` + // MEMORY { + // FLASH (X) : ORIGIN = $LINKER_FLASH, LENGTH = 0x000D0000 + // RAM (W) : ORIGIN = $LINKER_RAM, LENGTH = 46K + // } + // TBF_HEADER_SIZE = 0x60; + // INCLUDE libtock_layout.ld + // ``` let out_platform_path: PathBuf = [out_dir, "layout.ld"].iter().collect(); - copy(&platform_path, out_platform_path).expect("Unable to copy platform layout into OUT_DIR"); + let mut file = File::create(out_platform_path).expect("Could not create linker file"); + write!(file, "MEMORY {{\n").expect("Could not write linker file"); + write!( + file, + " FLASH (X) : ORIGIN = {}, LENGTH = 0x000D0000\n", + linker_flash + ) + .expect("Could not write linker file"); + write!( + file, + " RAM (X) : ORIGIN = {}, LENGTH = 46k\n", + linker_ram + ) + .expect("Could not write linker file"); + write!(file, "}}\n").expect("Could not write linker file"); + write!(file, "TBF_HEADER_SIZE = 0x60;\n").expect("Could not write linker file"); + write!(file, "INCLUDE libtock_layout.ld\n").expect("Could not write linker file"); // Copy the generic layout file into OUT_DIR. let out_layout_generic: PathBuf = [out_dir, LAYOUT_GENERIC_FILENAME].iter().collect(); From eccf105775d37afadd51fd6e616a75564de77510 Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Mon, 31 Jul 2023 18:44:50 -0400 Subject: [PATCH 02/31] make: make tab builds multiple tbfs Specifies ram and flash addresses and creates a TAB. --- Makefile | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Makefile b/Makefile index 8a9f30fe..3cb63c7f 100644 --- a/Makefile +++ b/Makefile @@ -127,6 +127,21 @@ test: examples test-stable cargo miri test $(EXCLUDE_MIRI) --workspace echo '[ SUCCESS ] libtock-rs tests pass' +.PHONY: tab +tab: + mkdir -p target/$(EXAMPLE) + LINKER_FLASH=0x00040000 LINKER_RAM=0x20008000 cargo build --example $(EXAMPLE) $(features) --target=thumbv7em-none-eabi $(release) + cp target/thumbv7em-none-eabi/release/examples/$(EXAMPLE) target/$(EXAMPLE)/cortex-m4.0x00040000.0x20008000.elf + LINKER_FLASH=0x00042000 LINKER_RAM=0x2000a000 cargo build --example $(EXAMPLE) $(features) --target=thumbv7em-none-eabi $(release) + cp target/thumbv7em-none-eabi/release/examples/$(EXAMPLE) target/$(EXAMPLE)/cortex-m4.0x00042000.0x2000a000.elf + LINKER_FLASH=0x00048000 LINKER_RAM=0x20010000 cargo build --example $(EXAMPLE) $(features) --target=thumbv7em-none-eabi $(release) + cp target/thumbv7em-none-eabi/release/examples/$(EXAMPLE) target/$(EXAMPLE)/cortex-m4.0x00048000.0x20010000.elf + + elf2tab --kernel-major 2 --kernel-minor 0 -n $(EXAMPLE) -o $(EXAMPLE).tab --protected-region-size 96 --stack 1024 \ + target/$(EXAMPLE)/cortex-m4.0x00040000.0x20008000.elf \ + target/$(EXAMPLE)/cortex-m4.0x00042000.0x2000a000.elf \ + target/$(EXAMPLE)/cortex-m4.0x00048000.0x20010000.elf \ + # Creates the `make EXAMPLE=` targets. Arguments: # 1) The name of the platform to build for. # From 852e5cfd23122617cd177197fd52f990dfa4df26 Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Mon, 31 Jul 2023 21:50:02 -0400 Subject: [PATCH 03/31] rerun on flash/ram variable change --- runtime/build.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/runtime/build.rs b/runtime/build.rs index 3861c1e5..06708469 100644 --- a/runtime/build.rs +++ b/runtime/build.rs @@ -15,7 +15,8 @@ fn auto_layout() { // Note: we need to print these rerun-if commands before using the variable // or file, so that if the build script fails cargo knows when to re-run it. - // println!("cargo:rerun-if-env-changed={}", PLATFORM_CFG_VAR); + println!("cargo:rerun-if-env-changed={}", LINKER_FLASH_CFG_VAR); + println!("cargo:rerun-if-env-changed={}", LINKER_RAM_CFG_VAR); // Read configuration from environment variables. From d789d470151adff0a51d62057dd7a42856ec7e8d Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Mon, 31 Jul 2023 22:38:02 -0400 Subject: [PATCH 04/31] make: remove --protected-region-size flag --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 3cb63c7f..beae2cd7 100644 --- a/Makefile +++ b/Makefile @@ -137,7 +137,7 @@ tab: LINKER_FLASH=0x00048000 LINKER_RAM=0x20010000 cargo build --example $(EXAMPLE) $(features) --target=thumbv7em-none-eabi $(release) cp target/thumbv7em-none-eabi/release/examples/$(EXAMPLE) target/$(EXAMPLE)/cortex-m4.0x00048000.0x20010000.elf - elf2tab --kernel-major 2 --kernel-minor 0 -n $(EXAMPLE) -o $(EXAMPLE).tab --protected-region-size 96 --stack 1024 \ + elf2tab --kernel-major 2 --kernel-minor 0 -n $(EXAMPLE) -o $(EXAMPLE).tab --stack 1024 \ target/$(EXAMPLE)/cortex-m4.0x00040000.0x20008000.elf \ target/$(EXAMPLE)/cortex-m4.0x00042000.0x2000a000.elf \ target/$(EXAMPLE)/cortex-m4.0x00048000.0x20010000.elf \ From 26d11d610e90cf02e5ed9197b67cbf929c80de5c Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Mon, 31 Jul 2023 22:38:32 -0400 Subject: [PATCH 05/31] build.rs: update to new linker format --- runtime/build.rs | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/runtime/build.rs b/runtime/build.rs index 06708469..04159d9a 100644 --- a/runtime/build.rs +++ b/runtime/build.rs @@ -38,30 +38,23 @@ fn auto_layout() { // Create a valid linker file with the specified flash and ram locations. // // ``` - // MEMORY { - // FLASH (X) : ORIGIN = $LINKER_FLASH, LENGTH = 0x000D0000 - // RAM (W) : ORIGIN = $LINKER_RAM, LENGTH = 46K - // } // TBF_HEADER_SIZE = 0x60; + // + // FLASH_START = 0x00040000; + // FLASH_LENGTH = 0x00040000; + // + // RAM_START = 0x20008000; + // RAM_LENGTH = 62K; + // // INCLUDE libtock_layout.ld // ``` let out_platform_path: PathBuf = [out_dir, "layout.ld"].iter().collect(); let mut file = File::create(out_platform_path).expect("Could not create linker file"); - write!(file, "MEMORY {{\n").expect("Could not write linker file"); - write!( - file, - " FLASH (X) : ORIGIN = {}, LENGTH = 0x000D0000\n", - linker_flash - ) - .expect("Could not write linker file"); - write!( - file, - " RAM (X) : ORIGIN = {}, LENGTH = 46k\n", - linker_ram - ) - .expect("Could not write linker file"); - write!(file, "}}\n").expect("Could not write linker file"); write!(file, "TBF_HEADER_SIZE = 0x60;\n").expect("Could not write linker file"); + write!(file, "FLASH_START = {};\n", linker_flash).expect("Could not write linker file"); + write!(file, "FLASH_LENGTH = 0x000D0000;\n",).expect("Could not write linker file"); + write!(file, "RAM_START = {};\n", linker_ram).expect("Could not write linker file"); + write!(file, "RAM_LENGTH = 46K;\n",).expect("Could not write linker file"); write!(file, "INCLUDE libtock_layout.ld\n").expect("Could not write linker file"); // Copy the generic layout file into OUT_DIR. From bff74a23aef0f83315ad47f677eba6fdbba55793 Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Mon, 31 Jul 2023 23:48:49 -0400 Subject: [PATCH 06/31] make: add more fixed addresses --- Makefile | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/Makefile b/Makefile index beae2cd7..81d18697 100644 --- a/Makefile +++ b/Makefile @@ -130,6 +130,16 @@ test: examples test-stable .PHONY: tab tab: mkdir -p target/$(EXAMPLE) + LINKER_FLASH=0x00030000 LINKER_RAM=0x20008000 cargo build --example $(EXAMPLE) $(features) --target=thumbv7em-none-eabi $(release) + cp target/thumbv7em-none-eabi/release/examples/$(EXAMPLE) target/$(EXAMPLE)/cortex-m4.0x00030000.0x20008000.elf + LINKER_FLASH=0x00038000 LINKER_RAM=0x20010000 cargo build --example $(EXAMPLE) $(features) --target=thumbv7em-none-eabi $(release) + cp target/thumbv7em-none-eabi/release/examples/$(EXAMPLE) target/$(EXAMPLE)/cortex-m4.0x00038000.0x20010000.elf + + LINKER_FLASH=0x00040000 LINKER_RAM=0x10002000 cargo build --example $(EXAMPLE) $(features) --target=thumbv7em-none-eabi $(release) + cp target/thumbv7em-none-eabi/release/examples/$(EXAMPLE) target/$(EXAMPLE)/cortex-m4.0x00040000.0x10002000.elf + LINKER_FLASH=0x00048000 LINKER_RAM=0x1000a000 cargo build --example $(EXAMPLE) $(features) --target=thumbv7em-none-eabi $(release) + cp target/thumbv7em-none-eabi/release/examples/$(EXAMPLE) target/$(EXAMPLE)/cortex-m4.0x00048000.0x1000a000.elf + LINKER_FLASH=0x00040000 LINKER_RAM=0x20008000 cargo build --example $(EXAMPLE) $(features) --target=thumbv7em-none-eabi $(release) cp target/thumbv7em-none-eabi/release/examples/$(EXAMPLE) target/$(EXAMPLE)/cortex-m4.0x00040000.0x20008000.elf LINKER_FLASH=0x00042000 LINKER_RAM=0x2000a000 cargo build --example $(EXAMPLE) $(features) --target=thumbv7em-none-eabi $(release) @@ -137,10 +147,35 @@ tab: LINKER_FLASH=0x00048000 LINKER_RAM=0x20010000 cargo build --example $(EXAMPLE) $(features) --target=thumbv7em-none-eabi $(release) cp target/thumbv7em-none-eabi/release/examples/$(EXAMPLE) target/$(EXAMPLE)/cortex-m4.0x00048000.0x20010000.elf + LINKER_FLASH=0x00080000 LINKER_RAM=0x20006000 cargo build --example $(EXAMPLE) $(features) --target=thumbv7em-none-eabi $(release) + cp target/thumbv7em-none-eabi/release/examples/$(EXAMPLE) target/$(EXAMPLE)/cortex-m4.0x00080000.0x20006000.elf + LINKER_FLASH=0x00088000 LINKER_RAM=0x2000e000 cargo build --example $(EXAMPLE) $(features) --target=thumbv7em-none-eabi $(release) + cp target/thumbv7em-none-eabi/release/examples/$(EXAMPLE) target/$(EXAMPLE)/cortex-m4.0x00088000.0x2000e000.elf + + LINKER_FLASH=0x403b0000 LINKER_RAM=0x3fca2000 cargo build --example $(EXAMPLE) $(features) --target=riscv32imc-unknown-none-elf $(release) + cp target/riscv32imc-unknown-none-elf/release/examples/$(EXAMPLE) target/$(EXAMPLE)/riscv32imc.0x403b0000.0x3fca2000.elf + LINKER_FLASH=0x40440000 LINKER_RAM=0x3fcaa000 cargo build --example $(EXAMPLE) $(features) --target=riscv32imc-unknown-none-elf $(release) + cp target/riscv32imc-unknown-none-elf/release/examples/$(EXAMPLE) target/$(EXAMPLE)/riscv32imc.0x40440000.0x3fcaa000.elf + + LINKER_FLASH=0x10020000 LINKER_RAM=0x20004000 cargo build --example $(EXAMPLE) $(features) --target=thumbv6m-none-eabi $(release) + cp target/thumbv6m-none-eabi/release/examples/$(EXAMPLE) target/$(EXAMPLE)/cortex-m0.0x10020000.0x20006000.elf + LINKER_FLASH=0x10028000 LINKER_RAM=0x2000c000 cargo build --example $(EXAMPLE) $(features) --target=thumbv6m-none-eabi $(release) + cp target/thumbv6m-none-eabi/release/examples/$(EXAMPLE) target/$(EXAMPLE)/cortex-m0.0x10028000.0x2000c000.elf + elf2tab --kernel-major 2 --kernel-minor 0 -n $(EXAMPLE) -o $(EXAMPLE).tab --stack 1024 \ + target/$(EXAMPLE)/cortex-m4.0x00030000.0x20008000.elf \ + target/$(EXAMPLE)/cortex-m4.0x00038000.0x20010000.elf \ + target/$(EXAMPLE)/cortex-m4.0x00040000.0x10002000.elf \ + target/$(EXAMPLE)/cortex-m4.0x00048000.0x1000a000.elf \ target/$(EXAMPLE)/cortex-m4.0x00040000.0x20008000.elf \ target/$(EXAMPLE)/cortex-m4.0x00042000.0x2000a000.elf \ target/$(EXAMPLE)/cortex-m4.0x00048000.0x20010000.elf \ + target/$(EXAMPLE)/cortex-m4.0x00080000.0x20006000.elf \ + target/$(EXAMPLE)/cortex-m4.0x00088000.0x2000e000.elf \ + target/$(EXAMPLE)/riscv32imc.0x403b0000.0x3fca2000.elf \ + target/$(EXAMPLE)/riscv32imc.0x40440000.0x3fcaa000.elf \ + target/$(EXAMPLE)/cortex-m0.0x10020000.0x20006000.elf \ + target/$(EXAMPLE)/cortex-m0.0x10028000.0x2000c000.elf \ # Creates the `make EXAMPLE=` targets. Arguments: # 1) The name of the platform to build for. From e62499196b6d54a96e5e4353a22e15db9a54718e Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Tue, 1 Aug 2023 00:15:19 -0400 Subject: [PATCH 07/31] build.rs: support both existing make and proposed --- runtime/build.rs | 72 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 23 deletions(-) diff --git a/runtime/build.rs b/runtime/build.rs index 04159d9a..3f425de5 100644 --- a/runtime/build.rs +++ b/runtime/build.rs @@ -9,12 +9,14 @@ fn auto_layout() { use std::io::Write; use std::path::PathBuf; + const PLATFORM_CFG_VAR: &str = "LIBTOCK_PLATFORM"; const LINKER_FLASH_CFG_VAR: &str = "LINKER_FLASH"; const LINKER_RAM_CFG_VAR: &str = "LINKER_RAM"; const LAYOUT_GENERIC_FILENAME: &str = "libtock_layout.ld"; // Note: we need to print these rerun-if commands before using the variable // or file, so that if the build script fails cargo knows when to re-run it. + println!("cargo:rerun-if-env-changed={}", PLATFORM_CFG_VAR); println!("cargo:rerun-if-env-changed={}", LINKER_FLASH_CFG_VAR); println!("cargo:rerun-if-env-changed={}", LINKER_RAM_CFG_VAR); @@ -30,32 +32,56 @@ fn auto_layout() { "Build path contains a newline, which is unsupported" ); + // Where we are going to put the custom linker script for this particular + // build. + let out_platform_path: PathBuf = [out_dir, "layout.ld"].iter().collect(); + + // Choose the linker file we are going to use for this build. That can be + // specified by choosing a platform, where the linker file will be selected + // from `runtime/layouts`, or by explicitly setting the flash and RAM + // addresses. + // Read the platform environment variable as a String (our platform names // should all be valid UTF-8). - let linker_flash = std::env::var(LINKER_FLASH_CFG_VAR).expect("Please specify LINKER_FLASH"); - let linker_ram = std::env::var(LINKER_RAM_CFG_VAR).expect("Please specify LINKER_RAM"); + let platform = std::env::var(PLATFORM_CFG_VAR); - // Create a valid linker file with the specified flash and ram locations. - // - // ``` - // TBF_HEADER_SIZE = 0x60; - // - // FLASH_START = 0x00040000; - // FLASH_LENGTH = 0x00040000; - // - // RAM_START = 0x20008000; - // RAM_LENGTH = 62K; - // - // INCLUDE libtock_layout.ld - // ``` - let out_platform_path: PathBuf = [out_dir, "layout.ld"].iter().collect(); - let mut file = File::create(out_platform_path).expect("Could not create linker file"); - write!(file, "TBF_HEADER_SIZE = 0x60;\n").expect("Could not write linker file"); - write!(file, "FLASH_START = {};\n", linker_flash).expect("Could not write linker file"); - write!(file, "FLASH_LENGTH = 0x000D0000;\n",).expect("Could not write linker file"); - write!(file, "RAM_START = {};\n", linker_ram).expect("Could not write linker file"); - write!(file, "RAM_LENGTH = 46K;\n",).expect("Could not write linker file"); - write!(file, "INCLUDE libtock_layout.ld\n").expect("Could not write linker file"); + // Read the explicit flash and RAM addresses. + let linker_flash = std::env::var(LINKER_FLASH_CFG_VAR); + let linker_ram = std::env::var(LINKER_RAM_CFG_VAR); + + if let Ok(platform) = platform { + // Copy the platform-specific layout file into OUT_DIR. + let platform_filename = format!("{}.ld", platform); + let platform_path: PathBuf = ["layouts", &platform_filename].iter().collect(); + println!("cargo:rerun-if-changed={}", platform_path.display()); + assert!(platform_path.exists(), "Unknown platform {}", platform); + copy(&platform_path, out_platform_path) + .expect("Unable to copy platform layout into OUT_DIR"); + } else if let (Ok(linker_flash), Ok(linker_ram)) = (linker_flash, linker_ram) { + // Create a valid linker file with the specified flash and ram locations. + // + // ``` + // TBF_HEADER_SIZE = 0x60; + // + // FLASH_START = 0x00040000; + // FLASH_LENGTH = 0x00040000; + // + // RAM_START = 0x20008000; + // RAM_LENGTH = 62K; + // + // INCLUDE libtock_layout.ld + // ``` + let out_platform_path: PathBuf = [out_dir, "layout.ld"].iter().collect(); + let mut file = File::create(out_platform_path).expect("Could not create linker file"); + write!(file, "TBF_HEADER_SIZE = 0x60;\n").expect("Could not write linker file"); + write!(file, "FLASH_START = {};\n", linker_flash).expect("Could not write linker file"); + write!(file, "FLASH_LENGTH = 0x000D0000;\n",).expect("Could not write linker file"); + write!(file, "RAM_START = {};\n", linker_ram).expect("Could not write linker file"); + write!(file, "RAM_LENGTH = 46K;\n",).expect("Could not write linker file"); + write!(file, "INCLUDE libtock_layout.ld\n").expect("Could not write linker file"); + } else { + panic!("Need to set LIBTOCK_PLATFORM or (LINKER_FLASH and LINKER_RAM)"); + } // Copy the generic layout file into OUT_DIR. let out_layout_generic: PathBuf = [out_dir, LAYOUT_GENERIC_FILENAME].iter().collect(); From 4449115b647c445d3012c15540dbbc8be0d4a7fe Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Tue, 1 Aug 2023 14:29:22 -0400 Subject: [PATCH 08/31] make: ensure footer, add space in header Header needs to be larger to accomodate additional TBF TLVs such as storage permissions and the program header. --- Makefile | 2 +- runtime/build.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 81d18697..d6a80d38 100644 --- a/Makefile +++ b/Makefile @@ -162,7 +162,7 @@ tab: LINKER_FLASH=0x10028000 LINKER_RAM=0x2000c000 cargo build --example $(EXAMPLE) $(features) --target=thumbv6m-none-eabi $(release) cp target/thumbv6m-none-eabi/release/examples/$(EXAMPLE) target/$(EXAMPLE)/cortex-m0.0x10028000.0x2000c000.elf - elf2tab --kernel-major 2 --kernel-minor 0 -n $(EXAMPLE) -o $(EXAMPLE).tab --stack 1024 \ + elf2tab --kernel-major 2 --kernel-minor 0 -n $(EXAMPLE) -o $(EXAMPLE).tab --stack 1024 --minimum-footer-size 256 \ target/$(EXAMPLE)/cortex-m4.0x00030000.0x20008000.elf \ target/$(EXAMPLE)/cortex-m4.0x00038000.0x20010000.elf \ target/$(EXAMPLE)/cortex-m4.0x00040000.0x10002000.elf \ diff --git a/runtime/build.rs b/runtime/build.rs index 3f425de5..b3904343 100644 --- a/runtime/build.rs +++ b/runtime/build.rs @@ -61,7 +61,7 @@ fn auto_layout() { // Create a valid linker file with the specified flash and ram locations. // // ``` - // TBF_HEADER_SIZE = 0x60; + // TBF_HEADER_SIZE = 0x80; // // FLASH_START = 0x00040000; // FLASH_LENGTH = 0x00040000; @@ -73,7 +73,7 @@ fn auto_layout() { // ``` let out_platform_path: PathBuf = [out_dir, "layout.ld"].iter().collect(); let mut file = File::create(out_platform_path).expect("Could not create linker file"); - write!(file, "TBF_HEADER_SIZE = 0x60;\n").expect("Could not write linker file"); + write!(file, "TBF_HEADER_SIZE = 0x80;\n").expect("Could not write linker file"); write!(file, "FLASH_START = {};\n", linker_flash).expect("Could not write linker file"); write!(file, "FLASH_LENGTH = 0x000D0000;\n",).expect("Could not write linker file"); write!(file, "RAM_START = {};\n", linker_ram).expect("Could not write linker file"); From 815aae3a2a0238aacbcc30d8f22c697ef9e1ec2a Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Wed, 2 Aug 2023 23:14:20 -0400 Subject: [PATCH 09/31] build.rs: give each linker script a name Rather than use layout.ld for all of them. --- runtime/build.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/runtime/build.rs b/runtime/build.rs index b3904343..b9ade74d 100644 --- a/runtime/build.rs +++ b/runtime/build.rs @@ -71,7 +71,8 @@ fn auto_layout() { // // INCLUDE libtock_layout.ld // ``` - let out_platform_path: PathBuf = [out_dir, "layout.ld"].iter().collect(); + let linker_script_name = format!("{}.{}.ld", linker_flash, linker_ram); + let out_platform_path: PathBuf = [out_dir, &linker_script_name].iter().collect(); let mut file = File::create(out_platform_path).expect("Could not create linker file"); write!(file, "TBF_HEADER_SIZE = 0x80;\n").expect("Could not write linker file"); write!(file, "FLASH_START = {};\n", linker_flash).expect("Could not write linker file"); @@ -79,6 +80,9 @@ fn auto_layout() { write!(file, "RAM_START = {};\n", linker_ram).expect("Could not write linker file"); write!(file, "RAM_LENGTH = 46K;\n",).expect("Could not write linker file"); write!(file, "INCLUDE libtock_layout.ld\n").expect("Could not write linker file"); + + // Pass the name of this linker script to rustc. + println!("cargo:rustc-link-arg=-T{}", linker_script_name); } else { panic!("Need to set LIBTOCK_PLATFORM or (LINKER_FLASH and LINKER_RAM)"); } From 9e8b77c704583b8020db838193232102dc357cef Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Wed, 2 Aug 2023 23:14:46 -0400 Subject: [PATCH 10/31] make: a slightly different version for make tab Use make rules and targets. --- Makefile | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/Makefile b/Makefile index d6a80d38..de8f9473 100644 --- a/Makefile +++ b/Makefile @@ -177,6 +177,41 @@ tab: target/$(EXAMPLE)/cortex-m0.0x10020000.0x20006000.elf \ target/$(EXAMPLE)/cortex-m0.0x10028000.0x2000c000.elf \ +# Helper function to define target variables. +# https://stackoverflow.com/questions/50322607/multiple-target-specific-variable-values +assign-vars = $(foreach A,$2,$(eval $1: $A)) + +# F = Flash Address +# R = RAM Address +# T = Target +# A = Architecture +$(call assign-vars, elf01, F=0x00030000 R=0x20008000 T=thumbv7em-none-eabi A=cortex-m4) +$(call assign-vars, elf02, F=0x00038000 R=0x20010000 T=thumbv7em-none-eabi A=cortex-m4) + +$(call assign-vars, elf03, F=0x00040000 R=0x10002000 T=thumbv7em-none-eabi A=cortex-m4) +$(call assign-vars, elf04, F=0x00048000 R=0x1000a000 T=thumbv7em-none-eabi A=cortex-m4) + +$(call assign-vars, elf05, F=0x00040000 R=0x20008000 T=thumbv7em-none-eabi A=cortex-m4) +$(call assign-vars, elf06, F=0x00042000 R=0x2000a000 T=thumbv7em-none-eabi A=cortex-m4) +$(call assign-vars, elf07, F=0x00048000 R=0x20010000 T=thumbv7em-none-eabi A=cortex-m4) + +$(call assign-vars, elf08, F=0x00080000 R=0x20006000 T=thumbv7em-none-eabi A=cortex-m4) +$(call assign-vars, elf09, F=0x00088000 R=0x2000e000 T=thumbv7em-none-eabi A=cortex-m4) + +$(call assign-vars, elf10, F=0x403b0000 R=0x3fca2000 T=riscv32imc-unknown-none-elf A=riscv32imc) +$(call assign-vars, elf11, F=0x40440000 R=0x3fcaa000 T=riscv32imc-unknown-none-elf A=riscv32imc) + +$(call assign-vars, elf12, F=0x10020000 R=0x20004000 T=thumbv6m-none-eabi A=cortex-m0) +$(call assign-vars, elf13, F=0x10028000 R=0x2000c000 T=thumbv6m-none-eabi A=cortex-m0) + +elf01 elf02 elf03 elf04 elf05 elf06 elf07 elf08 elf09 elf10 elf11 elf12 elf13: + LINKER_FLASH=$(F) LINKER_RAM=$(R) cargo build --example $(EXAMPLE) $(features) --target=$(T) $(release) + cp target/$(T)/release/examples/$(EXAMPLE) target/$(EXAMPLE)/$(A).$(F).$(R).elf + $(eval ELF_LIST += target/$(EXAMPLE)/$(A).$(F).$(R).elf) + +elfs: elf01 elf02 elf03 elf04 elf05 elf06 elf07 elf08 elf09 elf10 elf11 elf12 elf13 + elf2tab --kernel-major 2 --kernel-minor 0 -n $(EXAMPLE) -o $(EXAMPLE).tab --stack 1024 --minimum-footer-size 256 $(ELF_LIST) + # Creates the `make EXAMPLE=` targets. Arguments: # 1) The name of the platform to build for. # From e1835cf6ca2a2e24bef06501eef11ca48f684e43 Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Thu, 3 Aug 2023 15:57:22 -0400 Subject: [PATCH 11/31] move build.rs to root The current build.rs only applies to the runtime crate, which makes setting the linker script impossible (well, it only works for the runtime crate). By moving this to the root we can set the linker script for all crates and examples and such. --- runtime/build.rs => build.rs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) rename runtime/build.rs => build.rs (89%) diff --git a/runtime/build.rs b/build.rs similarity index 89% rename from runtime/build.rs rename to build.rs index b9ade74d..e0a96aa9 100644 --- a/runtime/build.rs +++ b/build.rs @@ -1,8 +1,3 @@ -// auto_layout() identifies the correct linker scripts to use based on the -// LIBTOCK_PLATFORM environment variable, and copies the linker scripts into -// OUT_DIR. The cargo invocation must pass -C link-arg=-Tlayout.ld to rustc -// (using the rustflags cargo config). -#[cfg(not(feature = "no_auto_layout"))] fn auto_layout() { use std::fs::copy; use std::fs::File; @@ -52,11 +47,12 @@ fn auto_layout() { if let Ok(platform) = platform { // Copy the platform-specific layout file into OUT_DIR. let platform_filename = format!("{}.ld", platform); - let platform_path: PathBuf = ["layouts", &platform_filename].iter().collect(); + let platform_path: PathBuf = ["runtime", "layouts", &platform_filename].iter().collect(); println!("cargo:rerun-if-changed={}", platform_path.display()); assert!(platform_path.exists(), "Unknown platform {}", platform); copy(&platform_path, out_platform_path) .expect("Unable to copy platform layout into OUT_DIR"); + println!("cargo:rustc-link-arg=-Tlayout.ld"); } else if let (Ok(linker_flash), Ok(linker_ram)) = (linker_flash, linker_ram) { // Create a valid linker file with the specified flash and ram locations. // @@ -83,14 +79,16 @@ fn auto_layout() { // Pass the name of this linker script to rustc. println!("cargo:rustc-link-arg=-T{}", linker_script_name); + // println!("cargo:rustc-link-arg-bins=-T{}", linker_script_name); } else { panic!("Need to set LIBTOCK_PLATFORM or (LINKER_FLASH and LINKER_RAM)"); } // Copy the generic layout file into OUT_DIR. + let in_layout_generic: PathBuf = ["runtime", LAYOUT_GENERIC_FILENAME].iter().collect(); let out_layout_generic: PathBuf = [out_dir, LAYOUT_GENERIC_FILENAME].iter().collect(); println!("cargo:rerun-if-changed={}", LAYOUT_GENERIC_FILENAME); - copy(LAYOUT_GENERIC_FILENAME, out_layout_generic) + copy(in_layout_generic, out_layout_generic) .expect("Unable to copy layout_generic.ld into OUT_DIR"); // Tell rustc where to search for the layout file. @@ -98,6 +96,5 @@ fn auto_layout() { } fn main() { - #[cfg(not(feature = "no_auto_layout"))] auto_layout(); } From 70f9661058c63a6374f08ba5f037ba6a9390cd15 Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Thu, 3 Aug 2023 15:58:15 -0400 Subject: [PATCH 12/31] do not set linker script in .cargo/config We set this with the build.rs file now. --- .cargo/config | 1 - 1 file changed, 1 deletion(-) diff --git a/.cargo/config b/.cargo/config index 44e0274a..4cb3ae18 100644 --- a/.cargo/config +++ b/.cargo/config @@ -10,6 +10,5 @@ rtv7em = "rthumbv7em" [target.'cfg(any(target_arch = "arm", target_arch = "riscv32"))'] rustflags = [ "-C", "relocation-model=static", - "-C", "link-arg=-Tlayout.ld", ] runner = ["cargo", "run", "-p", "runner", "--release"] From c3772fb354f6826019a693ba944bc8e3ef7487c4 Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Thu, 3 Aug 2023 16:56:18 -0400 Subject: [PATCH 13/31] no longer copy linker files around Just point the linker to where they are already stored. --- build.rs | 42 ++++++++++++++++++------------------------ 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/build.rs b/build.rs index e0a96aa9..07dff307 100644 --- a/build.rs +++ b/build.rs @@ -1,5 +1,4 @@ fn auto_layout() { - use std::fs::copy; use std::fs::File; use std::io::Write; use std::path::PathBuf; @@ -7,7 +6,6 @@ fn auto_layout() { const PLATFORM_CFG_VAR: &str = "LIBTOCK_PLATFORM"; const LINKER_FLASH_CFG_VAR: &str = "LINKER_FLASH"; const LINKER_RAM_CFG_VAR: &str = "LINKER_RAM"; - const LAYOUT_GENERIC_FILENAME: &str = "libtock_layout.ld"; // Note: we need to print these rerun-if commands before using the variable // or file, so that if the build script fails cargo knows when to re-run it. @@ -27,9 +25,9 @@ fn auto_layout() { "Build path contains a newline, which is unsupported" ); - // Where we are going to put the custom linker script for this particular - // build. - let out_platform_path: PathBuf = [out_dir, "layout.ld"].iter().collect(); + // Point the linker to the generic libtock-rs linker file. + let generic_ld_dir: PathBuf = ["runtime"].iter().collect(); + println!("cargo:rustc-link-search={}", generic_ld_dir.display()); // Choose the linker file we are going to use for this build. That can be // specified by choosing a platform, where the linker file will be selected @@ -45,14 +43,18 @@ fn auto_layout() { let linker_ram = std::env::var(LINKER_RAM_CFG_VAR); if let Ok(platform) = platform { - // Copy the platform-specific layout file into OUT_DIR. - let platform_filename = format!("{}.ld", platform); - let platform_path: PathBuf = ["runtime", "layouts", &platform_filename].iter().collect(); - println!("cargo:rerun-if-changed={}", platform_path.display()); - assert!(platform_path.exists(), "Unknown platform {}", platform); - copy(&platform_path, out_platform_path) - .expect("Unable to copy platform layout into OUT_DIR"); - println!("cargo:rustc-link-arg=-Tlayout.ld"); + // Point the linker to the correct platform-specific linker file. + let platform_ld_name = format!("{}.ld", platform); + let platform_ld_dir: PathBuf = ["runtime", "layouts"].iter().collect(); + let platform_ld_path: PathBuf = ["runtime", "layouts", &platform_ld_name].iter().collect(); + + assert!(platform_ld_path.exists(), "Unknown platform {}", platform); + + println!("cargo:rerun-if-changed={}", platform_ld_path.display()); + println!("cargo:rustc-link-arg=-T{}", platform_ld_name); + + // Tell rustc where to search for the layout file. + println!("cargo:rustc-link-search={}", platform_ld_dir.display()); } else if let (Ok(linker_flash), Ok(linker_ram)) = (linker_flash, linker_ram) { // Create a valid linker file with the specified flash and ram locations. // @@ -79,20 +81,12 @@ fn auto_layout() { // Pass the name of this linker script to rustc. println!("cargo:rustc-link-arg=-T{}", linker_script_name); - // println!("cargo:rustc-link-arg-bins=-T{}", linker_script_name); + + // Tell rustc where to search for the layout file. + println!("cargo:rustc-link-search={}", out_dir); } else { panic!("Need to set LIBTOCK_PLATFORM or (LINKER_FLASH and LINKER_RAM)"); } - - // Copy the generic layout file into OUT_DIR. - let in_layout_generic: PathBuf = ["runtime", LAYOUT_GENERIC_FILENAME].iter().collect(); - let out_layout_generic: PathBuf = [out_dir, LAYOUT_GENERIC_FILENAME].iter().collect(); - println!("cargo:rerun-if-changed={}", LAYOUT_GENERIC_FILENAME); - copy(in_layout_generic, out_layout_generic) - .expect("Unable to copy layout_generic.ld into OUT_DIR"); - - // Tell rustc where to search for the layout file. - println!("cargo:rustc-link-search={}", out_dir); } fn main() { From 095b18786e31ed0a77643d748de5800033a07068 Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Thu, 3 Aug 2023 22:42:55 -0400 Subject: [PATCH 14/31] new libtock_runtime_build crate --- Cargo.toml | 3 ++ build.rs | 93 +------------------------------- libtock_runtime_build/Cargo.toml | 9 ++++ libtock_runtime_build/src/lib.rs | 92 +++++++++++++++++++++++++++++++ 4 files changed, 105 insertions(+), 92 deletions(-) create mode 100644 libtock_runtime_build/Cargo.toml create mode 100644 libtock_runtime_build/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index f86ea661..9c6275a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,6 +28,9 @@ libtock_runtime = { path = "runtime" } libtock_sound_pressure = {path = "apis/sound_pressure"} libtock_temperature = { path = "apis/temperature" } +[build-dependencies] +libtock_runtime_build = { path = "libtock_runtime_build"} + [profile.dev] panic = "abort" lto = true diff --git a/build.rs b/build.rs index 07dff307..d83f5bb0 100644 --- a/build.rs +++ b/build.rs @@ -1,94 +1,3 @@ -fn auto_layout() { - use std::fs::File; - use std::io::Write; - use std::path::PathBuf; - - const PLATFORM_CFG_VAR: &str = "LIBTOCK_PLATFORM"; - const LINKER_FLASH_CFG_VAR: &str = "LINKER_FLASH"; - const LINKER_RAM_CFG_VAR: &str = "LINKER_RAM"; - - // Note: we need to print these rerun-if commands before using the variable - // or file, so that if the build script fails cargo knows when to re-run it. - println!("cargo:rerun-if-env-changed={}", PLATFORM_CFG_VAR); - println!("cargo:rerun-if-env-changed={}", LINKER_FLASH_CFG_VAR); - println!("cargo:rerun-if-env-changed={}", LINKER_RAM_CFG_VAR); - - // Read configuration from environment variables. - - // Note: cargo fails if run in a path that is not valid Unicode, so this - // script doesn't need to handle non-Unicode paths. Also, OUT_DIR cannot be - // in a location with a newline in it, or we have no way to pass - // rustc-link-search to cargo. - let out_dir = &std::env::var("OUT_DIR").expect("Unable to read OUT_DIR"); - assert!( - !out_dir.contains('\n'), - "Build path contains a newline, which is unsupported" - ); - - // Point the linker to the generic libtock-rs linker file. - let generic_ld_dir: PathBuf = ["runtime"].iter().collect(); - println!("cargo:rustc-link-search={}", generic_ld_dir.display()); - - // Choose the linker file we are going to use for this build. That can be - // specified by choosing a platform, where the linker file will be selected - // from `runtime/layouts`, or by explicitly setting the flash and RAM - // addresses. - - // Read the platform environment variable as a String (our platform names - // should all be valid UTF-8). - let platform = std::env::var(PLATFORM_CFG_VAR); - - // Read the explicit flash and RAM addresses. - let linker_flash = std::env::var(LINKER_FLASH_CFG_VAR); - let linker_ram = std::env::var(LINKER_RAM_CFG_VAR); - - if let Ok(platform) = platform { - // Point the linker to the correct platform-specific linker file. - let platform_ld_name = format!("{}.ld", platform); - let platform_ld_dir: PathBuf = ["runtime", "layouts"].iter().collect(); - let platform_ld_path: PathBuf = ["runtime", "layouts", &platform_ld_name].iter().collect(); - - assert!(platform_ld_path.exists(), "Unknown platform {}", platform); - - println!("cargo:rerun-if-changed={}", platform_ld_path.display()); - println!("cargo:rustc-link-arg=-T{}", platform_ld_name); - - // Tell rustc where to search for the layout file. - println!("cargo:rustc-link-search={}", platform_ld_dir.display()); - } else if let (Ok(linker_flash), Ok(linker_ram)) = (linker_flash, linker_ram) { - // Create a valid linker file with the specified flash and ram locations. - // - // ``` - // TBF_HEADER_SIZE = 0x80; - // - // FLASH_START = 0x00040000; - // FLASH_LENGTH = 0x00040000; - // - // RAM_START = 0x20008000; - // RAM_LENGTH = 62K; - // - // INCLUDE libtock_layout.ld - // ``` - let linker_script_name = format!("{}.{}.ld", linker_flash, linker_ram); - let out_platform_path: PathBuf = [out_dir, &linker_script_name].iter().collect(); - let mut file = File::create(out_platform_path).expect("Could not create linker file"); - write!(file, "TBF_HEADER_SIZE = 0x80;\n").expect("Could not write linker file"); - write!(file, "FLASH_START = {};\n", linker_flash).expect("Could not write linker file"); - write!(file, "FLASH_LENGTH = 0x000D0000;\n",).expect("Could not write linker file"); - write!(file, "RAM_START = {};\n", linker_ram).expect("Could not write linker file"); - write!(file, "RAM_LENGTH = 46K;\n",).expect("Could not write linker file"); - write!(file, "INCLUDE libtock_layout.ld\n").expect("Could not write linker file"); - - // Pass the name of this linker script to rustc. - println!("cargo:rustc-link-arg=-T{}", linker_script_name); - - // Tell rustc where to search for the layout file. - println!("cargo:rustc-link-search={}", out_dir); - } else { - panic!("Need to set LIBTOCK_PLATFORM or (LINKER_FLASH and LINKER_RAM)"); - } -} - fn main() { - auto_layout(); + libtock_runtime_build::auto_layout(); } diff --git a/libtock_runtime_build/Cargo.toml b/libtock_runtime_build/Cargo.toml new file mode 100644 index 00000000..e4b2f7b0 --- /dev/null +++ b/libtock_runtime_build/Cargo.toml @@ -0,0 +1,9 @@ +[package] +authors = ["Tock Project Developers "] +categories = ["embedded", "no-std", "os"] +description = """Helper functions for compiling libtock-rs apps.""" +edition = "2021" +license = "Apache-2.0 OR MIT" +name = "libtock_runtime_build" +repository = "https://www.github.com/tock/libtock-rs" +version = "0.1.0" diff --git a/libtock_runtime_build/src/lib.rs b/libtock_runtime_build/src/lib.rs new file mode 100644 index 00000000..dd976a2b --- /dev/null +++ b/libtock_runtime_build/src/lib.rs @@ -0,0 +1,92 @@ +//! Utility functions for implementing build.rs files for libtock-rs apps. + +pub fn auto_layout() { + use std::fs::File; + use std::io::Write; + use std::path::PathBuf; + + const PLATFORM_CFG_VAR: &str = "LIBTOCK_PLATFORM"; + const LINKER_FLASH_CFG_VAR: &str = "LINKER_FLASH"; + const LINKER_RAM_CFG_VAR: &str = "LINKER_RAM"; + + // Note: we need to print these rerun-if commands before using the variable + // or file, so that if the build script fails cargo knows when to re-run it. + println!("cargo:rerun-if-env-changed={}", PLATFORM_CFG_VAR); + println!("cargo:rerun-if-env-changed={}", LINKER_FLASH_CFG_VAR); + println!("cargo:rerun-if-env-changed={}", LINKER_RAM_CFG_VAR); + + // Read configuration from environment variables. + + // Note: cargo fails if run in a path that is not valid Unicode, so this + // script doesn't need to handle non-Unicode paths. Also, OUT_DIR cannot be + // in a location with a newline in it, or we have no way to pass + // rustc-link-search to cargo. + let out_dir = &std::env::var("OUT_DIR").expect("Unable to read OUT_DIR"); + assert!( + !out_dir.contains('\n'), + "Build path contains a newline, which is unsupported" + ); + + // Point the linker to the generic libtock-rs linker file. + let generic_ld_dir: PathBuf = ["runtime"].iter().collect(); + println!("cargo:rustc-link-search={}", generic_ld_dir.display()); + + // Choose the linker file we are going to use for this build. That can be + // specified by choosing a platform, where the linker file will be selected + // from `runtime/layouts`, or by explicitly setting the flash and RAM + // addresses. + + // Read the platform environment variable as a String (our platform names + // should all be valid UTF-8). + let platform = std::env::var(PLATFORM_CFG_VAR); + + // Read the explicit flash and RAM addresses. + let linker_flash = std::env::var(LINKER_FLASH_CFG_VAR); + let linker_ram = std::env::var(LINKER_RAM_CFG_VAR); + + if let Ok(platform) = platform { + // Point the linker to the correct platform-specific linker file. + let platform_ld_name = format!("{}.ld", platform); + let platform_ld_dir: PathBuf = ["runtime", "layouts"].iter().collect(); + let platform_ld_path: PathBuf = ["runtime", "layouts", &platform_ld_name].iter().collect(); + + assert!(platform_ld_path.exists(), "Unknown platform {}", platform); + + println!("cargo:rerun-if-changed={}", platform_ld_path.display()); + println!("cargo:rustc-link-arg=-T{}", platform_ld_name); + + // Tell rustc where to search for the layout file. + println!("cargo:rustc-link-search={}", platform_ld_dir.display()); + } else if let (Ok(linker_flash), Ok(linker_ram)) = (linker_flash, linker_ram) { + // Create a valid linker file with the specified flash and ram locations. + // + // ``` + // TBF_HEADER_SIZE = 0x80; + // + // FLASH_START = 0x00040000; + // FLASH_LENGTH = 0x00040000; + // + // RAM_START = 0x20008000; + // RAM_LENGTH = 62K; + // + // INCLUDE libtock_layout.ld + // ``` + let linker_script_name = format!("{}.{}.ld", linker_flash, linker_ram); + let out_platform_path: PathBuf = [out_dir, &linker_script_name].iter().collect(); + let mut file = File::create(out_platform_path).expect("Could not create linker file"); + write!(file, "TBF_HEADER_SIZE = 0x80;\n").expect("Could not write linker file"); + write!(file, "FLASH_START = {};\n", linker_flash).expect("Could not write linker file"); + write!(file, "FLASH_LENGTH = 0x000D0000;\n",).expect("Could not write linker file"); + write!(file, "RAM_START = {};\n", linker_ram).expect("Could not write linker file"); + write!(file, "RAM_LENGTH = 46K;\n",).expect("Could not write linker file"); + write!(file, "INCLUDE libtock_layout.ld\n").expect("Could not write linker file"); + + // Pass the name of this linker script to rustc. + println!("cargo:rustc-link-arg=-T{}", linker_script_name); + + // Tell rustc where to search for the layout file. + println!("cargo:rustc-link-search={}", out_dir); + } else { + panic!("Need to set LIBTOCK_PLATFORM or (LINKER_FLASH and LINKER_RAM)"); + } +} From 1816a373ca654d71bfb8c8be568bdaafd56c34de Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Thu, 3 Aug 2023 23:21:37 -0400 Subject: [PATCH 15/31] split build.rs into runtime-specific and root In runtime we need to get the linker scripts somewhere that the linker can use them. We _always_ need libtock_layout.ld, and we may want the board-specific ld scripts. In the new crate for build.rs, we specify which linker script we actually want. --- libtock_runtime_build/src/lib.rs | 13 ----------- runtime/Cargo.toml | 5 ---- runtime/build.rs | 40 ++++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 18 deletions(-) create mode 100644 runtime/build.rs diff --git a/libtock_runtime_build/src/lib.rs b/libtock_runtime_build/src/lib.rs index dd976a2b..0954d487 100644 --- a/libtock_runtime_build/src/lib.rs +++ b/libtock_runtime_build/src/lib.rs @@ -27,10 +27,6 @@ pub fn auto_layout() { "Build path contains a newline, which is unsupported" ); - // Point the linker to the generic libtock-rs linker file. - let generic_ld_dir: PathBuf = ["runtime"].iter().collect(); - println!("cargo:rustc-link-search={}", generic_ld_dir.display()); - // Choose the linker file we are going to use for this build. That can be // specified by choosing a platform, where the linker file will be selected // from `runtime/layouts`, or by explicitly setting the flash and RAM @@ -47,16 +43,7 @@ pub fn auto_layout() { if let Ok(platform) = platform { // Point the linker to the correct platform-specific linker file. let platform_ld_name = format!("{}.ld", platform); - let platform_ld_dir: PathBuf = ["runtime", "layouts"].iter().collect(); - let platform_ld_path: PathBuf = ["runtime", "layouts", &platform_ld_name].iter().collect(); - - assert!(platform_ld_path.exists(), "Unknown platform {}", platform); - - println!("cargo:rerun-if-changed={}", platform_ld_path.display()); println!("cargo:rustc-link-arg=-T{}", platform_ld_name); - - // Tell rustc where to search for the layout file. - println!("cargo:rustc-link-search={}", platform_ld_dir.display()); } else if let (Ok(linker_flash), Ok(linker_ram)) = (linker_flash, linker_ram) { // Create a valid linker file with the specified flash and ram locations. // diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index a8633923..11861b24 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -14,11 +14,6 @@ libtock_platform = { path = "../platform" } [features] -# By default, libtock_runtime looks for the LIBTOCK_PLATFORM variable to decide -# what layout file to use. If you are providing your own linker script, set -# no_auto_layout to disable the layout file logic. -no_auto_layout = [] - # By default, libtock_runtime calls Memop to tell the Tock kernel where the # stack and heap begin. The kernel uses those addresses to specify the stack and # heap address ranges if the process faults. Those calls cost 22 bytes on ARM diff --git a/runtime/build.rs b/runtime/build.rs new file mode 100644 index 00000000..e9a2b1f2 --- /dev/null +++ b/runtime/build.rs @@ -0,0 +1,40 @@ +//! This build.rs makes common linker scripts available when linking libtock-rs +//! apps. + +fn main() { + use std::fs::copy; + use std::fs::read_dir; + use std::path::PathBuf; + + const LAYOUT_GENERIC_FILENAME: &str = "libtock_layout.ld"; + + // Note: cargo fails if run in a path that is not valid Unicode, so this + // script doesn't need to handle non-Unicode paths. Also, OUT_DIR cannot be + // in a location with a newline in it, or we have no way to pass + // rustc-link-search to cargo. + let out_dir = &std::env::var("OUT_DIR").expect("Unable to read OUT_DIR"); + assert!( + !out_dir.contains('\n'), + "Build path contains a newline, which is unsupported" + ); + + // Copy all platform linker scripts to a directory where the linker can find + // them. + let paths = read_dir("layouts").unwrap(); + for path in paths { + let ld_path = path.as_ref().unwrap().path(); + let ld_name = path.as_ref().unwrap().file_name().into_string().unwrap(); + let out_ld_path: PathBuf = [out_dir, &ld_name].iter().collect(); + copy(ld_path, out_ld_path).expect("Unable to copy platform layout into OUT_DIR"); + } + + // Copy the generic layout file into OUT_DIR. + let out_layout_generic: PathBuf = [out_dir, LAYOUT_GENERIC_FILENAME].iter().collect(); + println!("cargo:rerun-if-changed={}", LAYOUT_GENERIC_FILENAME); + copy(LAYOUT_GENERIC_FILENAME, out_layout_generic) + .expect("Unable to copy layout_generic.ld into OUT_DIR"); + + // Tell the linker that it can find linker scripts in the out directory of + // the libtock_runtime crate. + println!("cargo:rustc-link-search={}", out_dir); +} From b6cbd1c34c82a8a544752b2118580c6f77b6ae74 Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Thu, 3 Aug 2023 23:36:25 -0400 Subject: [PATCH 16/31] put each built artifact in its own dir --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index de8f9473..d9fd06ed 100644 --- a/Makefile +++ b/Makefile @@ -205,8 +205,8 @@ $(call assign-vars, elf12, F=0x10020000 R=0x20004000 T=thumbv6m-none-eabi A=cort $(call assign-vars, elf13, F=0x10028000 R=0x2000c000 T=thumbv6m-none-eabi A=cortex-m0) elf01 elf02 elf03 elf04 elf05 elf06 elf07 elf08 elf09 elf10 elf11 elf12 elf13: - LINKER_FLASH=$(F) LINKER_RAM=$(R) cargo build --example $(EXAMPLE) $(features) --target=$(T) $(release) - cp target/$(T)/release/examples/$(EXAMPLE) target/$(EXAMPLE)/$(A).$(F).$(R).elf + LINKER_FLASH=$(F) LINKER_RAM=$(R) cargo build --example $(EXAMPLE) $(features) --target=$(T) $(release) --out-dir target/$(A).$(F).$(R) -Z unstable-options + cp target/$(A).$(F).$(R)/$(T)/release/examples/$(EXAMPLE) target/$(EXAMPLE)/$(A).$(F).$(R).elf $(eval ELF_LIST += target/$(EXAMPLE)/$(A).$(F).$(R).elf) elfs: elf01 elf02 elf03 elf04 elf05 elf06 elf07 elf08 elf09 elf10 elf11 elf12 elf13 From 4b62d587b7441a0f7b0ae7577c1550728ac20627 Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Fri, 4 Aug 2023 00:13:07 -0400 Subject: [PATCH 17/31] move all buildrs to new build crate --- {runtime => libtock_runtime_build}/build.rs | 4 ++++ {runtime => libtock_runtime_build}/layouts/apollo3.ld | 0 {runtime => libtock_runtime_build}/layouts/clue_nrf52840.ld | 0 .../layouts/esp32_c3_devkitm_1.ld | 0 {runtime => libtock_runtime_build}/layouts/hail.ld | 0 {runtime => libtock_runtime_build}/layouts/hifive1.ld | 0 {runtime => libtock_runtime_build}/layouts/imix.ld | 0 {runtime => libtock_runtime_build}/layouts/imxrt1050.ld | 0 {runtime => libtock_runtime_build}/layouts/microbit_v2.ld | 0 {runtime => libtock_runtime_build}/layouts/msp432.ld | 0 .../layouts/nano_rp2040_connect.ld | 0 {runtime => libtock_runtime_build}/layouts/nrf52.ld | 0 {runtime => libtock_runtime_build}/layouts/nrf52840.ld | 0 {runtime => libtock_runtime_build}/layouts/nucleo_f429zi.ld | 0 {runtime => libtock_runtime_build}/layouts/nucleo_f446re.ld | 0 {runtime => libtock_runtime_build}/layouts/opentitan.ld | 0 .../layouts/raspberry_pi_pico.ld | 0 .../layouts/stm32f3discovery.ld | 0 .../layouts/stm32f412gdiscovery.ld | 0 {runtime => libtock_runtime_build}/libtock_layout.ld | 0 libtock_runtime_build/src/lib.rs | 5 +++++ 21 files changed, 9 insertions(+) rename {runtime => libtock_runtime_build}/build.rs (89%) rename {runtime => libtock_runtime_build}/layouts/apollo3.ld (100%) rename {runtime => libtock_runtime_build}/layouts/clue_nrf52840.ld (100%) rename {runtime => libtock_runtime_build}/layouts/esp32_c3_devkitm_1.ld (100%) rename {runtime => libtock_runtime_build}/layouts/hail.ld (100%) rename {runtime => libtock_runtime_build}/layouts/hifive1.ld (100%) rename {runtime => libtock_runtime_build}/layouts/imix.ld (100%) rename {runtime => libtock_runtime_build}/layouts/imxrt1050.ld (100%) rename {runtime => libtock_runtime_build}/layouts/microbit_v2.ld (100%) rename {runtime => libtock_runtime_build}/layouts/msp432.ld (100%) rename {runtime => libtock_runtime_build}/layouts/nano_rp2040_connect.ld (100%) rename {runtime => libtock_runtime_build}/layouts/nrf52.ld (100%) rename {runtime => libtock_runtime_build}/layouts/nrf52840.ld (100%) rename {runtime => libtock_runtime_build}/layouts/nucleo_f429zi.ld (100%) rename {runtime => libtock_runtime_build}/layouts/nucleo_f446re.ld (100%) rename {runtime => libtock_runtime_build}/layouts/opentitan.ld (100%) rename {runtime => libtock_runtime_build}/layouts/raspberry_pi_pico.ld (100%) rename {runtime => libtock_runtime_build}/layouts/stm32f3discovery.ld (100%) rename {runtime => libtock_runtime_build}/layouts/stm32f412gdiscovery.ld (100%) rename {runtime => libtock_runtime_build}/libtock_layout.ld (100%) diff --git a/runtime/build.rs b/libtock_runtime_build/build.rs similarity index 89% rename from runtime/build.rs rename to libtock_runtime_build/build.rs index e9a2b1f2..1c1de5c4 100644 --- a/runtime/build.rs +++ b/libtock_runtime_build/build.rs @@ -18,6 +18,10 @@ fn main() { "Build path contains a newline, which is unsupported" ); + // Share the out dir of this crate with the actual source so we know where + // we put the linker scripts. + println!("cargo:rustc-env=LIBTOCK_RUNTIME_BUILD_OUT_DIR={}", out_dir); + // Copy all platform linker scripts to a directory where the linker can find // them. let paths = read_dir("layouts").unwrap(); diff --git a/runtime/layouts/apollo3.ld b/libtock_runtime_build/layouts/apollo3.ld similarity index 100% rename from runtime/layouts/apollo3.ld rename to libtock_runtime_build/layouts/apollo3.ld diff --git a/runtime/layouts/clue_nrf52840.ld b/libtock_runtime_build/layouts/clue_nrf52840.ld similarity index 100% rename from runtime/layouts/clue_nrf52840.ld rename to libtock_runtime_build/layouts/clue_nrf52840.ld diff --git a/runtime/layouts/esp32_c3_devkitm_1.ld b/libtock_runtime_build/layouts/esp32_c3_devkitm_1.ld similarity index 100% rename from runtime/layouts/esp32_c3_devkitm_1.ld rename to libtock_runtime_build/layouts/esp32_c3_devkitm_1.ld diff --git a/runtime/layouts/hail.ld b/libtock_runtime_build/layouts/hail.ld similarity index 100% rename from runtime/layouts/hail.ld rename to libtock_runtime_build/layouts/hail.ld diff --git a/runtime/layouts/hifive1.ld b/libtock_runtime_build/layouts/hifive1.ld similarity index 100% rename from runtime/layouts/hifive1.ld rename to libtock_runtime_build/layouts/hifive1.ld diff --git a/runtime/layouts/imix.ld b/libtock_runtime_build/layouts/imix.ld similarity index 100% rename from runtime/layouts/imix.ld rename to libtock_runtime_build/layouts/imix.ld diff --git a/runtime/layouts/imxrt1050.ld b/libtock_runtime_build/layouts/imxrt1050.ld similarity index 100% rename from runtime/layouts/imxrt1050.ld rename to libtock_runtime_build/layouts/imxrt1050.ld diff --git a/runtime/layouts/microbit_v2.ld b/libtock_runtime_build/layouts/microbit_v2.ld similarity index 100% rename from runtime/layouts/microbit_v2.ld rename to libtock_runtime_build/layouts/microbit_v2.ld diff --git a/runtime/layouts/msp432.ld b/libtock_runtime_build/layouts/msp432.ld similarity index 100% rename from runtime/layouts/msp432.ld rename to libtock_runtime_build/layouts/msp432.ld diff --git a/runtime/layouts/nano_rp2040_connect.ld b/libtock_runtime_build/layouts/nano_rp2040_connect.ld similarity index 100% rename from runtime/layouts/nano_rp2040_connect.ld rename to libtock_runtime_build/layouts/nano_rp2040_connect.ld diff --git a/runtime/layouts/nrf52.ld b/libtock_runtime_build/layouts/nrf52.ld similarity index 100% rename from runtime/layouts/nrf52.ld rename to libtock_runtime_build/layouts/nrf52.ld diff --git a/runtime/layouts/nrf52840.ld b/libtock_runtime_build/layouts/nrf52840.ld similarity index 100% rename from runtime/layouts/nrf52840.ld rename to libtock_runtime_build/layouts/nrf52840.ld diff --git a/runtime/layouts/nucleo_f429zi.ld b/libtock_runtime_build/layouts/nucleo_f429zi.ld similarity index 100% rename from runtime/layouts/nucleo_f429zi.ld rename to libtock_runtime_build/layouts/nucleo_f429zi.ld diff --git a/runtime/layouts/nucleo_f446re.ld b/libtock_runtime_build/layouts/nucleo_f446re.ld similarity index 100% rename from runtime/layouts/nucleo_f446re.ld rename to libtock_runtime_build/layouts/nucleo_f446re.ld diff --git a/runtime/layouts/opentitan.ld b/libtock_runtime_build/layouts/opentitan.ld similarity index 100% rename from runtime/layouts/opentitan.ld rename to libtock_runtime_build/layouts/opentitan.ld diff --git a/runtime/layouts/raspberry_pi_pico.ld b/libtock_runtime_build/layouts/raspberry_pi_pico.ld similarity index 100% rename from runtime/layouts/raspberry_pi_pico.ld rename to libtock_runtime_build/layouts/raspberry_pi_pico.ld diff --git a/runtime/layouts/stm32f3discovery.ld b/libtock_runtime_build/layouts/stm32f3discovery.ld similarity index 100% rename from runtime/layouts/stm32f3discovery.ld rename to libtock_runtime_build/layouts/stm32f3discovery.ld diff --git a/runtime/layouts/stm32f412gdiscovery.ld b/libtock_runtime_build/layouts/stm32f412gdiscovery.ld similarity index 100% rename from runtime/layouts/stm32f412gdiscovery.ld rename to libtock_runtime_build/layouts/stm32f412gdiscovery.ld diff --git a/runtime/libtock_layout.ld b/libtock_runtime_build/libtock_layout.ld similarity index 100% rename from runtime/libtock_layout.ld rename to libtock_runtime_build/libtock_layout.ld diff --git a/libtock_runtime_build/src/lib.rs b/libtock_runtime_build/src/lib.rs index 0954d487..478025f5 100644 --- a/libtock_runtime_build/src/lib.rs +++ b/libtock_runtime_build/src/lib.rs @@ -27,6 +27,11 @@ pub fn auto_layout() { "Build path contains a newline, which is unsupported" ); + // Set the linker search path to the out dir of this crate where we have + // stored all of the linker files. + let runtime_build_out_dir = env!("LIBTOCK_RUNTIME_BUILD_OUT_DIR"); + println!("cargo:rustc-link-search={}", runtime_build_out_dir); + // Choose the linker file we are going to use for this build. That can be // specified by choosing a platform, where the linker file will be selected // from `runtime/layouts`, or by explicitly setting the flash and RAM From eb83a8d0b8b0f766c6275cd2f8285954dd18d191 Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Fri, 4 Aug 2023 09:25:37 -0400 Subject: [PATCH 18/31] runtime build docs --- libtock_runtime_build/README.md | 60 ++++++++++++++++++++++++++++++++ libtock_runtime_build/src/lib.rs | 31 +++++++++++++++-- 2 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 libtock_runtime_build/README.md diff --git a/libtock_runtime_build/README.md b/libtock_runtime_build/README.md new file mode 100644 index 00000000..470e3cfc --- /dev/null +++ b/libtock_runtime_build/README.md @@ -0,0 +1,60 @@ +Libtock Runtime Build Support Crate +=================================== + +This crate provides helpers for building libtock-rs apps. + +Usage +----- + +There are three general steps to use this crate. + +1. This crate should be included as a build dependency in the app's Cargo.toml + file: + + ```toml + # Cargo.toml + ... + + [build-dependencies] + libtock_runtime_build = { git = "https://github.com/tock/libtock-rs"} + ``` + + This will ensure the crate and the contained linker scripts are available for + the app build. + +2. This crate provides a helper function which can used from the libtock-rs + app's build.rs file. In the common case, you just call the provided function + from the build.rs file in your crate's root: + + ```rs + // build.rs + + fn main() { + libtock_runtime_build::auto_layout(); + } + ``` + + This will allow cargo to setup linker scripts and paths for the linker when + your app is built. + +3. When calling `cargo build` you need to instruct the build.rs on where in + memory to compile your app for. This crate supports two mechanisms to do + this. You can only use one. + + 1. Set the `LIBTOCK_PLATFORM` environment variable which specifies the name + of the linker script in `/layouts` to be used. So for example, if you are + using the microbit_v2 you might run: + + ```bash + $ LIBTOCK_PLATFORM=microbit_v2 cargo build --target thumbv7em-none-eabi --release + ``` + + 2. Set the `LINKER_FLASH` and `LINKER_RAM` environment variables which + specify the starting addresses of flash and RAM memory, respectively. This + allows you to customize where exactly the compiled app must be placed in + flash and RAM. For example, to build for common Cortex-M4 platforms you + might run: + + ```bash + $ LINKER_FLASH=0x00040000 LINKER_RAM=0x20008000 cargo build --target thumbv7em-none-eabi --release + ``` diff --git a/libtock_runtime_build/src/lib.rs b/libtock_runtime_build/src/lib.rs index 478025f5..e70c7ff0 100644 --- a/libtock_runtime_build/src/lib.rs +++ b/libtock_runtime_build/src/lib.rs @@ -1,5 +1,33 @@ //! Utility functions for implementing build.rs files for libtock-rs apps. +/// This path is set by this crate's build.rs file when this crate is compiled. +/// This allows this file to know the path of its own local outdir where copies +/// of linker scripts are stored (by this crate's build.rs). That path can then +/// be used in other libtock-rs compilations to provide useful linker scripts. +pub const RUNTIME_BUILD_OUT_DIR: &str = env!("LIBTOCK_RUNTIME_BUILD_OUT_DIR"); + +/// Helper function to configure cargo to use suitable linker scripts for +/// linking libtock-rs apps. +/// +/// This function does two things: +/// +/// 1. Make sure that the linker's search path includes where +/// `libtock_layout.ld` is stored. This is a general linker script designed +/// for libtock-rs apps and the Tock kernel. +/// +/// 2. Reference a board-specific linker script that essentially sets the +/// `MEMORY` command to specify the flash and RAM addresses where the app +/// should be compiled. This happens by passing the `-T` +/// flag to the linker. +/// +/// This function supports two methods for doing this: +/// +/// 1. Passing the `LIBTOCK_PLATFORM` environment variable which specifies +/// the name of the linker script in `/layouts` to be used. +/// +/// 2. Passing the `LINKER_FLASH` and `LINKER_RAM` environment variables +/// which specify the starting addresses of flash and RAM memory, +/// respectively. pub fn auto_layout() { use std::fs::File; use std::io::Write; @@ -29,8 +57,7 @@ pub fn auto_layout() { // Set the linker search path to the out dir of this crate where we have // stored all of the linker files. - let runtime_build_out_dir = env!("LIBTOCK_RUNTIME_BUILD_OUT_DIR"); - println!("cargo:rustc-link-search={}", runtime_build_out_dir); + println!("cargo:rustc-link-search={}", RUNTIME_BUILD_OUT_DIR); // Choose the linker file we are going to use for this build. That can be // specified by choosing a platform, where the linker file will be selected From 33196c6a67a03782ae30dc721d1ff25605d505bd Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Fri, 4 Aug 2023 09:42:54 -0400 Subject: [PATCH 19/31] make: we don't actually need the copy --- Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Makefile b/Makefile index d9fd06ed..461c1600 100644 --- a/Makefile +++ b/Makefile @@ -206,8 +206,7 @@ $(call assign-vars, elf13, F=0x10028000 R=0x2000c000 T=thumbv6m-none-eabi A=cort elf01 elf02 elf03 elf04 elf05 elf06 elf07 elf08 elf09 elf10 elf11 elf12 elf13: LINKER_FLASH=$(F) LINKER_RAM=$(R) cargo build --example $(EXAMPLE) $(features) --target=$(T) $(release) --out-dir target/$(A).$(F).$(R) -Z unstable-options - cp target/$(A).$(F).$(R)/$(T)/release/examples/$(EXAMPLE) target/$(EXAMPLE)/$(A).$(F).$(R).elf - $(eval ELF_LIST += target/$(EXAMPLE)/$(A).$(F).$(R).elf) + $(eval ELF_LIST += target/$(A).$(F).$(R)/$(EXAMPLE),$(A).$(F).$(R)) elfs: elf01 elf02 elf03 elf04 elf05 elf06 elf07 elf08 elf09 elf10 elf11 elf12 elf13 elf2tab --kernel-major 2 --kernel-minor 0 -n $(EXAMPLE) -o $(EXAMPLE).tab --stack 1024 --minimum-footer-size 256 $(ELF_LIST) From d4a59f1aac5b1134c8a13009cd250c6f0c7d53a5 Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Fri, 4 Aug 2023 09:44:16 -0400 Subject: [PATCH 20/31] make: just use the assign-vars, it's cleaner --- Makefile | 53 ++--------------------------------------------------- 1 file changed, 2 insertions(+), 51 deletions(-) diff --git a/Makefile b/Makefile index 461c1600..be05ba5d 100644 --- a/Makefile +++ b/Makefile @@ -127,56 +127,6 @@ test: examples test-stable cargo miri test $(EXCLUDE_MIRI) --workspace echo '[ SUCCESS ] libtock-rs tests pass' -.PHONY: tab -tab: - mkdir -p target/$(EXAMPLE) - LINKER_FLASH=0x00030000 LINKER_RAM=0x20008000 cargo build --example $(EXAMPLE) $(features) --target=thumbv7em-none-eabi $(release) - cp target/thumbv7em-none-eabi/release/examples/$(EXAMPLE) target/$(EXAMPLE)/cortex-m4.0x00030000.0x20008000.elf - LINKER_FLASH=0x00038000 LINKER_RAM=0x20010000 cargo build --example $(EXAMPLE) $(features) --target=thumbv7em-none-eabi $(release) - cp target/thumbv7em-none-eabi/release/examples/$(EXAMPLE) target/$(EXAMPLE)/cortex-m4.0x00038000.0x20010000.elf - - LINKER_FLASH=0x00040000 LINKER_RAM=0x10002000 cargo build --example $(EXAMPLE) $(features) --target=thumbv7em-none-eabi $(release) - cp target/thumbv7em-none-eabi/release/examples/$(EXAMPLE) target/$(EXAMPLE)/cortex-m4.0x00040000.0x10002000.elf - LINKER_FLASH=0x00048000 LINKER_RAM=0x1000a000 cargo build --example $(EXAMPLE) $(features) --target=thumbv7em-none-eabi $(release) - cp target/thumbv7em-none-eabi/release/examples/$(EXAMPLE) target/$(EXAMPLE)/cortex-m4.0x00048000.0x1000a000.elf - - LINKER_FLASH=0x00040000 LINKER_RAM=0x20008000 cargo build --example $(EXAMPLE) $(features) --target=thumbv7em-none-eabi $(release) - cp target/thumbv7em-none-eabi/release/examples/$(EXAMPLE) target/$(EXAMPLE)/cortex-m4.0x00040000.0x20008000.elf - LINKER_FLASH=0x00042000 LINKER_RAM=0x2000a000 cargo build --example $(EXAMPLE) $(features) --target=thumbv7em-none-eabi $(release) - cp target/thumbv7em-none-eabi/release/examples/$(EXAMPLE) target/$(EXAMPLE)/cortex-m4.0x00042000.0x2000a000.elf - LINKER_FLASH=0x00048000 LINKER_RAM=0x20010000 cargo build --example $(EXAMPLE) $(features) --target=thumbv7em-none-eabi $(release) - cp target/thumbv7em-none-eabi/release/examples/$(EXAMPLE) target/$(EXAMPLE)/cortex-m4.0x00048000.0x20010000.elf - - LINKER_FLASH=0x00080000 LINKER_RAM=0x20006000 cargo build --example $(EXAMPLE) $(features) --target=thumbv7em-none-eabi $(release) - cp target/thumbv7em-none-eabi/release/examples/$(EXAMPLE) target/$(EXAMPLE)/cortex-m4.0x00080000.0x20006000.elf - LINKER_FLASH=0x00088000 LINKER_RAM=0x2000e000 cargo build --example $(EXAMPLE) $(features) --target=thumbv7em-none-eabi $(release) - cp target/thumbv7em-none-eabi/release/examples/$(EXAMPLE) target/$(EXAMPLE)/cortex-m4.0x00088000.0x2000e000.elf - - LINKER_FLASH=0x403b0000 LINKER_RAM=0x3fca2000 cargo build --example $(EXAMPLE) $(features) --target=riscv32imc-unknown-none-elf $(release) - cp target/riscv32imc-unknown-none-elf/release/examples/$(EXAMPLE) target/$(EXAMPLE)/riscv32imc.0x403b0000.0x3fca2000.elf - LINKER_FLASH=0x40440000 LINKER_RAM=0x3fcaa000 cargo build --example $(EXAMPLE) $(features) --target=riscv32imc-unknown-none-elf $(release) - cp target/riscv32imc-unknown-none-elf/release/examples/$(EXAMPLE) target/$(EXAMPLE)/riscv32imc.0x40440000.0x3fcaa000.elf - - LINKER_FLASH=0x10020000 LINKER_RAM=0x20004000 cargo build --example $(EXAMPLE) $(features) --target=thumbv6m-none-eabi $(release) - cp target/thumbv6m-none-eabi/release/examples/$(EXAMPLE) target/$(EXAMPLE)/cortex-m0.0x10020000.0x20006000.elf - LINKER_FLASH=0x10028000 LINKER_RAM=0x2000c000 cargo build --example $(EXAMPLE) $(features) --target=thumbv6m-none-eabi $(release) - cp target/thumbv6m-none-eabi/release/examples/$(EXAMPLE) target/$(EXAMPLE)/cortex-m0.0x10028000.0x2000c000.elf - - elf2tab --kernel-major 2 --kernel-minor 0 -n $(EXAMPLE) -o $(EXAMPLE).tab --stack 1024 --minimum-footer-size 256 \ - target/$(EXAMPLE)/cortex-m4.0x00030000.0x20008000.elf \ - target/$(EXAMPLE)/cortex-m4.0x00038000.0x20010000.elf \ - target/$(EXAMPLE)/cortex-m4.0x00040000.0x10002000.elf \ - target/$(EXAMPLE)/cortex-m4.0x00048000.0x1000a000.elf \ - target/$(EXAMPLE)/cortex-m4.0x00040000.0x20008000.elf \ - target/$(EXAMPLE)/cortex-m4.0x00042000.0x2000a000.elf \ - target/$(EXAMPLE)/cortex-m4.0x00048000.0x20010000.elf \ - target/$(EXAMPLE)/cortex-m4.0x00080000.0x20006000.elf \ - target/$(EXAMPLE)/cortex-m4.0x00088000.0x2000e000.elf \ - target/$(EXAMPLE)/riscv32imc.0x403b0000.0x3fca2000.elf \ - target/$(EXAMPLE)/riscv32imc.0x40440000.0x3fcaa000.elf \ - target/$(EXAMPLE)/cortex-m0.0x10020000.0x20006000.elf \ - target/$(EXAMPLE)/cortex-m0.0x10028000.0x2000c000.elf \ - # Helper function to define target variables. # https://stackoverflow.com/questions/50322607/multiple-target-specific-variable-values assign-vars = $(foreach A,$2,$(eval $1: $A)) @@ -208,7 +158,8 @@ elf01 elf02 elf03 elf04 elf05 elf06 elf07 elf08 elf09 elf10 elf11 elf12 elf13: LINKER_FLASH=$(F) LINKER_RAM=$(R) cargo build --example $(EXAMPLE) $(features) --target=$(T) $(release) --out-dir target/$(A).$(F).$(R) -Z unstable-options $(eval ELF_LIST += target/$(A).$(F).$(R)/$(EXAMPLE),$(A).$(F).$(R)) -elfs: elf01 elf02 elf03 elf04 elf05 elf06 elf07 elf08 elf09 elf10 elf11 elf12 elf13 +.PHONY: tab +tab: elf01 elf02 elf03 elf04 elf05 elf06 elf07 elf08 elf09 elf10 elf11 elf12 elf13 elf2tab --kernel-major 2 --kernel-minor 0 -n $(EXAMPLE) -o $(EXAMPLE).tab --stack 1024 --minimum-footer-size 256 $(ELF_LIST) # Creates the `make EXAMPLE=` targets. Arguments: From 86ae365f1efad96c24b577078ef0aaad1407e0c0 Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Fri, 4 Aug 2023 10:17:22 -0400 Subject: [PATCH 21/31] make: generate rules no need to specify target names manually --- Makefile | 70 ++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 22 deletions(-) diff --git a/Makefile b/Makefile index be05ba5d..cc035066 100644 --- a/Makefile +++ b/Makefile @@ -127,39 +127,65 @@ test: examples test-stable cargo miri test $(EXCLUDE_MIRI) --workspace echo '[ SUCCESS ] libtock-rs tests pass' -# Helper function to define target variables. -# https://stackoverflow.com/questions/50322607/multiple-target-specific-variable-values -assign-vars = $(foreach A,$2,$(eval $1: $A)) +# Helper functions to define make targets to build for specific (flash, ram, +# target) compilation tuples. +# +# Inspiration from these answers: +# - https://stackoverflow.com/a/50357925 +# - https://stackoverflow.com/a/9458230 +# +# To create a compilation target for a specific architecture with specific flash +# and RAM addresses, use `fixed-target`: +# +# ``` +# $(call fixed-target, F=0x00030000 R=0x20008000 T=thumbv7em-none-eabi A=cortex-m4) +# ``` +# +# The "arguments" if you will are: +# - F = Flash Address: The address in flash the app is compiled for. +# - R = RAM Address: The address in RAM the app is compiled for. +# - T = Target: The cargo target to compile for. +# - A = Architecture: The Tock architecture name the target corresponds to. +# +# This technique uses two make variables internally to keep track of state: +# - `ELF_TARGETS`: This is the list of unique targets for each compilation +# tuple. Each target invokes `cargo build` with the specified settings. +# - `ELF_LIST`: The is a list of .elf paths of the generated elfs (one per +# compilation tuple). This is passed to `elf2tab` to generate the output .tab +# file. +# +# Internally, what `fixed-target` does is define a new make target named the +# join of all of the F/R/T/A variables (with the `=` characters removed) and +# then assigns target variables to that new target to represent the compilation +# tuple values. +concat = $(subst =,,$(subst $(eval ) ,,$1)) +fixed-target = $(foreach A,$1,$(eval $(call concat,$1): $A)) $(eval ELF_TARGETS += $(call concat,$1)) -# F = Flash Address -# R = RAM Address -# T = Target -# A = Architecture -$(call assign-vars, elf01, F=0x00030000 R=0x20008000 T=thumbv7em-none-eabi A=cortex-m4) -$(call assign-vars, elf02, F=0x00038000 R=0x20010000 T=thumbv7em-none-eabi A=cortex-m4) +$(call fixed-target, F=0x00030000 R=0x20008000 T=thumbv7em-none-eabi A=cortex-m4) +$(call fixed-target, F=0x00038000 R=0x20010000 T=thumbv7em-none-eabi A=cortex-m4) -$(call assign-vars, elf03, F=0x00040000 R=0x10002000 T=thumbv7em-none-eabi A=cortex-m4) -$(call assign-vars, elf04, F=0x00048000 R=0x1000a000 T=thumbv7em-none-eabi A=cortex-m4) +$(call fixed-target, F=0x00040000 R=0x10002000 T=thumbv7em-none-eabi A=cortex-m4) +$(call fixed-target, F=0x00048000 R=0x1000a000 T=thumbv7em-none-eabi A=cortex-m4) -$(call assign-vars, elf05, F=0x00040000 R=0x20008000 T=thumbv7em-none-eabi A=cortex-m4) -$(call assign-vars, elf06, F=0x00042000 R=0x2000a000 T=thumbv7em-none-eabi A=cortex-m4) -$(call assign-vars, elf07, F=0x00048000 R=0x20010000 T=thumbv7em-none-eabi A=cortex-m4) +$(call fixed-target, F=0x00040000 R=0x20008000 T=thumbv7em-none-eabi A=cortex-m4) +$(call fixed-target, F=0x00042000 R=0x2000a000 T=thumbv7em-none-eabi A=cortex-m4) +$(call fixed-target, F=0x00048000 R=0x20010000 T=thumbv7em-none-eabi A=cortex-m4) -$(call assign-vars, elf08, F=0x00080000 R=0x20006000 T=thumbv7em-none-eabi A=cortex-m4) -$(call assign-vars, elf09, F=0x00088000 R=0x2000e000 T=thumbv7em-none-eabi A=cortex-m4) +$(call fixed-target, F=0x00080000 R=0x20006000 T=thumbv7em-none-eabi A=cortex-m4) +$(call fixed-target, F=0x00088000 R=0x2000e000 T=thumbv7em-none-eabi A=cortex-m4) -$(call assign-vars, elf10, F=0x403b0000 R=0x3fca2000 T=riscv32imc-unknown-none-elf A=riscv32imc) -$(call assign-vars, elf11, F=0x40440000 R=0x3fcaa000 T=riscv32imc-unknown-none-elf A=riscv32imc) +$(call fixed-target, F=0x403b0000 R=0x3fca2000 T=riscv32imc-unknown-none-elf A=riscv32imc) +$(call fixed-target, F=0x40440000 R=0x3fcaa000 T=riscv32imc-unknown-none-elf A=riscv32imc) -$(call assign-vars, elf12, F=0x10020000 R=0x20004000 T=thumbv6m-none-eabi A=cortex-m0) -$(call assign-vars, elf13, F=0x10028000 R=0x2000c000 T=thumbv6m-none-eabi A=cortex-m0) +$(call fixed-target, F=0x10020000 R=0x20004000 T=thumbv6m-none-eabi A=cortex-m0) +$(call fixed-target, F=0x10028000 R=0x2000c000 T=thumbv6m-none-eabi A=cortex-m0) -elf01 elf02 elf03 elf04 elf05 elf06 elf07 elf08 elf09 elf10 elf11 elf12 elf13: +$(ELF_TARGETS): LINKER_FLASH=$(F) LINKER_RAM=$(R) cargo build --example $(EXAMPLE) $(features) --target=$(T) $(release) --out-dir target/$(A).$(F).$(R) -Z unstable-options $(eval ELF_LIST += target/$(A).$(F).$(R)/$(EXAMPLE),$(A).$(F).$(R)) .PHONY: tab -tab: elf01 elf02 elf03 elf04 elf05 elf06 elf07 elf08 elf09 elf10 elf11 elf12 elf13 +tab: $(ELF_TARGETS) elf2tab --kernel-major 2 --kernel-minor 0 -n $(EXAMPLE) -o $(EXAMPLE).tab --stack 1024 --minimum-footer-size 256 $(ELF_LIST) # Creates the `make EXAMPLE=` targets. Arguments: From e8ad310c8b6df40b0db84019a828ec1bc3e15db6 Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Mon, 7 Aug 2023 10:58:54 -0400 Subject: [PATCH 22/31] readme: update readme with `make tab` info --- README.md | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index aeec0efb..1ee36c62 100644 --- a/README.md +++ b/README.md @@ -9,11 +9,10 @@ Generally this library was tested with Tock [Release The library should work on all Tock boards, but currently apps must be compiled for the flash and RAM address they are executed at. See [Fix -relocation](https://github.com/tock/libtock-rs/issues/28) for more details. -This means that process binaries 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. +relocation](https://github.com/tock/libtock-rs/issues/28) for more details. You +may either compile a process binary especially for your board and use only a +single application written in rust at a time, or use the `make tab` target that +builds examples for a series of likely useful flash and RAM addresses. ## Getting Started @@ -44,6 +43,8 @@ The easiest way to start using libtock-rs is adding an example to the `examples/` folder. We recommend starting by copying the `console` example, as it is a simple example that shows you how to perform normal debug prints. +### Building for a specific board + To build your example for your board you can use ```shell @@ -62,6 +63,23 @@ This script does the following steps for you: - create a TAB (tock application bundle) - if you have a J-Link compatible board connected: flash this TAB to your board (using tockloader) +### Building a generic TAB (Tock Application Bundle) file + +To build your example for a variety of boards you can use + +```shell +make tab EXAMPLE= +``` + +To install the tab use tockloader + +```shell +tockloader install +``` + +Tockloader will determine which compiled version with the correct flash and RAM +addresses to use. + ## License From 0ce8ea271f5f0400590e201129c615ad9c3b802b Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Mon, 7 Aug 2023 11:21:33 -0400 Subject: [PATCH 23/31] add libtock_runtime_build to EXCLUDE_STD --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index cc035066..f603c803 100644 --- a/Makefile +++ b/Makefile @@ -101,7 +101,8 @@ EXCLUDE_MIRI := $(EXCLUDE_RUNTIME) --exclude ufmt-macros # Arguments to pass to cargo to exclude `std` and crates that depend on it. Used # when we build a crate for an embedded target, as those targets lack `std`. EXCLUDE_STD := --exclude libtock_unittest --exclude print_sizes \ - --exclude runner --exclude syscalls_tests + --exclude runner --exclude syscalls_tests \ + --exclude libtock_runtime_build # Currently, all of our crates should build with a stable toolchain. This # verifies our crates don't depend on unstable features by using cargo check. We From ebffaf99ba279cf6b52cb48acf08d96e5790df34 Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Mon, 7 Aug 2023 15:03:33 -0400 Subject: [PATCH 24/31] libtock build: fix clippy suggestions --- libtock_runtime_build/src/lib.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libtock_runtime_build/src/lib.rs b/libtock_runtime_build/src/lib.rs index e70c7ff0..d1e299ca 100644 --- a/libtock_runtime_build/src/lib.rs +++ b/libtock_runtime_build/src/lib.rs @@ -93,12 +93,12 @@ pub fn auto_layout() { let linker_script_name = format!("{}.{}.ld", linker_flash, linker_ram); let out_platform_path: PathBuf = [out_dir, &linker_script_name].iter().collect(); let mut file = File::create(out_platform_path).expect("Could not create linker file"); - write!(file, "TBF_HEADER_SIZE = 0x80;\n").expect("Could not write linker file"); - write!(file, "FLASH_START = {};\n", linker_flash).expect("Could not write linker file"); - write!(file, "FLASH_LENGTH = 0x000D0000;\n",).expect("Could not write linker file"); - write!(file, "RAM_START = {};\n", linker_ram).expect("Could not write linker file"); - write!(file, "RAM_LENGTH = 46K;\n",).expect("Could not write linker file"); - write!(file, "INCLUDE libtock_layout.ld\n").expect("Could not write linker file"); + writeln!(file, "TBF_HEADER_SIZE = 0x80;").expect("Could not write linker file"); + writeln!(file, "FLASH_START = {};", linker_flash).expect("Could not write linker file"); + writeln!(file, "FLASH_LENGTH = 0x000D0000;",).expect("Could not write linker file"); + writeln!(file, "RAM_START = {};", linker_ram).expect("Could not write linker file"); + writeln!(file, "RAM_LENGTH = 46K;",).expect("Could not write linker file"); + writeln!(file, "INCLUDE libtock_layout.ld").expect("Could not write linker file"); // Pass the name of this linker script to rustc. println!("cargo:rustc-link-arg=-T{}", linker_script_name); From 6829e1d1088e7631f534bb03aae52398db776e9e Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Mon, 7 Aug 2023 15:27:13 -0400 Subject: [PATCH 25/31] libtock_runtime_build -> libtock_build_scripts --- Cargo.toml | 2 +- Makefile | 2 +- build.rs | 2 +- {libtock_runtime_build => build_scripts}/Cargo.toml | 2 +- {libtock_runtime_build => build_scripts}/README.md | 6 +++--- {libtock_runtime_build => build_scripts}/build.rs | 0 {libtock_runtime_build => build_scripts}/layouts/apollo3.ld | 0 .../layouts/clue_nrf52840.ld | 0 .../layouts/esp32_c3_devkitm_1.ld | 0 {libtock_runtime_build => build_scripts}/layouts/hail.ld | 0 {libtock_runtime_build => build_scripts}/layouts/hifive1.ld | 0 {libtock_runtime_build => build_scripts}/layouts/imix.ld | 0 .../layouts/imxrt1050.ld | 0 .../layouts/microbit_v2.ld | 0 {libtock_runtime_build => build_scripts}/layouts/msp432.ld | 0 .../layouts/nano_rp2040_connect.ld | 0 {libtock_runtime_build => build_scripts}/layouts/nrf52.ld | 0 .../layouts/nrf52840.ld | 0 .../layouts/nucleo_f429zi.ld | 0 .../layouts/nucleo_f446re.ld | 0 .../layouts/opentitan.ld | 0 .../layouts/raspberry_pi_pico.ld | 0 .../layouts/stm32f3discovery.ld | 0 .../layouts/stm32f412gdiscovery.ld | 0 {libtock_runtime_build => build_scripts}/libtock_layout.ld | 0 {libtock_runtime_build => build_scripts}/src/lib.rs | 0 26 files changed, 7 insertions(+), 7 deletions(-) rename {libtock_runtime_build => build_scripts}/Cargo.toml (90%) rename {libtock_runtime_build => build_scripts}/README.md (92%) rename {libtock_runtime_build => build_scripts}/build.rs (100%) rename {libtock_runtime_build => build_scripts}/layouts/apollo3.ld (100%) rename {libtock_runtime_build => build_scripts}/layouts/clue_nrf52840.ld (100%) rename {libtock_runtime_build => build_scripts}/layouts/esp32_c3_devkitm_1.ld (100%) rename {libtock_runtime_build => build_scripts}/layouts/hail.ld (100%) rename {libtock_runtime_build => build_scripts}/layouts/hifive1.ld (100%) rename {libtock_runtime_build => build_scripts}/layouts/imix.ld (100%) rename {libtock_runtime_build => build_scripts}/layouts/imxrt1050.ld (100%) rename {libtock_runtime_build => build_scripts}/layouts/microbit_v2.ld (100%) rename {libtock_runtime_build => build_scripts}/layouts/msp432.ld (100%) rename {libtock_runtime_build => build_scripts}/layouts/nano_rp2040_connect.ld (100%) rename {libtock_runtime_build => build_scripts}/layouts/nrf52.ld (100%) rename {libtock_runtime_build => build_scripts}/layouts/nrf52840.ld (100%) rename {libtock_runtime_build => build_scripts}/layouts/nucleo_f429zi.ld (100%) rename {libtock_runtime_build => build_scripts}/layouts/nucleo_f446re.ld (100%) rename {libtock_runtime_build => build_scripts}/layouts/opentitan.ld (100%) rename {libtock_runtime_build => build_scripts}/layouts/raspberry_pi_pico.ld (100%) rename {libtock_runtime_build => build_scripts}/layouts/stm32f3discovery.ld (100%) rename {libtock_runtime_build => build_scripts}/layouts/stm32f412gdiscovery.ld (100%) rename {libtock_runtime_build => build_scripts}/libtock_layout.ld (100%) rename {libtock_runtime_build => build_scripts}/src/lib.rs (100%) diff --git a/Cargo.toml b/Cargo.toml index 9c6275a1..1ae3b4cc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,7 @@ libtock_sound_pressure = {path = "apis/sound_pressure"} libtock_temperature = { path = "apis/temperature" } [build-dependencies] -libtock_runtime_build = { path = "libtock_runtime_build"} +libtock_build_scripts = { path = "build_scripts"} [profile.dev] panic = "abort" diff --git a/Makefile b/Makefile index f603c803..9f22cae0 100644 --- a/Makefile +++ b/Makefile @@ -102,7 +102,7 @@ EXCLUDE_MIRI := $(EXCLUDE_RUNTIME) --exclude ufmt-macros # when we build a crate for an embedded target, as those targets lack `std`. EXCLUDE_STD := --exclude libtock_unittest --exclude print_sizes \ --exclude runner --exclude syscalls_tests \ - --exclude libtock_runtime_build + --exclude libtock_build_scripts # Currently, all of our crates should build with a stable toolchain. This # verifies our crates don't depend on unstable features by using cargo check. We diff --git a/build.rs b/build.rs index d83f5bb0..d39f0124 100644 --- a/build.rs +++ b/build.rs @@ -1,3 +1,3 @@ fn main() { - libtock_runtime_build::auto_layout(); + libtock_build_scripts::auto_layout(); } diff --git a/libtock_runtime_build/Cargo.toml b/build_scripts/Cargo.toml similarity index 90% rename from libtock_runtime_build/Cargo.toml rename to build_scripts/Cargo.toml index e4b2f7b0..3cdcb510 100644 --- a/libtock_runtime_build/Cargo.toml +++ b/build_scripts/Cargo.toml @@ -4,6 +4,6 @@ categories = ["embedded", "no-std", "os"] description = """Helper functions for compiling libtock-rs apps.""" edition = "2021" license = "Apache-2.0 OR MIT" -name = "libtock_runtime_build" +name = "libtock_build_scripts" repository = "https://www.github.com/tock/libtock-rs" version = "0.1.0" diff --git a/libtock_runtime_build/README.md b/build_scripts/README.md similarity index 92% rename from libtock_runtime_build/README.md rename to build_scripts/README.md index 470e3cfc..e7ee399c 100644 --- a/libtock_runtime_build/README.md +++ b/build_scripts/README.md @@ -1,4 +1,4 @@ -Libtock Runtime Build Support Crate +Libtock Build Scripts Support Crate =================================== This crate provides helpers for building libtock-rs apps. @@ -16,7 +16,7 @@ There are three general steps to use this crate. ... [build-dependencies] - libtock_runtime_build = { git = "https://github.com/tock/libtock-rs"} + libtock_build_scripts = { git = "https://github.com/tock/libtock-rs"} ``` This will ensure the crate and the contained linker scripts are available for @@ -30,7 +30,7 @@ There are three general steps to use this crate. // build.rs fn main() { - libtock_runtime_build::auto_layout(); + libtock_build_scripts::auto_layout(); } ``` diff --git a/libtock_runtime_build/build.rs b/build_scripts/build.rs similarity index 100% rename from libtock_runtime_build/build.rs rename to build_scripts/build.rs diff --git a/libtock_runtime_build/layouts/apollo3.ld b/build_scripts/layouts/apollo3.ld similarity index 100% rename from libtock_runtime_build/layouts/apollo3.ld rename to build_scripts/layouts/apollo3.ld diff --git a/libtock_runtime_build/layouts/clue_nrf52840.ld b/build_scripts/layouts/clue_nrf52840.ld similarity index 100% rename from libtock_runtime_build/layouts/clue_nrf52840.ld rename to build_scripts/layouts/clue_nrf52840.ld diff --git a/libtock_runtime_build/layouts/esp32_c3_devkitm_1.ld b/build_scripts/layouts/esp32_c3_devkitm_1.ld similarity index 100% rename from libtock_runtime_build/layouts/esp32_c3_devkitm_1.ld rename to build_scripts/layouts/esp32_c3_devkitm_1.ld diff --git a/libtock_runtime_build/layouts/hail.ld b/build_scripts/layouts/hail.ld similarity index 100% rename from libtock_runtime_build/layouts/hail.ld rename to build_scripts/layouts/hail.ld diff --git a/libtock_runtime_build/layouts/hifive1.ld b/build_scripts/layouts/hifive1.ld similarity index 100% rename from libtock_runtime_build/layouts/hifive1.ld rename to build_scripts/layouts/hifive1.ld diff --git a/libtock_runtime_build/layouts/imix.ld b/build_scripts/layouts/imix.ld similarity index 100% rename from libtock_runtime_build/layouts/imix.ld rename to build_scripts/layouts/imix.ld diff --git a/libtock_runtime_build/layouts/imxrt1050.ld b/build_scripts/layouts/imxrt1050.ld similarity index 100% rename from libtock_runtime_build/layouts/imxrt1050.ld rename to build_scripts/layouts/imxrt1050.ld diff --git a/libtock_runtime_build/layouts/microbit_v2.ld b/build_scripts/layouts/microbit_v2.ld similarity index 100% rename from libtock_runtime_build/layouts/microbit_v2.ld rename to build_scripts/layouts/microbit_v2.ld diff --git a/libtock_runtime_build/layouts/msp432.ld b/build_scripts/layouts/msp432.ld similarity index 100% rename from libtock_runtime_build/layouts/msp432.ld rename to build_scripts/layouts/msp432.ld diff --git a/libtock_runtime_build/layouts/nano_rp2040_connect.ld b/build_scripts/layouts/nano_rp2040_connect.ld similarity index 100% rename from libtock_runtime_build/layouts/nano_rp2040_connect.ld rename to build_scripts/layouts/nano_rp2040_connect.ld diff --git a/libtock_runtime_build/layouts/nrf52.ld b/build_scripts/layouts/nrf52.ld similarity index 100% rename from libtock_runtime_build/layouts/nrf52.ld rename to build_scripts/layouts/nrf52.ld diff --git a/libtock_runtime_build/layouts/nrf52840.ld b/build_scripts/layouts/nrf52840.ld similarity index 100% rename from libtock_runtime_build/layouts/nrf52840.ld rename to build_scripts/layouts/nrf52840.ld diff --git a/libtock_runtime_build/layouts/nucleo_f429zi.ld b/build_scripts/layouts/nucleo_f429zi.ld similarity index 100% rename from libtock_runtime_build/layouts/nucleo_f429zi.ld rename to build_scripts/layouts/nucleo_f429zi.ld diff --git a/libtock_runtime_build/layouts/nucleo_f446re.ld b/build_scripts/layouts/nucleo_f446re.ld similarity index 100% rename from libtock_runtime_build/layouts/nucleo_f446re.ld rename to build_scripts/layouts/nucleo_f446re.ld diff --git a/libtock_runtime_build/layouts/opentitan.ld b/build_scripts/layouts/opentitan.ld similarity index 100% rename from libtock_runtime_build/layouts/opentitan.ld rename to build_scripts/layouts/opentitan.ld diff --git a/libtock_runtime_build/layouts/raspberry_pi_pico.ld b/build_scripts/layouts/raspberry_pi_pico.ld similarity index 100% rename from libtock_runtime_build/layouts/raspberry_pi_pico.ld rename to build_scripts/layouts/raspberry_pi_pico.ld diff --git a/libtock_runtime_build/layouts/stm32f3discovery.ld b/build_scripts/layouts/stm32f3discovery.ld similarity index 100% rename from libtock_runtime_build/layouts/stm32f3discovery.ld rename to build_scripts/layouts/stm32f3discovery.ld diff --git a/libtock_runtime_build/layouts/stm32f412gdiscovery.ld b/build_scripts/layouts/stm32f412gdiscovery.ld similarity index 100% rename from libtock_runtime_build/layouts/stm32f412gdiscovery.ld rename to build_scripts/layouts/stm32f412gdiscovery.ld diff --git a/libtock_runtime_build/libtock_layout.ld b/build_scripts/libtock_layout.ld similarity index 100% rename from libtock_runtime_build/libtock_layout.ld rename to build_scripts/libtock_layout.ld diff --git a/libtock_runtime_build/src/lib.rs b/build_scripts/src/lib.rs similarity index 100% rename from libtock_runtime_build/src/lib.rs rename to build_scripts/src/lib.rs From adefcf560d280ad0be7075f72df70965c2954348 Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Mon, 7 Aug 2023 15:34:55 -0400 Subject: [PATCH 26/31] build_scripts: use LIBTOCK_ env variables --- Makefile | 2 +- build_scripts/README.md | 12 ++++++------ build_scripts/build.rs | 2 +- build_scripts/src/lib.rs | 20 ++++++++++---------- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Makefile b/Makefile index 9f22cae0..4fa9bd9f 100644 --- a/Makefile +++ b/Makefile @@ -182,7 +182,7 @@ $(call fixed-target, F=0x10020000 R=0x20004000 T=thumbv6m-none-eabi A=cortex-m0) $(call fixed-target, F=0x10028000 R=0x2000c000 T=thumbv6m-none-eabi A=cortex-m0) $(ELF_TARGETS): - LINKER_FLASH=$(F) LINKER_RAM=$(R) cargo build --example $(EXAMPLE) $(features) --target=$(T) $(release) --out-dir target/$(A).$(F).$(R) -Z unstable-options + LIBTOCK_LINKER_FLASH=$(F) LIBTOCK_LINKER_RAM=$(R) cargo build --example $(EXAMPLE) $(features) --target=$(T) $(release) --out-dir target/$(A).$(F).$(R) -Z unstable-options $(eval ELF_LIST += target/$(A).$(F).$(R)/$(EXAMPLE),$(A).$(F).$(R)) .PHONY: tab diff --git a/build_scripts/README.md b/build_scripts/README.md index e7ee399c..240ecfe7 100644 --- a/build_scripts/README.md +++ b/build_scripts/README.md @@ -49,12 +49,12 @@ There are three general steps to use this crate. $ LIBTOCK_PLATFORM=microbit_v2 cargo build --target thumbv7em-none-eabi --release ``` - 2. Set the `LINKER_FLASH` and `LINKER_RAM` environment variables which - specify the starting addresses of flash and RAM memory, respectively. This - allows you to customize where exactly the compiled app must be placed in - flash and RAM. For example, to build for common Cortex-M4 platforms you - might run: + 2. Set the `LIBTOCK_LINKER_FLASH` and `LIBTOCK_LINKER_RAM` environment + variables which specify the starting addresses of flash and RAM memory, + respectively. This allows you to customize where exactly the compiled app + must be placed in flash and RAM. For example, to build for common + Cortex-M4 platforms you might run: ```bash - $ LINKER_FLASH=0x00040000 LINKER_RAM=0x20008000 cargo build --target thumbv7em-none-eabi --release + $ LIBTOCK_LINKER_FLASH=0x00040000 LIBTOCK_LINKER_RAM=0x20008000 cargo build --target thumbv7em-none-eabi --release ``` diff --git a/build_scripts/build.rs b/build_scripts/build.rs index 1c1de5c4..daa4e992 100644 --- a/build_scripts/build.rs +++ b/build_scripts/build.rs @@ -20,7 +20,7 @@ fn main() { // Share the out dir of this crate with the actual source so we know where // we put the linker scripts. - println!("cargo:rustc-env=LIBTOCK_RUNTIME_BUILD_OUT_DIR={}", out_dir); + println!("cargo:rustc-env=LIBTOCK_BUILD_SCRIPTS_OUT_DIR={}", out_dir); // Copy all platform linker scripts to a directory where the linker can find // them. diff --git a/build_scripts/src/lib.rs b/build_scripts/src/lib.rs index d1e299ca..2362b77f 100644 --- a/build_scripts/src/lib.rs +++ b/build_scripts/src/lib.rs @@ -4,7 +4,7 @@ /// This allows this file to know the path of its own local outdir where copies /// of linker scripts are stored (by this crate's build.rs). That path can then /// be used in other libtock-rs compilations to provide useful linker scripts. -pub const RUNTIME_BUILD_OUT_DIR: &str = env!("LIBTOCK_RUNTIME_BUILD_OUT_DIR"); +pub const BUILD_SCRIPTS_OUT_DIR: &str = env!("LIBTOCK_BUILD_SCRIPTS_OUT_DIR"); /// Helper function to configure cargo to use suitable linker scripts for /// linking libtock-rs apps. @@ -22,20 +22,20 @@ pub const RUNTIME_BUILD_OUT_DIR: &str = env!("LIBTOCK_RUNTIME_BUILD_OUT_DIR"); /// /// This function supports two methods for doing this: /// -/// 1. Passing the `LIBTOCK_PLATFORM` environment variable which specifies -/// the name of the linker script in `/layouts` to be used. +/// 1. Passing the `LIBTOCK_LIBTOCK_PLATFORM` environment variable which +/// specifies the name of the linker script in `/layouts` to be used. /// -/// 2. Passing the `LINKER_FLASH` and `LINKER_RAM` environment variables -/// which specify the starting addresses of flash and RAM memory, -/// respectively. +/// 2. Passing the `LIBTOCK_LINKER_FLASH` and `LINKER_RAM` environment +/// variables which specify the starting addresses of flash and RAM +/// memory, respectively. pub fn auto_layout() { use std::fs::File; use std::io::Write; use std::path::PathBuf; const PLATFORM_CFG_VAR: &str = "LIBTOCK_PLATFORM"; - const LINKER_FLASH_CFG_VAR: &str = "LINKER_FLASH"; - const LINKER_RAM_CFG_VAR: &str = "LINKER_RAM"; + const LINKER_FLASH_CFG_VAR: &str = "LIBTOCK_LINKER_FLASH"; + const LINKER_RAM_CFG_VAR: &str = "LIBTOCK_LINKER_RAM"; // Note: we need to print these rerun-if commands before using the variable // or file, so that if the build script fails cargo knows when to re-run it. @@ -57,7 +57,7 @@ pub fn auto_layout() { // Set the linker search path to the out dir of this crate where we have // stored all of the linker files. - println!("cargo:rustc-link-search={}", RUNTIME_BUILD_OUT_DIR); + println!("cargo:rustc-link-search={}", BUILD_SCRIPTS_OUT_DIR); // Choose the linker file we are going to use for this build. That can be // specified by choosing a platform, where the linker file will be selected @@ -106,6 +106,6 @@ pub fn auto_layout() { // Tell rustc where to search for the layout file. println!("cargo:rustc-link-search={}", out_dir); } else { - panic!("Need to set LIBTOCK_PLATFORM or (LINKER_FLASH and LINKER_RAM)"); + panic!("Need to set LIBTOCK_PLATFORM or (LIBTOCK_LINKER_FLASH and LIBTOCK_LINKER_RAM)"); } } From 2e95f628a0693886730f63054981284cab8571e7 Mon Sep 17 00:00:00 2001 From: Johnathan Van Why Date: Mon, 7 Aug 2023 15:15:44 -0700 Subject: [PATCH 27/31] Remove `build_scripts/build.rs`. Instead of copying the linker script files into a directory that `no_auto_layout` can read, this includes `libtock_layout.ld` as a string in the `libtock_build_scripts` library and generates the per-platform linker script. --- build_scripts/build.rs | 44 ---- build_scripts/layouts/apollo3.ld | 11 - build_scripts/layouts/clue_nrf52840.ld | 11 - build_scripts/layouts/esp32_c3_devkitm_1.ld | 11 - build_scripts/layouts/hail.ld | 11 - build_scripts/layouts/hifive1.ld | 11 - build_scripts/layouts/imix.ld | 11 - build_scripts/layouts/imxrt1050.ld | 11 - build_scripts/layouts/microbit_v2.ld | 11 - build_scripts/layouts/msp432.ld | 9 - build_scripts/layouts/nano_rp2040_connect.ld | 11 - build_scripts/layouts/nrf52.ld | 11 - build_scripts/layouts/nrf52840.ld | 11 - build_scripts/layouts/nucleo_f429zi.ld | 11 - build_scripts/layouts/nucleo_f446re.ld | 11 - build_scripts/layouts/opentitan.ld | 11 - build_scripts/layouts/raspberry_pi_pico.ld | 11 - build_scripts/layouts/stm32f3discovery.ld | 11 - build_scripts/layouts/stm32f412gdiscovery.ld | 11 - build_scripts/src/lib.rs | 232 +++++++++++++------ 20 files changed, 155 insertions(+), 317 deletions(-) delete mode 100644 build_scripts/build.rs delete mode 100644 build_scripts/layouts/apollo3.ld delete mode 100644 build_scripts/layouts/clue_nrf52840.ld delete mode 100644 build_scripts/layouts/esp32_c3_devkitm_1.ld delete mode 100644 build_scripts/layouts/hail.ld delete mode 100644 build_scripts/layouts/hifive1.ld delete mode 100644 build_scripts/layouts/imix.ld delete mode 100644 build_scripts/layouts/imxrt1050.ld delete mode 100644 build_scripts/layouts/microbit_v2.ld delete mode 100644 build_scripts/layouts/msp432.ld delete mode 100644 build_scripts/layouts/nano_rp2040_connect.ld delete mode 100644 build_scripts/layouts/nrf52.ld delete mode 100644 build_scripts/layouts/nrf52840.ld delete mode 100644 build_scripts/layouts/nucleo_f429zi.ld delete mode 100644 build_scripts/layouts/nucleo_f446re.ld delete mode 100644 build_scripts/layouts/opentitan.ld delete mode 100644 build_scripts/layouts/raspberry_pi_pico.ld delete mode 100644 build_scripts/layouts/stm32f3discovery.ld delete mode 100644 build_scripts/layouts/stm32f412gdiscovery.ld diff --git a/build_scripts/build.rs b/build_scripts/build.rs deleted file mode 100644 index daa4e992..00000000 --- a/build_scripts/build.rs +++ /dev/null @@ -1,44 +0,0 @@ -//! This build.rs makes common linker scripts available when linking libtock-rs -//! apps. - -fn main() { - use std::fs::copy; - use std::fs::read_dir; - use std::path::PathBuf; - - const LAYOUT_GENERIC_FILENAME: &str = "libtock_layout.ld"; - - // Note: cargo fails if run in a path that is not valid Unicode, so this - // script doesn't need to handle non-Unicode paths. Also, OUT_DIR cannot be - // in a location with a newline in it, or we have no way to pass - // rustc-link-search to cargo. - let out_dir = &std::env::var("OUT_DIR").expect("Unable to read OUT_DIR"); - assert!( - !out_dir.contains('\n'), - "Build path contains a newline, which is unsupported" - ); - - // Share the out dir of this crate with the actual source so we know where - // we put the linker scripts. - println!("cargo:rustc-env=LIBTOCK_BUILD_SCRIPTS_OUT_DIR={}", out_dir); - - // Copy all platform linker scripts to a directory where the linker can find - // them. - let paths = read_dir("layouts").unwrap(); - for path in paths { - let ld_path = path.as_ref().unwrap().path(); - let ld_name = path.as_ref().unwrap().file_name().into_string().unwrap(); - let out_ld_path: PathBuf = [out_dir, &ld_name].iter().collect(); - copy(ld_path, out_ld_path).expect("Unable to copy platform layout into OUT_DIR"); - } - - // Copy the generic layout file into OUT_DIR. - let out_layout_generic: PathBuf = [out_dir, LAYOUT_GENERIC_FILENAME].iter().collect(); - println!("cargo:rerun-if-changed={}", LAYOUT_GENERIC_FILENAME); - copy(LAYOUT_GENERIC_FILENAME, out_layout_generic) - .expect("Unable to copy layout_generic.ld into OUT_DIR"); - - // Tell the linker that it can find linker scripts in the out directory of - // the libtock_runtime crate. - println!("cargo:rustc-link-search={}", out_dir); -} diff --git a/build_scripts/layouts/apollo3.ld b/build_scripts/layouts/apollo3.ld deleted file mode 100644 index aa1ab716..00000000 --- a/build_scripts/layouts/apollo3.ld +++ /dev/null @@ -1,11 +0,0 @@ -/* Layout for the Apollo3 MCU, used by the examples in this repository. */ - -TBF_HEADER_SIZE = 0x60; - -FLASH_START = 0x00040000; -FLASH_LENGTH = 0x00060000; - -RAM_START = 0x10002000; -RAM_LENGTH = 0x2000; - -INCLUDE libtock_layout.ld diff --git a/build_scripts/layouts/clue_nrf52840.ld b/build_scripts/layouts/clue_nrf52840.ld deleted file mode 100644 index 46c06610..00000000 --- a/build_scripts/layouts/clue_nrf52840.ld +++ /dev/null @@ -1,11 +0,0 @@ -/* Layout for the micro:bit v2 board, used by the examples in this repository. */ - -TBF_HEADER_SIZE = 0x60; - -FLASH_START = 0x00080000; -FLASH_LENGTH = 512K; - -RAM_START = 0x20006000; -RAM_LENGTH = 216K; - -INCLUDE libtock_layout.ld diff --git a/build_scripts/layouts/esp32_c3_devkitm_1.ld b/build_scripts/layouts/esp32_c3_devkitm_1.ld deleted file mode 100644 index a2aa5c40..00000000 --- a/build_scripts/layouts/esp32_c3_devkitm_1.ld +++ /dev/null @@ -1,11 +0,0 @@ -/* Layout for the esp32c3 DevKit M1 board, used by the examples in this repository. */ - -TBF_HEADER_SIZE = 0x60; - -FLASH_START = 0x403B0000; -FLASH_LENGTH = 0x30000; - -RAM_START = 0x3FCA2000; -RAM_LENGTH = 0x2E000; - -INCLUDE libtock_layout.ld diff --git a/build_scripts/layouts/hail.ld b/build_scripts/layouts/hail.ld deleted file mode 100644 index 8e8a790b..00000000 --- a/build_scripts/layouts/hail.ld +++ /dev/null @@ -1,11 +0,0 @@ -/* Layout for the Hail board, used by the examples in this repository. */ - -TBF_HEADER_SIZE = 0x60; - -FLASH_START = 0x00030000; -FLASH_LENGTH = 0x00040000; - -RAM_START = 0x20008000; -RAM_LENGTH = 62K; - -INCLUDE libtock_layout.ld diff --git a/build_scripts/layouts/hifive1.ld b/build_scripts/layouts/hifive1.ld deleted file mode 100644 index de02227e..00000000 --- a/build_scripts/layouts/hifive1.ld +++ /dev/null @@ -1,11 +0,0 @@ -/* Layout for the RISC-V 32 boards, used by the examples in this repository. */ - -TBF_HEADER_SIZE = 0x60; - -FLASH_START = 0x20040000; -FLASH_LENGTH = 32M; - -RAM_START = 0x80003000; -RAM_LENGTH = 0x1000; - -INCLUDE libtock_layout.ld diff --git a/build_scripts/layouts/imix.ld b/build_scripts/layouts/imix.ld deleted file mode 100644 index 2b88e8c7..00000000 --- a/build_scripts/layouts/imix.ld +++ /dev/null @@ -1,11 +0,0 @@ -/* Layout for the Imix board, used by the examples in this repository. */ - -TBF_HEADER_SIZE = 0x60; - -FLASH_START = 0x00040000; -FLASH_LENGTH = 0x00040000; - -RAM_START = 0x20008000; -RAM_LENGTH = 62K; - -INCLUDE libtock_layout.ld diff --git a/build_scripts/layouts/imxrt1050.ld b/build_scripts/layouts/imxrt1050.ld deleted file mode 100644 index e4c6bfe2..00000000 --- a/build_scripts/layouts/imxrt1050.ld +++ /dev/null @@ -1,11 +0,0 @@ -/* Layout for the iMX.RT1050 board, used by the examples in this repository. */ - -TBF_HEADER_SIZE = 0x60; - -FLASH_START = 0x63002000; -FLASH_LENGTH = 0x1000000; - -RAM_START = 0x20004000; -RAM_LENGTH = 112K; - -INCLUDE libtock_layout.ld diff --git a/build_scripts/layouts/microbit_v2.ld b/build_scripts/layouts/microbit_v2.ld deleted file mode 100644 index d5a3f387..00000000 --- a/build_scripts/layouts/microbit_v2.ld +++ /dev/null @@ -1,11 +0,0 @@ -/* Layout for the micro:bit v2 board, used by the examples in this repository. */ - -TBF_HEADER_SIZE = 0x60; - -FLASH_START = 0x00040000; -FLASH_LENGTH = 256K; - -RAM_START = 0x20004000; -RAM_LENGTH = 112K; - -INCLUDE libtock_layout.ld diff --git a/build_scripts/layouts/msp432.ld b/build_scripts/layouts/msp432.ld deleted file mode 100644 index 3ffb351b..00000000 --- a/build_scripts/layouts/msp432.ld +++ /dev/null @@ -1,9 +0,0 @@ -TBF_HEADER_SIZE = 0x60; - -FLASH_START = 0x00020000; -FLASH_LENGTH = 0x00020000; - -RAM_START = 0x20004000; -RAM_LENGTH = 0x2000; - -INCLUDE libtock_layout.ld diff --git a/build_scripts/layouts/nano_rp2040_connect.ld b/build_scripts/layouts/nano_rp2040_connect.ld deleted file mode 100644 index 2ee8b5a3..00000000 --- a/build_scripts/layouts/nano_rp2040_connect.ld +++ /dev/null @@ -1,11 +0,0 @@ -/* Layout for the Raspberry Pi Pico board, used by the examples in this repository. */ - -TBF_HEADER_SIZE = 0x60; - -FLASH_START = 0x10020000; -FLASH_LENGTH = 256K; - -RAM_START = 0x20004000; -RAM_LENGTH = 248K; - -INCLUDE libtock_layout.ld diff --git a/build_scripts/layouts/nrf52.ld b/build_scripts/layouts/nrf52.ld deleted file mode 100644 index e4accb52..00000000 --- a/build_scripts/layouts/nrf52.ld +++ /dev/null @@ -1,11 +0,0 @@ -/* Layout for the nRF52-DK, used by the examples in this repository. */ - -TBF_HEADER_SIZE = 0x60; - -FLASH_START = 0x00030000; -FLASH_LENGTH = 0x00060000; - -RAM_START = 0x20004000; -RAM_LENGTH = 62K; - -INCLUDE libtock_layout.ld diff --git a/build_scripts/layouts/nrf52840.ld b/build_scripts/layouts/nrf52840.ld deleted file mode 100644 index fd100c14..00000000 --- a/build_scripts/layouts/nrf52840.ld +++ /dev/null @@ -1,11 +0,0 @@ -/* Layout for the nRF52840-DK, usable by the examples in this repository. */ - -TBF_HEADER_SIZE = 0x60; - -FLASH_START = 0x00030000; -FLASH_LENGTH = 0x000D0000; - -RAM_START = 0x20008000; -RAM_LENGTH = 46K; - -INCLUDE libtock_layout.ld diff --git a/build_scripts/layouts/nucleo_f429zi.ld b/build_scripts/layouts/nucleo_f429zi.ld deleted file mode 100644 index 2bdee3cb..00000000 --- a/build_scripts/layouts/nucleo_f429zi.ld +++ /dev/null @@ -1,11 +0,0 @@ -/* Layout for the Nucleo F429zi, used by the examples in this repository. */ - -TBF_HEADER_SIZE = 0x60; - -FLASH_START = 0x08040000; -FLASH_LENGTH = 255K; - -RAM_START = 0x20004000; -RAM_LENGTH = 112K; - -INCLUDE libtock_layout.ld diff --git a/build_scripts/layouts/nucleo_f446re.ld b/build_scripts/layouts/nucleo_f446re.ld deleted file mode 100644 index 5dea1e60..00000000 --- a/build_scripts/layouts/nucleo_f446re.ld +++ /dev/null @@ -1,11 +0,0 @@ -/* Layout for the Nucleo F446re, used by the examples in this repository. */ - -TBF_HEADER_SIZE = 0x60; - -FLASH_START = 0x08040000; -FLASH_LENGTH = 255K; - -RAM_START = 0x20004000; -RAM_LENGTH = 176K; - -INCLUDE libtock_layout.ld diff --git a/build_scripts/layouts/opentitan.ld b/build_scripts/layouts/opentitan.ld deleted file mode 100644 index 725810fe..00000000 --- a/build_scripts/layouts/opentitan.ld +++ /dev/null @@ -1,11 +0,0 @@ -/* Layout for the RISC-V 32 boards, used by the examples in this repository. */ - -TBF_HEADER_SIZE = 0x80; - -FLASH_START = 0x20030000; -FLASH_LENGTH = 32M; - -RAM_START = 0x10005000; -RAM_LENGTH = 512K; - -INCLUDE libtock_layout.ld diff --git a/build_scripts/layouts/raspberry_pi_pico.ld b/build_scripts/layouts/raspberry_pi_pico.ld deleted file mode 100644 index b4d1f7b5..00000000 --- a/build_scripts/layouts/raspberry_pi_pico.ld +++ /dev/null @@ -1,11 +0,0 @@ -/* Layout for the Raspberry Pi Pico board, used by the examples in this repository. */ - -TBF_HEADER_SIZE = 0x60; - -FLASH_START = 0x10040000; -FLASH_LENGTH = 256K; - -RAM_START = 0x20012000; -RAM_LENGTH = 192K; - -INCLUDE libtock_layout.ld diff --git a/build_scripts/layouts/stm32f3discovery.ld b/build_scripts/layouts/stm32f3discovery.ld deleted file mode 100644 index 5e4cee1a..00000000 --- a/build_scripts/layouts/stm32f3discovery.ld +++ /dev/null @@ -1,11 +0,0 @@ -/* Layout for the stm32f3discovery board, usable by the examples in this repository. */ - -TBF_HEADER_SIZE = 0x60; - -FLASH_START = 0x08020000; -FLASH_LENGTH = 0x00020000; - -RAM_START = 0x20004000; -RAM_LENGTH = 48K; - -INCLUDE libtock_layout.ld diff --git a/build_scripts/layouts/stm32f412gdiscovery.ld b/build_scripts/layouts/stm32f412gdiscovery.ld deleted file mode 100644 index cc41a7c2..00000000 --- a/build_scripts/layouts/stm32f412gdiscovery.ld +++ /dev/null @@ -1,11 +0,0 @@ -/* Layout for the stm32f412gdiscovery board, usable by the examples in this repository. */ - -TBF_HEADER_SIZE = 0x60; - -FLASH_START = 0x08030000; -FLASH_LENGTH = 256K; - -RAM_START = 0x20004000; -RAM_LENGTH = 112K; - -INCLUDE libtock_layout.ld diff --git a/build_scripts/src/lib.rs b/build_scripts/src/lib.rs index 2362b77f..971a8e2d 100644 --- a/build_scripts/src/lib.rs +++ b/build_scripts/src/lib.rs @@ -1,111 +1,189 @@ //! Utility functions for implementing build.rs files for libtock-rs apps. -/// This path is set by this crate's build.rs file when this crate is compiled. -/// This allows this file to know the path of its own local outdir where copies -/// of linker scripts are stored (by this crate's build.rs). That path can then -/// be used in other libtock-rs compilations to provide useful linker scripts. -pub const BUILD_SCRIPTS_OUT_DIR: &str = env!("LIBTOCK_BUILD_SCRIPTS_OUT_DIR"); +/// List of known `LIBTOCK_PLATFORM` values. +#[rustfmt::skip] +const PLATFORMS: &[(&str, &str, &str, &str, &str)] = &[ + // Name | Flash start | Flash len | RAM start | RAM length + ("apollo3" , "0x00040000", "0x0060000", "0x10002000", "0x02000"), + ("clue_nrf52840" , "0x00080000", "512K" , "0x20006000", "216K" ), + ("esp32_c3_devkitm_1" , "0x403B0000", "0x0030000", "0x3FCA2000", "0x2E000"), + ("hail" , "0x00030000", "0x0040000", "0x20008000", "62K" ), + ("hifive1" , "0x20040000", "32M" , "0x80003000", "0x01000"), + ("imix" , "0x00040000", "0x0040000", "0x20008000", "62K" ), + ("imxrt1050" , "0x63002000", "0x1000000", "0x20004000", "112K" ), + ("microbit_v2" , "0x00040000", "256K" , "0x20004000", "112K" ), + ("msp432" , "0x00020000", "0x0020000", "0x20004000", "0x02000"), + ("nano_rp2040_connect", "0x10020000", "256K" , "0x20004000", "248K" ), + ("nrf52" , "0x00030000", "0x0060000", "0x20004000", "62K" ), + ("nrf52840" , "0x00030000", "0x00D0000", "0x20008000", "46K" ), + ("nucleo_f429zi" , "0x08040000", "255K" , "0x20004000", "112K" ), + ("nucleo_f446re" , "0x08040000", "255K" , "0x20004000", "176K" ), + ("opentitan" , "0x20030000", "32M" , "0x10005000", "512K" ), + ("raspberry_pi_pico" , "0x10040000", "256K" , "0x20012000", "192K" ), + ("stm32f3discovery" , "0x08020000", "0x0020000", "0x20004000", "48K" ), + ("stm32f412gdiscovery", "0x08030000", "256K" , "0x20004000", "112K" ), +]; /// Helper function to configure cargo to use suitable linker scripts for /// linking libtock-rs apps. /// -/// This function does two things: +/// `auto_layout` function does a few things: /// -/// 1. Make sure that the linker's search path includes where -/// `libtock_layout.ld` is stored. This is a general linker script designed -/// for libtock-rs apps and the Tock kernel. +/// 1. Copies `libtock_layout.ld` into the linker's search path. +/// 2. Generates a linker script that specifies which flash and RAM addresses +/// the app should be compiled for. This linker script depends on the +/// previously-mentioned `libtock_layout.ld`. +/// 3. Passes the `-T` argument to the linker to make it use +/// the generated linker script. /// -/// 2. Reference a board-specific linker script that essentially sets the -/// `MEMORY` command to specify the flash and RAM addresses where the app -/// should be compiled. This happens by passing the `-T` -/// flag to the linker. +/// `auto_layout` supports two mechanisms for specifying the flash and RAM +/// address ranges: /// -/// This function supports two methods for doing this: +/// 1. Passing the `LIBTOCK_PLATFORM` environment variable, specifying one of a +/// hardcoded list of known platforms. See the `PLATFORMS` variable above for +/// the list of supported platforms. +/// 2. Passing the `LIBTOCK_LINKER_FLASH` and `LIBTOCK_LINKER_RAM` environment +/// variables which specify the starting addresses of flash and RAM memory, +/// respectively. /// -/// 1. Passing the `LIBTOCK_LIBTOCK_PLATFORM` environment variable which -/// specifies the name of the linker script in `/layouts` to be used. -/// -/// 2. Passing the `LIBTOCK_LINKER_FLASH` and `LINKER_RAM` environment -/// variables which specify the starting addresses of flash and RAM -/// memory, respectively. +/// Programs passing `LIBTOCK_LINKER_FLASH` and `LIBTOCK_LINKER_RAM` may +/// additionally pass `LIBTOCK_TBF_HEADER_SIZE`, `LIBTOCK_LINKER_FLASH_LENGTH`, +/// and/or `LIBTOCK_LINKER_RAM_LENGTH`. If not specified, this function will +/// assume some default values for those variables. pub fn auto_layout() { + use std::env::var; use std::fs::File; use std::io::Write; + use std::ops::Deref; use std::path::PathBuf; - const PLATFORM_CFG_VAR: &str = "LIBTOCK_PLATFORM"; - const LINKER_FLASH_CFG_VAR: &str = "LIBTOCK_LINKER_FLASH"; - const LINKER_RAM_CFG_VAR: &str = "LIBTOCK_LINKER_RAM"; + const LIBTOCK_LAYOUT_NAME: &str = "libtock_layout.ld"; + const LINKER_FLASH_VAR: &str = "LIBTOCK_LINKER_FLASH"; + const LINKER_FLASH_LEN_VAR: &str = "LIBTOCK_LINKER_FLASH_LENGTH"; + const LINKER_RAM_VAR: &str = "LIBTOCK_LINKER_RAM"; + const LINKER_RAM_LEN_VAR: &str = "LIBTOCK_LINKER_RAM_LENGTH"; + const PLATFORM_VAR: &str = "LIBTOCK_PLATFORM"; + const TBF_HEADER_SIZE_VAR: &str = "LIBTOCK_TBF_HEADER_SIZE"; // Note: we need to print these rerun-if commands before using the variable // or file, so that if the build script fails cargo knows when to re-run it. - println!("cargo:rerun-if-env-changed={}", PLATFORM_CFG_VAR); - println!("cargo:rerun-if-env-changed={}", LINKER_FLASH_CFG_VAR); - println!("cargo:rerun-if-env-changed={}", LINKER_RAM_CFG_VAR); + println!("cargo:rerun-if-env-changed={}", LINKER_FLASH_VAR); + println!("cargo:rerun-if-env-changed={}", LINKER_FLASH_LEN_VAR); + println!("cargo:rerun-if-env-changed={}", LINKER_RAM_VAR); + println!("cargo:rerun-if-env-changed={}", LINKER_RAM_LEN_VAR); + println!("cargo:rerun-if-env-changed={}", PLATFORM_VAR); + println!("cargo:rerun-if-env-changed={}", TBF_HEADER_SIZE_VAR); - // Read configuration from environment variables. + let platform = get_env_var(PLATFORM_VAR); + let flash_start = get_env_var(LINKER_FLASH_VAR); + let ram_start = get_env_var(LINKER_RAM_VAR); + let flash_len; + let ram_len; + // Determine the flash and RAM address ranges. This detects whether + // LIBTOCK_PLATFORM was specified or whether the flash and RAM ranges were + // specified directly. + let (flash_start, flash_len, ram_start, ram_len) = match (platform, &flash_start, &ram_start) { + (None, Some(flash_start), Some(ram_start)) => { + // The flash and RAM ranges were specified directly. + flash_len = get_env_var(LINKER_FLASH_LEN_VAR); + ram_len = get_env_var(LINKER_RAM_LEN_VAR); + ( + flash_start.deref(), + flash_len.as_deref().unwrap_or("0xD0000"), + ram_start.deref(), + ram_len.as_deref().unwrap_or("46K"), + ) + } + (Some(platform), None, None) => { + // LIBTOCK_PLATFORM was specified. + match PLATFORMS + .iter() + .find(|&&(name, _, _, _, _)| name == platform) + { + None => panic!("Unknown platform: {}", platform), + Some(&(_, flash_start, flash_len, ram_start, ram_len)) => { + (flash_start, flash_len, ram_start, ram_len) + } + } + } + _ => panic!( + "Must specify either {} or both {} and {}; please see \ + libtock_build_scripts' documentation for more information.", + PLATFORM_VAR, LINKER_FLASH_VAR, LINKER_RAM_VAR + ), + }; + let tbf_header_size; + let tbf_header_size = match get_env_var(TBF_HEADER_SIZE_VAR) { + None => "0x80", + Some(value) => { + tbf_header_size = value; + &tbf_header_size + } + }; // Note: cargo fails if run in a path that is not valid Unicode, so this // script doesn't need to handle non-Unicode paths. Also, OUT_DIR cannot be // in a location with a newline in it, or we have no way to pass // rustc-link-search to cargo. - let out_dir = &std::env::var("OUT_DIR").expect("Unable to read OUT_DIR"); + let out_dir = &*var("OUT_DIR").expect("Unable to read OUT_DIR"); assert!( !out_dir.contains('\n'), "Build path contains a newline, which is unsupported" ); - // Set the linker search path to the out dir of this crate where we have - // stored all of the linker files. - println!("cargo:rustc-link-search={}", BUILD_SCRIPTS_OUT_DIR); - - // Choose the linker file we are going to use for this build. That can be - // specified by choosing a platform, where the linker file will be selected - // from `runtime/layouts`, or by explicitly setting the flash and RAM - // addresses. - - // Read the platform environment variable as a String (our platform names - // should all be valid UTF-8). - let platform = std::env::var(PLATFORM_CFG_VAR); + // Create a valid linker file with the specified flash and ram locations. + // + // ``` + // TBF_HEADER_SIZE = 0x80; + // FLASH_START = 0x00040000; + // FLASH_LENGTH = 0x00040000; + // RAM_START = 0x20008000; + // RAM_LENGTH = 62K; + // INCLUDE libtock_layout.ld + // ``` + let layout_name = format!("{flash_start}.{flash_len}.{ram_start}.{ram_len}.ld"); + let layout_path: PathBuf = [out_dir, &layout_name].iter().collect(); + let mut layout_file = + File::create(&layout_path).unwrap_or_else(|e| panic!("Could not open layout file: {}", e)); + writeln!( + layout_file, + "\ + TBF_HEADER_SIZE = {tbf_header_size};\n\ + FLASH_START = {flash_start};\n\ + FLASH_LENGTH = {flash_len};\n\ + RAM_START = {ram_start};\n\ + RAM_LENGTH = {ram_len};\n\ + INCLUDE {};", + LIBTOCK_LAYOUT_NAME + ) + .expect("Failed to write layout file"); + drop(layout_file); - // Read the explicit flash and RAM addresses. - let linker_flash = std::env::var(LINKER_FLASH_CFG_VAR); - let linker_ram = std::env::var(LINKER_RAM_CFG_VAR); + // Compile the contents of `libtock_layout.ld` into this library as a + // string, and copy those contents into out_dir at runtime. + let libtock_layout_path: PathBuf = [out_dir, &LIBTOCK_LAYOUT_NAME].iter().collect(); + let mut libtock_layout_file = File::create(libtock_layout_path) + .unwrap_or_else(|e| panic!("Could not open {}: {}", LIBTOCK_LAYOUT_NAME, e)); + write!( + libtock_layout_file, + "{}", + include_str!("../libtock_layout.ld") + ) + .expect("Failed to write libtock_layout.ld"); + drop(libtock_layout_file); - if let Ok(platform) = platform { - // Point the linker to the correct platform-specific linker file. - let platform_ld_name = format!("{}.ld", platform); - println!("cargo:rustc-link-arg=-T{}", platform_ld_name); - } else if let (Ok(linker_flash), Ok(linker_ram)) = (linker_flash, linker_ram) { - // Create a valid linker file with the specified flash and ram locations. - // - // ``` - // TBF_HEADER_SIZE = 0x80; - // - // FLASH_START = 0x00040000; - // FLASH_LENGTH = 0x00040000; - // - // RAM_START = 0x20008000; - // RAM_LENGTH = 62K; - // - // INCLUDE libtock_layout.ld - // ``` - let linker_script_name = format!("{}.{}.ld", linker_flash, linker_ram); - let out_platform_path: PathBuf = [out_dir, &linker_script_name].iter().collect(); - let mut file = File::create(out_platform_path).expect("Could not create linker file"); - writeln!(file, "TBF_HEADER_SIZE = 0x80;").expect("Could not write linker file"); - writeln!(file, "FLASH_START = {};", linker_flash).expect("Could not write linker file"); - writeln!(file, "FLASH_LENGTH = 0x000D0000;",).expect("Could not write linker file"); - writeln!(file, "RAM_START = {};", linker_ram).expect("Could not write linker file"); - writeln!(file, "RAM_LENGTH = 46K;",).expect("Could not write linker file"); - writeln!(file, "INCLUDE libtock_layout.ld").expect("Could not write linker file"); - - // Pass the name of this linker script to rustc. - println!("cargo:rustc-link-arg=-T{}", linker_script_name); + // Tell rustc which linker script to use and where to find it. + println!("cargo:rustc-link-arg=-T{}", layout_path.display()); + println!("cargo:rustc-link-search={}", out_dir); +} - // Tell rustc where to search for the layout file. - println!("cargo:rustc-link-search={}", out_dir); - } else { - panic!("Need to set LIBTOCK_PLATFORM or (LIBTOCK_LINKER_FLASH and LIBTOCK_LINKER_RAM)"); +// Retrieves an environment variable as a String. Returns None if the variable +// is not specified and panics if the variable is not valid Unicode. +fn get_env_var(name: &str) -> Option { + use std::env::{var, VarError}; + match var(name) { + Ok(value) => Some(value), + Err(VarError::NotPresent) => None, + Err(VarError::NotUnicode(value)) => panic!("Non-Unicode value in {}: {:?}", name, value), } } From 9a3f90fc1df2075388f0e3b69b1d8eaced851e91 Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Tue, 8 Aug 2023 16:44:53 -0400 Subject: [PATCH 28/31] build_scripts: fix & warning --- build_scripts/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_scripts/src/lib.rs b/build_scripts/src/lib.rs index 971a8e2d..f7581e77 100644 --- a/build_scripts/src/lib.rs +++ b/build_scripts/src/lib.rs @@ -161,7 +161,7 @@ pub fn auto_layout() { // Compile the contents of `libtock_layout.ld` into this library as a // string, and copy those contents into out_dir at runtime. - let libtock_layout_path: PathBuf = [out_dir, &LIBTOCK_LAYOUT_NAME].iter().collect(); + let libtock_layout_path: PathBuf = [out_dir, LIBTOCK_LAYOUT_NAME].iter().collect(); let mut libtock_layout_file = File::create(libtock_layout_path) .unwrap_or_else(|e| panic!("Could not open {}: {}", LIBTOCK_LAYOUT_NAME, e)); write!( From 225ac3cd0354abe4bc2b8c8b4f8cca611882fea6 Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Tue, 8 Aug 2023 18:17:17 -0400 Subject: [PATCH 29/31] make: elf2tab: kernel version 2.1 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 4fa9bd9f..00578e78 100644 --- a/Makefile +++ b/Makefile @@ -187,7 +187,7 @@ $(ELF_TARGETS): .PHONY: tab tab: $(ELF_TARGETS) - elf2tab --kernel-major 2 --kernel-minor 0 -n $(EXAMPLE) -o $(EXAMPLE).tab --stack 1024 --minimum-footer-size 256 $(ELF_LIST) + elf2tab --kernel-major 2 --kernel-minor 1 -n $(EXAMPLE) -o $(EXAMPLE).tab --stack 1024 --minimum-footer-size 256 $(ELF_LIST) # Creates the `make EXAMPLE=` targets. Arguments: # 1) The name of the platform to build for. From 6da0226033cc3043761a0a9df2def34e6b3965ef Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Tue, 8 Aug 2023 18:26:09 -0400 Subject: [PATCH 30/31] make: tab: put tabs in target/tab/ --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 00578e78..7b6cc2db 100644 --- a/Makefile +++ b/Makefile @@ -187,7 +187,8 @@ $(ELF_TARGETS): .PHONY: tab tab: $(ELF_TARGETS) - elf2tab --kernel-major 2 --kernel-minor 1 -n $(EXAMPLE) -o $(EXAMPLE).tab --stack 1024 --minimum-footer-size 256 $(ELF_LIST) + mkdir -p target/tab + elf2tab --kernel-major 2 --kernel-minor 1 -n $(EXAMPLE) -o target/tab/$(EXAMPLE).tab --stack 1024 --minimum-footer-size 256 $(ELF_LIST) # Creates the `make EXAMPLE=` targets. Arguments: # 1) The name of the platform to build for. From daa201a1026a6a239b30d2fccf51d4c55d2bb34b Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Tue, 8 Aug 2023 18:32:30 -0400 Subject: [PATCH 31/31] readme: specify target/tab path --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1ee36c62..84b37485 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ make tab EXAMPLE= To install the tab use tockloader ```shell -tockloader install +tockloader install target/tab/ ``` Tockloader will determine which compiled version with the correct flash and RAM