feat(boot): ✨ Replace r0 dependency
Use pointer provenance to guarantee absence of UBs.
This commit is contained in:
		
							parent
							
								
									568fdcb649
								
							
						
					
					
						commit
						dae26262bc
					
				| 
						 | 
					@ -99,7 +99,6 @@ dependencies = [
 | 
				
			||||||
 "cfg-if",
 | 
					 "cfg-if",
 | 
				
			||||||
 "cortex-a",
 | 
					 "cortex-a",
 | 
				
			||||||
 "machine",
 | 
					 "machine",
 | 
				
			||||||
 "r0",
 | 
					 | 
				
			||||||
 "seahash",
 | 
					 "seahash",
 | 
				
			||||||
 "snafu",
 | 
					 "snafu",
 | 
				
			||||||
 "tock-registers",
 | 
					 "tock-registers",
 | 
				
			||||||
| 
						 | 
					@ -389,7 +388,6 @@ dependencies = [
 | 
				
			||||||
 "cortex-a",
 | 
					 "cortex-a",
 | 
				
			||||||
 "once_cell",
 | 
					 "once_cell",
 | 
				
			||||||
 "qemu-exit",
 | 
					 "qemu-exit",
 | 
				
			||||||
 "r0",
 | 
					 | 
				
			||||||
 "snafu",
 | 
					 "snafu",
 | 
				
			||||||
 "tock-registers",
 | 
					 "tock-registers",
 | 
				
			||||||
 "usize_conversions",
 | 
					 "usize_conversions",
 | 
				
			||||||
| 
						 | 
					@ -458,7 +456,6 @@ dependencies = [
 | 
				
			||||||
 "cfg-if",
 | 
					 "cfg-if",
 | 
				
			||||||
 "cortex-a",
 | 
					 "cortex-a",
 | 
				
			||||||
 "machine",
 | 
					 "machine",
 | 
				
			||||||
 "r0",
 | 
					 | 
				
			||||||
 "snafu",
 | 
					 "snafu",
 | 
				
			||||||
 "tock-registers",
 | 
					 "tock-registers",
 | 
				
			||||||
 "usize_conversions",
 | 
					 "usize_conversions",
 | 
				
			||||||
| 
						 | 
					@ -546,12 +543,6 @@ dependencies = [
 | 
				
			||||||
 "proc-macro2",
 | 
					 "proc-macro2",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "r0"
 | 
					 | 
				
			||||||
version = "1.0.0"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "bd7a31eed1591dcbc95d92ad7161908e72f4677f8fabf2a32ca49b4237cbf211"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "redox_syscall"
 | 
					name = "redox_syscall"
 | 
				
			||||||
version = "0.2.16"
 | 
					version = "0.2.16"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,7 +27,6 @@ rpi4 = ["machine/rpi4"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[dependencies]
 | 
					[dependencies]
 | 
				
			||||||
machine = { path = "../../machine" }
 | 
					machine = { path = "../../machine" }
 | 
				
			||||||
r0 = "1.0"
 | 
					 | 
				
			||||||
cortex-a = "7.5"
 | 
					cortex-a = "7.5"
 | 
				
			||||||
tock-registers = "0.7"
 | 
					tock-registers = "0.7"
 | 
				
			||||||
ux = { version = "0.1", default-features = false }
 | 
					ux = { version = "0.1", default-features = false }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,7 +28,7 @@ pub unsafe extern "C" fn _start() -> ! {
 | 
				
			||||||
    extern "Rust" {
 | 
					    extern "Rust" {
 | 
				
			||||||
        // Boundaries of the .bss section, provided by the linker script
 | 
					        // Boundaries of the .bss section, provided by the linker script
 | 
				
			||||||
        static __bss_start: UnsafeCell<()>;
 | 
					        static __bss_start: UnsafeCell<()>;
 | 
				
			||||||
        static __bss_end_exclusive: UnsafeCell<()>;
 | 
					        static __bss_size: UnsafeCell<()>;
 | 
				
			||||||
        // Load address of the kernel binary
 | 
					        // Load address of the kernel binary
 | 
				
			||||||
        static __binary_nonzero_lma: UnsafeCell<()>;
 | 
					        static __binary_nonzero_lma: UnsafeCell<()>;
 | 
				
			||||||
        // Address to relocate to and image size
 | 
					        // Address to relocate to and image size
 | 
				
			||||||
| 
						 | 
					@ -42,7 +42,11 @@ pub unsafe extern "C" fn _start() -> ! {
 | 
				
			||||||
    SP.set(__boot_core_stack_end_exclusive.get() as u64);
 | 
					    SP.set(__boot_core_stack_end_exclusive.get() as u64);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Zeroes the .bss section
 | 
					    // Zeroes the .bss section
 | 
				
			||||||
    r0::zero_bss(__bss_start.get() as u64, __bss_end_exclusive.get() as u64);
 | 
					    let bss =
 | 
				
			||||||
 | 
					        core::slice::from_raw_parts_mut(__bss_start.get() as *mut u8, __bss_size.get() as usize);
 | 
				
			||||||
 | 
					    for i in bss {
 | 
				
			||||||
 | 
					        *i = 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Relocate the code
 | 
					    // Relocate the code
 | 
				
			||||||
    core::ptr::copy_nonoverlapping(
 | 
					    core::ptr::copy_nonoverlapping(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -50,7 +50,8 @@ _start:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Initialize bss.
 | 
					    // Initialize bss.
 | 
				
			||||||
    ADR_ABS	x0, __bss_start
 | 
					    ADR_ABS	x0, __bss_start
 | 
				
			||||||
    ADR_ABS x1, __bss_end_exclusive
 | 
					    ADR_ABS	x1, __bss_size
 | 
				
			||||||
 | 
					    add x1, x0, x1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.L_bss_init_loop:
 | 
					.L_bss_init_loop:
 | 
				
			||||||
    cmp	x0, x1
 | 
					    cmp	x0, x1
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -93,6 +93,6 @@ SECTIONS
 | 
				
			||||||
        __bss_start = .;
 | 
					        __bss_start = .;
 | 
				
			||||||
        *(.bss*);
 | 
					        *(.bss*);
 | 
				
			||||||
        . = ALIGN(16);
 | 
					        . = ALIGN(16);
 | 
				
			||||||
        __bss_end_exclusive = .;
 | 
					        __bss_size = . - __bss_start;
 | 
				
			||||||
    } :segment_data
 | 
					    } :segment_data
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -58,7 +58,8 @@ SECTIONS
 | 
				
			||||||
        *(.bss .bss.*)
 | 
					        *(.bss .bss.*)
 | 
				
			||||||
        *(COMMON)
 | 
					        *(COMMON)
 | 
				
			||||||
        . = ALIGN(PAGE_SIZE); /* Align up to page size */
 | 
					        . = ALIGN(PAGE_SIZE); /* Align up to page size */
 | 
				
			||||||
        __BSS_END = .;
 | 
					        __BSS_SIZE = . - __BSS_START;
 | 
				
			||||||
 | 
					        /* __BSS_END = .; unused */
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /DISCARD/ : { *(.comment) *(.gnu*) *(.note*) *(.eh_frame*) }
 | 
					    /DISCARD/ : { *(.comment) *(.gnu*) *(.note*) *(.eh_frame*) }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,7 +28,6 @@ rpi3 = []
 | 
				
			||||||
rpi4 = []
 | 
					rpi4 = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[dependencies]
 | 
					[dependencies]
 | 
				
			||||||
r0 = "1.0"
 | 
					 | 
				
			||||||
qemu-exit = "3.0"
 | 
					qemu-exit = "3.0"
 | 
				
			||||||
cortex-a = "7.5"
 | 
					cortex-a = "7.5"
 | 
				
			||||||
tock-registers = "0.7"
 | 
					tock-registers = "0.7"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,6 +10,11 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use {
 | 
					use {
 | 
				
			||||||
    crate::endless_sleep,
 | 
					    crate::endless_sleep,
 | 
				
			||||||
 | 
					    core::{
 | 
				
			||||||
 | 
					        cell::UnsafeCell,
 | 
				
			||||||
 | 
					        slice,
 | 
				
			||||||
 | 
					        sync::atomic::{self, Ordering},
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    cortex_a::{asm, registers::*},
 | 
					    cortex_a::{asm, registers::*},
 | 
				
			||||||
    tock_registers::interfaces::{Readable, Writeable},
 | 
					    tock_registers::interfaces::{Readable, Writeable},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -43,15 +48,33 @@ macro_rules! entry {
 | 
				
			||||||
/// Totally unsafe! We're in the hardware land.
 | 
					/// Totally unsafe! We're in the hardware land.
 | 
				
			||||||
#[link_section = ".text.boot"]
 | 
					#[link_section = ".text.boot"]
 | 
				
			||||||
unsafe fn reset() -> ! {
 | 
					unsafe fn reset() -> ! {
 | 
				
			||||||
    extern "C" {
 | 
					    extern "Rust" {
 | 
				
			||||||
        // Boundaries of the .bss section, provided by the linker script
 | 
					        // Boundaries of the .bss section, provided by the linker script.
 | 
				
			||||||
        // The type, `u64`, indicates that the memory is 8-byte aligned
 | 
					        static __BSS_START: UnsafeCell<()>;
 | 
				
			||||||
        static mut __BSS_START: u64;
 | 
					        static __BSS_SIZE: UnsafeCell<()>;
 | 
				
			||||||
        static mut __BSS_END: u64;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Zeroes the .bss section
 | 
					    // Zeroes the .bss section
 | 
				
			||||||
    r0::zero_bss(&mut __BSS_START, &mut __BSS_END);
 | 
					    // Based on https://gist.github.com/skoe/dbd3add2fc3baa600e9ebc995ddf0302 and discussions
 | 
				
			||||||
 | 
					    // on pointer provenance in closing r0 issues (https://github.com/rust-embedded/cortex-m-rt/issues/300)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // NB: https://doc.rust-lang.org/nightly/core/ptr/index.html#provenance
 | 
				
			||||||
 | 
					    // Importing pointers like `__BSS_START` and `__BSS_END` and performing pointer
 | 
				
			||||||
 | 
					    // arithmetic on them directly may lead to Undefined Behavior, because the
 | 
				
			||||||
 | 
					    // compiler may assume they come from different allocations and thus performing
 | 
				
			||||||
 | 
					    // undesirable optimizations on them.
 | 
				
			||||||
 | 
					    // So we use a painter-and-a-size as described in provenance section.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let bss = slice::from_raw_parts_mut(__BSS_START.get() as *mut u8, __BSS_SIZE.get() as usize);
 | 
				
			||||||
 | 
					    for i in bss {
 | 
				
			||||||
 | 
					        *i = 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Don't cross this line with loads and stores. The initializations
 | 
				
			||||||
 | 
					    // done above could be "invisible" to the compiler, because we write to the
 | 
				
			||||||
 | 
					    // same memory location that is used by statics after this point.
 | 
				
			||||||
 | 
					    // Additionally, we assume that no statics are accessed before this point.
 | 
				
			||||||
 | 
					    atomic::compiler_fence(Ordering::SeqCst);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    extern "Rust" {
 | 
					    extern "Rust" {
 | 
				
			||||||
        fn main() -> !;
 | 
					        fn main() -> !;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,6 +4,7 @@
 | 
				
			||||||
#![feature(allocator_api)]
 | 
					#![feature(allocator_api)]
 | 
				
			||||||
#![feature(format_args_nl)]
 | 
					#![feature(format_args_nl)]
 | 
				
			||||||
#![feature(core_intrinsics)]
 | 
					#![feature(core_intrinsics)]
 | 
				
			||||||
 | 
					#![feature(strict_provenance)]
 | 
				
			||||||
#![feature(stmt_expr_attributes)]
 | 
					#![feature(stmt_expr_attributes)]
 | 
				
			||||||
#![feature(slice_ptr_get)]
 | 
					#![feature(slice_ptr_get)]
 | 
				
			||||||
#![feature(nonnull_slice_from_raw_parts)]
 | 
					#![feature(nonnull_slice_from_raw_parts)]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,7 +28,6 @@ rpi4 = ["machine/rpi4"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[dependencies]
 | 
					[dependencies]
 | 
				
			||||||
machine = { path = "../machine" }
 | 
					machine = { path = "../machine" }
 | 
				
			||||||
r0 = "1.0"
 | 
					 | 
				
			||||||
cortex-a = "7.5"
 | 
					cortex-a = "7.5"
 | 
				
			||||||
tock-registers = "0.7"
 | 
					tock-registers = "0.7"
 | 
				
			||||||
ux = { version = "0.1", default-features = false }
 | 
					ux = { version = "0.1", default-features = false }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,11 +11,14 @@
 | 
				
			||||||
#![no_main]
 | 
					#![no_main]
 | 
				
			||||||
#![feature(ptr_internals)]
 | 
					#![feature(ptr_internals)]
 | 
				
			||||||
#![feature(format_args_nl)]
 | 
					#![feature(format_args_nl)]
 | 
				
			||||||
 | 
					#![feature(strict_provenance)]
 | 
				
			||||||
#![feature(custom_test_frameworks)]
 | 
					#![feature(custom_test_frameworks)]
 | 
				
			||||||
#![test_runner(machine::tests::test_runner)]
 | 
					#![test_runner(machine::tests::test_runner)]
 | 
				
			||||||
#![reexport_test_harness_main = "test_main"]
 | 
					#![reexport_test_harness_main = "test_main"]
 | 
				
			||||||
#![deny(missing_docs)]
 | 
					#![deny(missing_docs)]
 | 
				
			||||||
#![deny(warnings)]
 | 
					#![deny(warnings)]
 | 
				
			||||||
 | 
					#![deny(unused)]
 | 
				
			||||||
 | 
					#![feature(allocator_api)]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[cfg(not(test))]
 | 
					#[cfg(not(test))]
 | 
				
			||||||
use core::panic::PanicInfo;
 | 
					use core::panic::PanicInfo;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue