For educational purposes, use own zero_bss().

pull/41/head
Andre Richter 4 years ago
parent a41190e298
commit c64dd1197a
No known key found for this signature in database
GPG Key ID: 2116C1AB102F615E

@ -3,14 +3,4 @@
[[package]]
name = "kernel"
version = "0.1.0"
dependencies = [
"r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "r0"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2a38df5b15c8d5c7e8654189744d8e396bddc18ad48041a500ce52d6948941f"

@ -14,4 +14,3 @@ bsp_rpi3 = []
bsp_rpi4 = []
[dependencies]
r0 = "0.2.*"

@ -24,12 +24,11 @@ Check out `make qemu` again to see the additional code run.
diff -uNr 01_wait_forever/Cargo.toml 02_runtime_init/Cargo.toml
--- 01_wait_forever/Cargo.toml
+++ 02_runtime_init/Cargo.toml
@@ -14,4 +14,4 @@
@@ -14,4 +14,3 @@
bsp_rpi4 = []
[dependencies]
-
+r0 = "0.2.*"
diff -uNr 01_wait_forever/src/arch/aarch64/start.S 02_runtime_init/src/arch/aarch64/start.S
--- 01_wait_forever/src/arch/aarch64/start.S
@ -85,7 +84,7 @@ diff -uNr 01_wait_forever/src/bsp/rpi/link.ld 02_runtime_init/src/bsp/rpi/link.l
diff -uNr 01_wait_forever/src/main.rs 02_runtime_init/src/main.rs
--- 01_wait_forever/src/main.rs
+++ 02_runtime_init/src/main.rs
@@ -16,9 +16,19 @@
@@ -16,9 +16,20 @@
// the first function to run.
mod arch;
@ -95,6 +94,7 @@ diff -uNr 01_wait_forever/src/main.rs 02_runtime_init/src/main.rs
// Conditionally includes the selected `BSP` code.
mod bsp;
+mod memory;
mod panic_wait;
-// Kernel code coming next tutorial.
@ -107,16 +107,78 @@ diff -uNr 01_wait_forever/src/main.rs 02_runtime_init/src/main.rs
+ panic!()
+}
diff -uNr 01_wait_forever/src/memory.rs 02_runtime_init/src/memory.rs
--- 01_wait_forever/src/memory.rs
+++ 02_runtime_init/src/memory.rs
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: MIT OR Apache-2.0
+//
+// Copyright (c) 2018-2020 Andre Richter <andre.o.richter@gmail.com>
+
+//! Memory Management.
+
+use core::ops::Range;
+
+/// Zero out a memory region.
+///
+/// # Safety
+///
+/// - `range.start` and `range.end` must be valid.
+/// - `range.start` and `range.end` must be `T` aligned.
+pub unsafe fn zero_volatile<T>(range: Range<*mut T>)
+where
+ T: From<u8>,
+{
+ let mut ptr = range.start;
+
+ while ptr < range.end {
+ core::ptr::write_volatile(ptr, T::from(0));
+ ptr = ptr.offset(1);
+ }
+}
diff -uNr 01_wait_forever/src/runtime_init.rs 02_runtime_init/src/runtime_init.rs
--- 01_wait_forever/src/runtime_init.rs
+++ 02_runtime_init/src/runtime_init.rs
@@ -0,0 +1,25 @@
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: MIT OR Apache-2.0
+//
+// Copyright (c) 2018-2020 Andre Richter <andre.o.richter@gmail.com>
+
+//! Rust runtime initialization code.
+
+use crate::memory;
+use core::ops::Range;
+
+/// Return the range spanning the .bss section.
+///
+/// # Safety
+///
+/// - The symbol-provided addresses must be valid.
+/// - The symbol-provided addresses must be usize aligned.
+unsafe fn bss_range() -> Range<*mut usize> {
+ extern "C" {
+ // Boundaries of the .bss section, provided by linker script symbols.
+ static mut __bss_start: usize;
+ static mut __bss_end: usize;
+ }
+
+ Range {
+ start: &mut __bss_start,
+ end: &mut __bss_end,
+ }
+}
+
+/// Zero out the .bss section.
+///
+/// # Safety
+///
+/// - Must only be called pre `kernel_init()`.
+#[inline(always)]
+unsafe fn zero_bss() {
+ memory::zero_volatile(bss_range());
+}
+
+/// Equivalent to `crt0` or `c0` code in C/C++ world. Clears the `bss` section, then jumps to kernel
+/// init code.
+///
@ -125,14 +187,7 @@ diff -uNr 01_wait_forever/src/runtime_init.rs 02_runtime_init/src/runtime_init.r
+/// - Only a single core must be active and running this function.
+#[no_mangle]
+pub unsafe extern "C" fn runtime_init() -> ! {
+ extern "C" {
+ // Boundaries of the .bss section, provided by the linker script.
+ static mut __bss_start: u64;
+ static mut __bss_end: u64;
+ }
+
+ // Zero out the .bss section.
+ r0::zero_bss(&mut __bss_start, &mut __bss_end);
+ zero_bss();
+
+ crate::kernel_init()
+}

Binary file not shown.

Binary file not shown.

@ -22,6 +22,7 @@ mod runtime_init;
// Conditionally includes the selected `BSP` code.
mod bsp;
mod memory;
mod panic_wait;
/// Early init code.

@ -0,0 +1,25 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
//
// Copyright (c) 2018-2020 Andre Richter <andre.o.richter@gmail.com>
//! Memory Management.
use core::ops::Range;
/// Zero out a memory region.
///
/// # Safety
///
/// - `range.start` and `range.end` must be valid.
/// - `range.start` and `range.end` must be `T` aligned.
pub unsafe fn zero_volatile<T>(range: Range<*mut T>)
where
T: From<u8>,
{
let mut ptr = range.start;
while ptr < range.end {
core::ptr::write_volatile(ptr, T::from(0));
ptr = ptr.offset(1);
}
}

@ -4,6 +4,38 @@
//! Rust runtime initialization code.
use crate::memory;
use core::ops::Range;
/// Return the range spanning the .bss section.
///
/// # Safety
///
/// - The symbol-provided addresses must be valid.
/// - The symbol-provided addresses must be usize aligned.
unsafe fn bss_range() -> Range<*mut usize> {
extern "C" {
// Boundaries of the .bss section, provided by linker script symbols.
static mut __bss_start: usize;
static mut __bss_end: usize;
}
Range {
start: &mut __bss_start,
end: &mut __bss_end,
}
}
/// Zero out the .bss section.
///
/// # Safety
///
/// - Must only be called pre `kernel_init()`.
#[inline(always)]
unsafe fn zero_bss() {
memory::zero_volatile(bss_range());
}
/// Equivalent to `crt0` or `c0` code in C/C++ world. Clears the `bss` section, then jumps to kernel
/// init code.
///
@ -12,14 +44,7 @@
/// - Only a single core must be active and running this function.
#[no_mangle]
pub unsafe extern "C" fn runtime_init() -> ! {
extern "C" {
// Boundaries of the .bss section, provided by the linker script.
static mut __bss_start: u64;
static mut __bss_end: u64;
}
// Zero out the .bss section.
r0::zero_bss(&mut __bss_start, &mut __bss_end);
zero_bss();
crate::kernel_init()
}

@ -3,14 +3,4 @@
[[package]]
name = "kernel"
version = "0.1.0"
dependencies = [
"r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "r0"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2a38df5b15c8d5c7e8654189744d8e396bddc18ad48041a500ce52d6948941f"

@ -14,4 +14,3 @@ bsp_rpi3 = []
bsp_rpi4 = []
[dependencies]
r0 = "0.2.*"

@ -159,17 +159,18 @@ diff -uNr 02_runtime_init/src/main.rs 03_hacky_hello_world/src/main.rs
#![no_main]
#![no_std]
@@ -22,7 +36,9 @@
@@ -22,8 +36,10 @@
// Conditionally includes the selected `BSP` code.
mod bsp;
+mod interface;
mod memory;
mod panic_wait;
+mod print;
/// Early init code.
///
@@ -30,5 +46,7 @@
@@ -31,5 +47,7 @@
///
/// - Only a single core must be active and running this function.
unsafe fn kernel_init() -> ! {

Binary file not shown.

Binary file not shown.

@ -37,6 +37,7 @@ mod runtime_init;
mod bsp;
mod interface;
mod memory;
mod panic_wait;
mod print;

@ -0,0 +1,25 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
//
// Copyright (c) 2018-2020 Andre Richter <andre.o.richter@gmail.com>
//! Memory Management.
use core::ops::Range;
/// Zero out a memory region.
///
/// # Safety
///
/// - `range.start` and `range.end` must be valid.
/// - `range.start` and `range.end` must be `T` aligned.
pub unsafe fn zero_volatile<T>(range: Range<*mut T>)
where
T: From<u8>,
{
let mut ptr = range.start;
while ptr < range.end {
core::ptr::write_volatile(ptr, T::from(0));
ptr = ptr.offset(1);
}
}

@ -4,6 +4,38 @@
//! Rust runtime initialization code.
use crate::memory;
use core::ops::Range;
/// Return the range spanning the .bss section.
///
/// # Safety
///
/// - The symbol-provided addresses must be valid.
/// - The symbol-provided addresses must be usize aligned.
unsafe fn bss_range() -> Range<*mut usize> {
extern "C" {
// Boundaries of the .bss section, provided by linker script symbols.
static mut __bss_start: usize;
static mut __bss_end: usize;
}
Range {
start: &mut __bss_start,
end: &mut __bss_end,
}
}
/// Zero out the .bss section.
///
/// # Safety
///
/// - Must only be called pre `kernel_init()`.
#[inline(always)]
unsafe fn zero_bss() {
memory::zero_volatile(bss_range());
}
/// Equivalent to `crt0` or `c0` code in C/C++ world. Clears the `bss` section, then jumps to kernel
/// init code.
///
@ -12,14 +44,7 @@
/// - Only a single core must be active and running this function.
#[no_mangle]
pub unsafe extern "C" fn runtime_init() -> ! {
extern "C" {
// Boundaries of the .bss section, provided by the linker script.
static mut __bss_start: u64;
static mut __bss_end: u64;
}
// Zero out the .bss section.
r0::zero_bss(&mut __bss_start, &mut __bss_end);
zero_bss();
crate::kernel_init()
}

@ -13,14 +13,8 @@ name = "kernel"
version = "0.1.0"
dependencies = [
"cortex-a 2.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "r0"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "register"
version = "0.4.2"
@ -36,6 +30,5 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum cortex-a 2.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4aab2f5271d9bf17a52b34dd99993648132df3dacb79312a33332f2b6ae1d0fd"
"checksum r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2a38df5b15c8d5c7e8654189744d8e396bddc18ad48041a500ce52d6948941f"
"checksum register 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a51f149d257caa7d9aed1f870d573ba5e2429576e6fed0693341f23078c98e55"
"checksum tock-registers 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "50af9c49c55cfb4437dd78c1fada3be5d088cbe1bea641db8171283503606a70"

@ -14,7 +14,6 @@ bsp_rpi3 = ["cortex-a"]
bsp_rpi4 = ["cortex-a"]
[dependencies]
r0 = "0.2.*"
# Optional dependencies
cortex-a = { version = "2.8.x", optional = true }

@ -13,7 +13,7 @@ which provides zero-overhead abstractions and wraps the `unsafe` parts.
diff -uNr 03_hacky_hello_world/Cargo.toml 04_zero_overhead_abstraction/Cargo.toml
--- 03_hacky_hello_world/Cargo.toml
+++ 04_zero_overhead_abstraction/Cargo.toml
@@ -10,8 +10,11 @@
@@ -10,7 +10,10 @@
# The features section is used to select the target board.
[features]
default = []
@ -23,7 +23,6 @@ diff -uNr 03_hacky_hello_world/Cargo.toml 04_zero_overhead_abstraction/Cargo.tom
+bsp_rpi4 = ["cortex-a"]
[dependencies]
r0 = "0.2.*"
+
+# Optional dependencies
+cortex-a = { version = "2.8.x", optional = true }
@ -130,7 +129,7 @@ diff -uNr 03_hacky_hello_world/src/main.rs 04_zero_overhead_abstraction/src/main
#![feature(panic_info_message)]
#![no_main]
#![no_std]
@@ -46,7 +44,8 @@
@@ -47,7 +45,8 @@
///
/// - Only a single core must be active and running this function.
unsafe fn kernel_init() -> ! {
@ -145,15 +144,15 @@ diff -uNr 03_hacky_hello_world/src/main.rs 04_zero_overhead_abstraction/src/main
diff -uNr 03_hacky_hello_world/src/runtime_init.rs 04_zero_overhead_abstraction/src/runtime_init.rs
--- 03_hacky_hello_world/src/runtime_init.rs
+++ 04_zero_overhead_abstraction/src/runtime_init.rs
@@ -10,8 +10,7 @@
@@ -42,8 +42,7 @@
/// # Safety
///
/// - Only a single core must be active and running this function.
-#[no_mangle]
-pub unsafe extern "C" fn runtime_init() -> ! {
+pub unsafe fn runtime_init() -> ! {
extern "C" {
// Boundaries of the .bss section, provided by the linker script.
static mut __bss_start: u64;
zero_bss();
crate::kernel_init()
```

@ -35,6 +35,7 @@ mod runtime_init;
mod bsp;
mod interface;
mod memory;
mod panic_wait;
mod print;

@ -0,0 +1,25 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
//
// Copyright (c) 2018-2020 Andre Richter <andre.o.richter@gmail.com>
//! Memory Management.
use core::ops::Range;
/// Zero out a memory region.
///
/// # Safety
///
/// - `range.start` and `range.end` must be valid.
/// - `range.start` and `range.end` must be `T` aligned.
pub unsafe fn zero_volatile<T>(range: Range<*mut T>)
where
T: From<u8>,
{
let mut ptr = range.start;
while ptr < range.end {
core::ptr::write_volatile(ptr, T::from(0));
ptr = ptr.offset(1);
}
}

@ -4,6 +4,38 @@
//! Rust runtime initialization code.
use crate::memory;
use core::ops::Range;
/// Return the range spanning the .bss section.
///
/// # Safety
///
/// - The symbol-provided addresses must be valid.
/// - The symbol-provided addresses must be usize aligned.
unsafe fn bss_range() -> Range<*mut usize> {
extern "C" {
// Boundaries of the .bss section, provided by linker script symbols.
static mut __bss_start: usize;
static mut __bss_end: usize;
}
Range {
start: &mut __bss_start,
end: &mut __bss_end,
}
}
/// Zero out the .bss section.
///
/// # Safety
///
/// - Must only be called pre `kernel_init()`.
#[inline(always)]
unsafe fn zero_bss() {
memory::zero_volatile(bss_range());
}
/// Equivalent to `crt0` or `c0` code in C/C++ world. Clears the `bss` section, then jumps to kernel
/// init code.
///
@ -11,14 +43,7 @@
///
/// - Only a single core must be active and running this function.
pub unsafe fn runtime_init() -> ! {
extern "C" {
// Boundaries of the .bss section, provided by the linker script.
static mut __bss_start: u64;
static mut __bss_end: u64;
}
// Zero out the .bss section.
r0::zero_bss(&mut __bss_start, &mut __bss_end);
zero_bss();
crate::kernel_init()
}

@ -13,14 +13,8 @@ name = "kernel"
version = "0.1.0"
dependencies = [
"cortex-a 2.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "r0"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "register"
version = "0.4.2"
@ -36,6 +30,5 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum cortex-a 2.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4aab2f5271d9bf17a52b34dd99993648132df3dacb79312a33332f2b6ae1d0fd"
"checksum r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2a38df5b15c8d5c7e8654189744d8e396bddc18ad48041a500ce52d6948941f"
"checksum register 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a51f149d257caa7d9aed1f870d573ba5e2429576e6fed0693341f23078c98e55"
"checksum tock-registers 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "50af9c49c55cfb4437dd78c1fada3be5d088cbe1bea641db8171283503606a70"

@ -14,7 +14,6 @@ bsp_rpi3 = ["cortex-a"]
bsp_rpi4 = ["cortex-a"]
[dependencies]
r0 = "0.2.*"
# Optional dependencies
cortex-a = { version = "2.8.x", optional = true }

@ -341,7 +341,7 @@ diff -uNr 04_zero_overhead_abstraction/src/main.rs 05_safe_globals/src/main.rs
#![no_main]
#![no_std]
@@ -44,8 +45,12 @@
@@ -45,8 +46,12 @@
///
/// - Only a single core must be active and running this function.
unsafe fn kernel_init() -> ! {

Binary file not shown.

Binary file not shown.

@ -36,6 +36,7 @@ mod runtime_init;
mod bsp;
mod interface;
mod memory;
mod panic_wait;
mod print;

@ -0,0 +1,25 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
//
// Copyright (c) 2018-2020 Andre Richter <andre.o.richter@gmail.com>
//! Memory Management.
use core::ops::Range;
/// Zero out a memory region.
///
/// # Safety
///
/// - `range.start` and `range.end` must be valid.
/// - `range.start` and `range.end` must be `T` aligned.
pub unsafe fn zero_volatile<T>(range: Range<*mut T>)
where
T: From<u8>,
{
let mut ptr = range.start;
while ptr < range.end {
core::ptr::write_volatile(ptr, T::from(0));
ptr = ptr.offset(1);
}
}

@ -4,6 +4,38 @@
//! Rust runtime initialization code.
use crate::memory;
use core::ops::Range;
/// Return the range spanning the .bss section.
///
/// # Safety
///
/// - The symbol-provided addresses must be valid.
/// - The symbol-provided addresses must be usize aligned.
unsafe fn bss_range() -> Range<*mut usize> {
extern "C" {
// Boundaries of the .bss section, provided by linker script symbols.
static mut __bss_start: usize;
static mut __bss_end: usize;
}
Range {
start: &mut __bss_start,
end: &mut __bss_end,
}
}
/// Zero out the .bss section.
///
/// # Safety
///
/// - Must only be called pre `kernel_init()`.
#[inline(always)]
unsafe fn zero_bss() {
memory::zero_volatile(bss_range());
}
/// Equivalent to `crt0` or `c0` code in C/C++ world. Clears the `bss` section, then jumps to kernel
/// init code.
///
@ -11,14 +43,7 @@
///
/// - Only a single core must be active and running this function.
pub unsafe fn runtime_init() -> ! {
extern "C" {
// Boundaries of the .bss section, provided by the linker script.
static mut __bss_start: u64;
static mut __bss_end: u64;
}
// Zero out the .bss section.
r0::zero_bss(&mut __bss_start, &mut __bss_end);
zero_bss();
crate::kernel_init()
}

@ -13,15 +13,9 @@ name = "kernel"
version = "0.1.0"
dependencies = [
"cortex-a 2.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"register 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "r0"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "register"
version = "0.4.2"
@ -37,6 +31,5 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum cortex-a 2.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4aab2f5271d9bf17a52b34dd99993648132df3dacb79312a33332f2b6ae1d0fd"
"checksum r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2a38df5b15c8d5c7e8654189744d8e396bddc18ad48041a500ce52d6948941f"
"checksum register 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a51f149d257caa7d9aed1f870d573ba5e2429576e6fed0693341f23078c98e55"
"checksum tock-registers 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "50af9c49c55cfb4437dd78c1fada3be5d088cbe1bea641db8171283503606a70"

@ -14,7 +14,6 @@ bsp_rpi3 = ["cortex-a", "register"]
bsp_rpi4 = ["cortex-a", "register"]
[dependencies]
r0 = "0.2.*"
# Optional dependencies
cortex-a = { version = "2.8.x", optional = true }

@ -86,7 +86,7 @@ sudo screen /dev/ttyUSB0 115200
diff -uNr 05_safe_globals/Cargo.toml 06_drivers_gpio_uart/Cargo.toml
--- 05_safe_globals/Cargo.toml
+++ 06_drivers_gpio_uart/Cargo.toml
@@ -10,11 +10,12 @@
@@ -10,10 +10,11 @@
# The features section is used to select the target board.
[features]
default = []
@ -96,7 +96,6 @@ diff -uNr 05_safe_globals/Cargo.toml 06_drivers_gpio_uart/Cargo.toml
+bsp_rpi4 = ["cortex-a", "register"]
[dependencies]
r0 = "0.2.*"
# Optional dependencies
cortex-a = { version = "2.8.x", optional = true }
@ -865,7 +864,7 @@ diff -uNr 05_safe_globals/src/interface.rs 06_drivers_gpio_uart/src/interface.rs
diff -uNr 05_safe_globals/src/main.rs 06_drivers_gpio_uart/src/main.rs
--- 05_safe_globals/src/main.rs
+++ 06_drivers_gpio_uart/src/main.rs
@@ -41,16 +41,48 @@
@@ -42,16 +42,48 @@
/// Early init code.
///

Binary file not shown.

Binary file not shown.

@ -36,6 +36,7 @@ mod runtime_init;
mod bsp;
mod interface;
mod memory;
mod panic_wait;
mod print;

@ -0,0 +1,25 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
//
// Copyright (c) 2018-2020 Andre Richter <andre.o.richter@gmail.com>
//! Memory Management.
use core::ops::Range;
/// Zero out a memory region.
///
/// # Safety
///
/// - `range.start` and `range.end` must be valid.
/// - `range.start` and `range.end` must be `T` aligned.
pub unsafe fn zero_volatile<T>(range: Range<*mut T>)
where
T: From<u8>,
{
let mut ptr = range.start;
while ptr < range.end {
core::ptr::write_volatile(ptr, T::from(0));
ptr = ptr.offset(1);
}
}

@ -4,6 +4,38 @@
//! Rust runtime initialization code.
use crate::memory;
use core::ops::Range;
/// Return the range spanning the .bss section.
///
/// # Safety
///
/// - The symbol-provided addresses must be valid.
/// - The symbol-provided addresses must be usize aligned.
unsafe fn bss_range() -> Range<*mut usize> {
extern "C" {
// Boundaries of the .bss section, provided by linker script symbols.
static mut __bss_start: usize;
static mut __bss_end: usize;
}
Range {
start: &mut __bss_start,
end: &mut __bss_end,
}
}
/// Zero out the .bss section.
///
/// # Safety
///
/// - Must only be called pre `kernel_init()`.
#[inline(always)]
unsafe fn zero_bss() {
memory::zero_volatile(bss_range());
}
/// Equivalent to `crt0` or `c0` code in C/C++ world. Clears the `bss` section, then jumps to kernel
/// init code.
///
@ -11,14 +43,7 @@
///
/// - Only a single core must be active and running this function.
pub unsafe fn runtime_init() -> ! {
extern "C" {
// Boundaries of the .bss section, provided by the linker script.
static mut __bss_start: u64;
static mut __bss_end: u64;
}
// Zero out the .bss section.
r0::zero_bss(&mut __bss_start, &mut __bss_end);
zero_bss();
crate::kernel_init()
}

@ -13,15 +13,9 @@ name = "kernel"
version = "0.1.0"
dependencies = [
"cortex-a 2.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"register 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "r0"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "register"
version = "0.4.2"
@ -37,6 +31,5 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum cortex-a 2.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4aab2f5271d9bf17a52b34dd99993648132df3dacb79312a33332f2b6ae1d0fd"
"checksum r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2a38df5b15c8d5c7e8654189744d8e396bddc18ad48041a500ce52d6948941f"
"checksum register 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a51f149d257caa7d9aed1f870d573ba5e2429576e6fed0693341f23078c98e55"
"checksum tock-registers 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "50af9c49c55cfb4437dd78c1fada3be5d088cbe1bea641db8171283503606a70"

@ -14,7 +14,6 @@ bsp_rpi3 = ["cortex-a", "register"]
bsp_rpi4 = ["cortex-a", "register"]
[dependencies]
r0 = "0.2.*"
# Optional dependencies
cortex-a = { version = "2.8.x", optional = true }

@ -298,7 +298,7 @@ diff -uNr 06_drivers_gpio_uart/src/main.rs 07_uart_chainloader/src/main.rs
mod runtime_init;
// Conditionally includes the selected `BSP` code.
@@ -64,25 +68,48 @@
@@ -65,25 +69,48 @@
fn kernel_main() -> ! {
use interface::console::All;
@ -418,9 +418,9 @@ diff -uNr 06_drivers_gpio_uart/src/relocate.rs 07_uart_chainloader/src/relocate.
diff -uNr 06_drivers_gpio_uart/src/runtime_init.rs 07_uart_chainloader/src/runtime_init.rs
--- 06_drivers_gpio_uart/src/runtime_init.rs
+++ 07_uart_chainloader/src/runtime_init.rs
@@ -4,21 +4,39 @@
//! Rust runtime initialization code.
@@ -36,14 +36,32 @@
memory::zero_volatile(bss_range());
}
-/// Equivalent to `crt0` or `c0` code in C/C++ world. Clears the `bss` section, then jumps to kernel
-/// init code.
@ -434,10 +434,7 @@ diff -uNr 06_drivers_gpio_uart/src/runtime_init.rs 07_uart_chainloader/src/runti
-///
-/// - Only a single core must be active and running this function.
-pub unsafe fn runtime_init() -> ! {
- extern "C" {
- // Boundaries of the .bss section, provided by the linker script.
- static mut __bss_start: u64;
- static mut __bss_end: u64;
- zero_bss();
+/// By indirecting through a trait object, we can make use of the property that vtables store
+/// absolute addresses. So calling `init()` this way will kick execution to the relocated binary.
+pub trait RunTimeInit {
@ -448,21 +445,12 @@ diff -uNr 06_drivers_gpio_uart/src/runtime_init.rs 07_uart_chainloader/src/runti
+ ///
+ /// - Only a single core must be active and running this function.
+ unsafe fn runtime_init(&self) -> ! {
+ extern "C" {
+ // Boundaries of the .bss section, provided by the linker script.
+ static mut __bss_start: u64;
+ static mut __bss_end: u64;
+ }
+
+ // Zero out the .bss section.
+ r0::zero_bss(&mut __bss_start, &mut __bss_end);
+ zero_bss();
+
+ crate::kernel_init()
}
+ }
+}
- // Zero out the .bss section.
- r0::zero_bss(&mut __bss_start, &mut __bss_end);
+
+struct Traitor;
+impl RunTimeInit for Traitor {}

Binary file not shown.

Binary file not shown.

@ -40,6 +40,7 @@ mod runtime_init;
mod bsp;
mod interface;
mod memory;
mod panic_wait;
mod print;

@ -0,0 +1,25 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
//
// Copyright (c) 2018-2020 Andre Richter <andre.o.richter@gmail.com>
//! Memory Management.
use core::ops::Range;
/// Zero out a memory region.
///
/// # Safety
///
/// - `range.start` and `range.end` must be valid.
/// - `range.start` and `range.end` must be `T` aligned.
pub unsafe fn zero_volatile<T>(range: Range<*mut T>)
where
T: From<u8>,
{
let mut ptr = range.start;
while ptr < range.end {
core::ptr::write_volatile(ptr, T::from(0));
ptr = ptr.offset(1);
}
}

@ -4,6 +4,38 @@
//! Rust runtime initialization code.
use crate::memory;
use core::ops::Range;
/// Return the range spanning the .bss section.
///
/// # Safety
///
/// - The symbol-provided addresses must be valid.
/// - The symbol-provided addresses must be usize aligned.
unsafe fn bss_range() -> Range<*mut usize> {
extern "C" {
// Boundaries of the .bss section, provided by linker script symbols.
static mut __bss_start: usize;
static mut __bss_end: usize;
}
Range {
start: &mut __bss_start,
end: &mut __bss_end,
}
}
/// Zero out the .bss section.
///
/// # Safety
///
/// - Must only be called pre `kernel_init()`.
#[inline(always)]
unsafe fn zero_bss() {
memory::zero_volatile(bss_range());
}
/// We are outsmarting the compiler here by using a trait as a layer of indirection. Because we are
/// generating PIC code, a static dispatch to `init()` would generate a relative jump from the
/// callee to `init()`. However, when calling `init()`, code just finished copying the binary to the
@ -20,14 +52,7 @@ pub trait RunTimeInit {
///
/// - Only a single core must be active and running this function.
unsafe fn runtime_init(&self) -> ! {
extern "C" {
// Boundaries of the .bss section, provided by the linker script.
static mut __bss_start: u64;
static mut __bss_end: u64;
}
// Zero out the .bss section.
r0::zero_bss(&mut __bss_start, &mut __bss_end);
zero_bss();
crate::kernel_init()
}

@ -13,15 +13,9 @@ name = "kernel"
version = "0.1.0"
dependencies = [
"cortex-a 2.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"register 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "r0"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "register"
version = "0.4.2"
@ -37,6 +31,5 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum cortex-a 2.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4aab2f5271d9bf17a52b34dd99993648132df3dacb79312a33332f2b6ae1d0fd"
"checksum r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2a38df5b15c8d5c7e8654189744d8e396bddc18ad48041a500ce52d6948941f"
"checksum register 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a51f149d257caa7d9aed1f870d573ba5e2429576e6fed0693341f23078c98e55"
"checksum tock-registers 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "50af9c49c55cfb4437dd78c1fada3be5d088cbe1bea641db8171283503606a70"

@ -14,7 +14,6 @@ bsp_rpi3 = ["cortex-a", "register"]
bsp_rpi4 = ["cortex-a", "register"]
[dependencies]
r0 = "0.2.*"
# Optional dependencies
cortex-a = { version = "2.8.x", optional = true }

@ -348,7 +348,7 @@ diff -uNr 07_uart_chainloader/src/main.rs 08_timestamps/src/main.rs
mod runtime_init;
// Conditionally includes the selected `BSP` code.
@@ -66,50 +62,25 @@
@@ -67,50 +63,25 @@
/// The main function running after the early init.
fn kernel_main() -> ! {
@ -547,9 +547,9 @@ diff -uNr 07_uart_chainloader/src/relocate.rs 08_timestamps/src/relocate.rs
diff -uNr 07_uart_chainloader/src/runtime_init.rs 08_timestamps/src/runtime_init.rs
--- 07_uart_chainloader/src/runtime_init.rs
+++ 08_timestamps/src/runtime_init.rs
@@ -4,39 +4,21 @@
//! Rust runtime initialization code.
@@ -36,32 +36,14 @@
memory::zero_volatile(bss_range());
}
-/// We are outsmarting the compiler here by using a trait as a layer of indirection. Because we are
-/// generating PIC code, a static dispatch to `init()` would generate a relative jump from the
@ -569,31 +569,19 @@ diff -uNr 07_uart_chainloader/src/runtime_init.rs 08_timestamps/src/runtime_init
- ///
- /// - Only a single core must be active and running this function.
- unsafe fn runtime_init(&self) -> ! {
- extern "C" {
- // Boundaries of the .bss section, provided by the linker script.
- static mut __bss_start: u64;
- static mut __bss_end: u64;
- }
-
- // Zero out the .bss section.
- r0::zero_bss(&mut __bss_start, &mut __bss_end);
- zero_bss();
-
- crate::kernel_init()
- }
-}
-
-struct Traitor;
-impl RunTimeInit for Traitor {}
+/// # Safety
+///
+/// - Only a single core must be active and running this function.
+pub unsafe fn runtime_init() -> ! {
+ extern "C" {
+ // Boundaries of the .bss section, provided by the linker script.
+ static mut __bss_start: u64;
+ static mut __bss_end: u64;
}
-}
-struct Traitor;
-impl RunTimeInit for Traitor {}
+ // Zero out the .bss section.
+ r0::zero_bss(&mut __bss_start, &mut __bss_end);
+ zero_bss();
-/// Give the callee a `RunTimeInit` trait object.
-pub fn get() -> &'static dyn RunTimeInit {

Binary file not shown.

Binary file not shown.

@ -36,6 +36,7 @@ mod runtime_init;
mod bsp;
mod interface;
mod memory;
mod panic_wait;
mod print;

@ -0,0 +1,25 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
//
// Copyright (c) 2018-2020 Andre Richter <andre.o.richter@gmail.com>
//! Memory Management.
use core::ops::Range;
/// Zero out a memory region.
///
/// # Safety
///
/// - `range.start` and `range.end` must be valid.
/// - `range.start` and `range.end` must be `T` aligned.
pub unsafe fn zero_volatile<T>(range: Range<*mut T>)
where
T: From<u8>,
{
let mut ptr = range.start;
while ptr < range.end {
core::ptr::write_volatile(ptr, T::from(0));
ptr = ptr.offset(1);
}
}

@ -4,6 +4,38 @@
//! Rust runtime initialization code.
use crate::memory;
use core::ops::Range;
/// Return the range spanning the .bss section.
///
/// # Safety
///
/// - The symbol-provided addresses must be valid.
/// - The symbol-provided addresses must be usize aligned.
unsafe fn bss_range() -> Range<*mut usize> {
extern "C" {
// Boundaries of the .bss section, provided by linker script symbols.
static mut __bss_start: usize;
static mut __bss_end: usize;
}
Range {
start: &mut __bss_start,
end: &mut __bss_end,
}
}
/// Zero out the .bss section.
///
/// # Safety
///
/// - Must only be called pre `kernel_init()`.
#[inline(always)]
unsafe fn zero_bss() {
memory::zero_volatile(bss_range());
}
/// Equivalent to `crt0` or `c0` code in C/C++ world. Clears the `bss` section, then jumps to kernel
/// init code.
///
@ -11,14 +43,7 @@
///
/// - Only a single core must be active and running this function.
pub unsafe fn runtime_init() -> ! {
extern "C" {
// Boundaries of the .bss section, provided by the linker script.
static mut __bss_start: u64;
static mut __bss_end: u64;
}
// Zero out the .bss section.
r0::zero_bss(&mut __bss_start, &mut __bss_end);
zero_bss();
crate::kernel_init()
}

@ -13,15 +13,9 @@ name = "kernel"
version = "0.1.0"
dependencies = [
"cortex-a 2.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"register 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "r0"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "register"
version = "0.4.2"
@ -37,6 +31,5 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum cortex-a 2.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4aab2f5271d9bf17a52b34dd99993648132df3dacb79312a33332f2b6ae1d0fd"
"checksum r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2a38df5b15c8d5c7e8654189744d8e396bddc18ad48041a500ce52d6948941f"
"checksum register 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a51f149d257caa7d9aed1f870d573ba5e2429576e6fed0693341f23078c98e55"
"checksum tock-registers 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "50af9c49c55cfb4437dd78c1fada3be5d088cbe1bea641db8171283503606a70"

@ -14,7 +14,6 @@ bsp_rpi3 = ["cortex-a", "register"]
bsp_rpi4 = ["cortex-a", "register"]
[dependencies]
r0 = "0.2.*"
# Optional dependencies
cortex-a = { version = "2.8.x", optional = true }

Binary file not shown.

Binary file not shown.

@ -36,6 +36,7 @@ mod runtime_init;
mod bsp;
mod interface;
mod memory;
mod panic_wait;
mod print;

@ -0,0 +1,25 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
//
// Copyright (c) 2018-2020 Andre Richter <andre.o.richter@gmail.com>
//! Memory Management.
use core::ops::Range;
/// Zero out a memory region.
///
/// # Safety
///
/// - `range.start` and `range.end` must be valid.
/// - `range.start` and `range.end` must be `T` aligned.
pub unsafe fn zero_volatile<T>(range: Range<*mut T>)
where
T: From<u8>,
{
let mut ptr = range.start;
while ptr < range.end {
core::ptr::write_volatile(ptr, T::from(0));
ptr = ptr.offset(1);
}
}

@ -4,6 +4,38 @@
//! Rust runtime initialization code.
use crate::memory;
use core::ops::Range;
/// Return the range spanning the .bss section.
///
/// # Safety
///
/// - The symbol-provided addresses must be valid.
/// - The symbol-provided addresses must be usize aligned.
unsafe fn bss_range() -> Range<*mut usize> {
extern "C" {
// Boundaries of the .bss section, provided by linker script symbols.
static mut __bss_start: usize;
static mut __bss_end: usize;
}
Range {
start: &mut __bss_start,
end: &mut __bss_end,
}
}
/// Zero out the .bss section.
///
/// # Safety
///
/// - Must only be called pre `kernel_init()`.
#[inline(always)]
unsafe fn zero_bss() {
memory::zero_volatile(bss_range());
}
/// Equivalent to `crt0` or `c0` code in C/C++ world. Clears the `bss` section, then jumps to kernel
/// init code.
///
@ -11,14 +43,7 @@
///
/// - Only a single core must be active and running this function.
pub unsafe fn runtime_init() -> ! {
extern "C" {
// Boundaries of the .bss section, provided by the linker script.
static mut __bss_start: u64;
static mut __bss_end: u64;
}
// Zero out the .bss section.
r0::zero_bss(&mut __bss_start, &mut __bss_end);
zero_bss();
crate::kernel_init()
}

@ -13,15 +13,9 @@ name = "kernel"
version = "0.1.0"
dependencies = [
"cortex-a 2.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"register 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "r0"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "register"
version = "0.4.2"
@ -37,6 +31,5 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum cortex-a 2.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4aab2f5271d9bf17a52b34dd99993648132df3dacb79312a33332f2b6ae1d0fd"
"checksum r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2a38df5b15c8d5c7e8654189744d8e396bddc18ad48041a500ce52d6948941f"
"checksum register 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a51f149d257caa7d9aed1f870d573ba5e2429576e6fed0693341f23078c98e55"
"checksum tock-registers 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "50af9c49c55cfb4437dd78c1fada3be5d088cbe1bea641db8171283503606a70"

@ -14,7 +14,6 @@ bsp_rpi3 = ["cortex-a", "register"]
bsp_rpi4 = ["cortex-a", "register"]
[dependencies]
r0 = "0.2.*"
# Optional dependencies
cortex-a = { version = "2.8.x", optional = true }

@ -407,7 +407,7 @@ diff -uNr 09_hw_debug_JTAG/src/arch.rs 10_privilege_level/src/arch.rs
diff -uNr 09_hw_debug_JTAG/src/main.rs 10_privilege_level/src/main.rs
--- 09_hw_debug_JTAG/src/main.rs
+++ 10_privilege_level/src/main.rs
@@ -63,9 +63,16 @@
@@ -64,9 +64,16 @@
/// The main function running after the early init.
fn kernel_main() -> ! {
use core::time::Duration;
@ -425,7 +425,7 @@ diff -uNr 09_hw_debug_JTAG/src/main.rs 10_privilege_level/src/main.rs
info!(
"Architectural timer resolution: {} ns",
arch::timer().resolution().as_nanos()
@@ -76,11 +83,12 @@
@@ -77,11 +84,12 @@
info!(" {}. {}", i + 1, driver.compatible());
}

Binary file not shown.

Binary file not shown.

@ -36,6 +36,7 @@ mod runtime_init;
mod bsp;
mod interface;
mod memory;
mod panic_wait;
mod print;

@ -0,0 +1,25 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
//
// Copyright (c) 2018-2020 Andre Richter <andre.o.richter@gmail.com>
//! Memory Management.
use core::ops::Range;
/// Zero out a memory region.
///
/// # Safety
///
/// - `range.start` and `range.end` must be valid.
/// - `range.start` and `range.end` must be `T` aligned.
pub unsafe fn zero_volatile<T>(range: Range<*mut T>)
where
T: From<u8>,
{
let mut ptr = range.start;
while ptr < range.end {
core::ptr::write_volatile(ptr, T::from(0));
ptr = ptr.offset(1);
}
}

@ -4,6 +4,38 @@
//! Rust runtime initialization code.
use crate::memory;
use core::ops::Range;
/// Return the range spanning the .bss section.
///
/// # Safety
///
/// - The symbol-provided addresses must be valid.
/// - The symbol-provided addresses must be usize aligned.
unsafe fn bss_range() -> Range<*mut usize> {
extern "C" {
// Boundaries of the .bss section, provided by linker script symbols.
static mut __bss_start: usize;
static mut __bss_end: usize;
}
Range {
start: &mut __bss_start,
end: &mut __bss_end,
}
}
/// Zero out the .bss section.
///
/// # Safety
///
/// - Must only be called pre `kernel_init()`.
#[inline(always)]
unsafe fn zero_bss() {
memory::zero_volatile(bss_range());
}
/// Equivalent to `crt0` or `c0` code in C/C++ world. Clears the `bss` section, then jumps to kernel
/// init code.
///
@ -11,14 +43,7 @@
///
/// - Only a single core must be active and running this function.
pub unsafe fn runtime_init() -> ! {
extern "C" {
// Boundaries of the .bss section, provided by the linker script.
static mut __bss_start: u64;
static mut __bss_end: u64;
}
// Zero out the .bss section.
r0::zero_bss(&mut __bss_start, &mut __bss_end);
zero_bss();
crate::kernel_init()
}

@ -13,15 +13,9 @@ name = "kernel"
version = "0.1.0"
dependencies = [
"cortex-a 2.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"register 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "r0"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "register"
version = "0.4.2"
@ -37,6 +31,5 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum cortex-a 2.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4aab2f5271d9bf17a52b34dd99993648132df3dacb79312a33332f2b6ae1d0fd"
"checksum r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2a38df5b15c8d5c7e8654189744d8e396bddc18ad48041a500ce52d6948941f"
"checksum register 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a51f149d257caa7d9aed1f870d573ba5e2429576e6fed0693341f23078c98e55"
"checksum tock-registers 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "50af9c49c55cfb4437dd78c1fada3be5d088cbe1bea641db8171283503606a70"

@ -14,7 +14,6 @@ bsp_rpi3 = ["cortex-a", "register"]
bsp_rpi4 = ["cortex-a", "register"]
[dependencies]
r0 = "0.2.*"
# Optional dependencies
cortex-a = { version = "2.8.x", optional = true }

@ -822,15 +822,7 @@ diff -uNr 10_privilege_level/src/main.rs 11_virtual_memory/src/main.rs
#![feature(format_args_nl)]
#![feature(panic_info_message)]
#![feature(trait_alias)]
@@ -36,6 +38,7 @@
mod bsp;
mod interface;
+mod memory;
mod panic_wait;
mod print;
@@ -46,8 +49,18 @@
@@ -47,8 +49,18 @@
/// # Safety
///
/// - Only a single core must be active and running this function.
@ -850,7 +842,7 @@ diff -uNr 10_privilege_level/src/main.rs 11_virtual_memory/src/main.rs
for i in bsp::device_drivers().iter() {
if let Err(()) = i.init() {
panic!("Error loading driver: {}", i.compatible())
@@ -67,6 +80,9 @@
@@ -68,6 +80,9 @@
info!("Booting on: {}", bsp::board_name());
@ -860,7 +852,7 @@ diff -uNr 10_privilege_level/src/main.rs 11_virtual_memory/src/main.rs
let (_, privilege_level) = arch::state::current_privilege_level();
info!("Current privilege level: {}", privilege_level);
@@ -86,6 +102,13 @@
@@ -87,6 +102,13 @@
info!("Timer test, spinning for 1 second");
arch::timer().spin_for(Duration::from_secs(1));
@ -878,15 +870,24 @@ diff -uNr 10_privilege_level/src/main.rs 11_virtual_memory/src/main.rs
diff -uNr 10_privilege_level/src/memory.rs 11_virtual_memory/src/memory.rs
--- 10_privilege_level/src/memory.rs
+++ 11_virtual_memory/src/memory.rs
@@ -0,0 +1,147 @@
+// SPDX-License-Identifier: MIT OR Apache-2.0
+//
+// Copyright (c) 2018-2020 Andre Richter <andre.o.richter@gmail.com>
+
+//! Memory Management.
+
+use core::{fmt, ops::RangeInclusive};
@@ -4,7 +4,10 @@
//! Memory Management.
-use core::ops::Range;
+use core::{
+ fmt,
+ ops::{Range, RangeInclusive},
+};
/// Zero out a memory region.
///
@@ -23,3 +26,144 @@
ptr = ptr.offset(1);
}
}
+
+#[allow(dead_code)]
+#[derive(Copy, Clone)]
+pub enum Translation {
+ Identity,

Binary file not shown.

Binary file not shown.

@ -4,8 +4,30 @@
//! Memory Management.
use core::{fmt, ops::RangeInclusive};
use core::{
fmt,
ops::{Range, RangeInclusive},
};
/// Zero out a memory region.
///
/// # Safety
///
/// - `range.start` and `range.end` must be valid.
/// - `range.start` and `range.end` must be `T` aligned.
pub unsafe fn zero_volatile<T>(range: Range<*mut T>)
where
T: From<u8>,
{
let mut ptr = range.start;
while ptr < range.end {
core::ptr::write_volatile(ptr, T::from(0));
ptr = ptr.offset(1);
}
}
#[allow(dead_code)]
#[derive(Copy, Clone)]
pub enum Translation {
Identity,

@ -4,6 +4,38 @@
//! Rust runtime initialization code.
use crate::memory;
use core::ops::Range;
/// Return the range spanning the .bss section.
///
/// # Safety
///
/// - The symbol-provided addresses must be valid.
/// - The symbol-provided addresses must be usize aligned.
unsafe fn bss_range() -> Range<*mut usize> {
extern "C" {
// Boundaries of the .bss section, provided by linker script symbols.
static mut __bss_start: usize;
static mut __bss_end: usize;
}
Range {
start: &mut __bss_start,
end: &mut __bss_end,
}
}
/// Zero out the .bss section.
///
/// # Safety
///
/// - Must only be called pre `kernel_init()`.
#[inline(always)]
unsafe fn zero_bss() {
memory::zero_volatile(bss_range());
}
/// Equivalent to `crt0` or `c0` code in C/C++ world. Clears the `bss` section, then jumps to kernel
/// init code.
///
@ -11,14 +43,7 @@
///
/// - Only a single core must be active and running this function.
pub unsafe fn runtime_init() -> ! {
extern "C" {
// Boundaries of the .bss section, provided by the linker script.
static mut __bss_start: u64;
static mut __bss_end: u64;
}
// Zero out the .bss section.
r0::zero_bss(&mut __bss_start, &mut __bss_end);
zero_bss();
crate::kernel_init()
}

@ -13,15 +13,9 @@ name = "kernel"
version = "0.1.0"
dependencies = [
"cortex-a 2.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"register 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "r0"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "register"
version = "0.4.2"
@ -37,6 +31,5 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum cortex-a 2.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4aab2f5271d9bf17a52b34dd99993648132df3dacb79312a33332f2b6ae1d0fd"
"checksum r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2a38df5b15c8d5c7e8654189744d8e396bddc18ad48041a500ce52d6948941f"
"checksum register 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a51f149d257caa7d9aed1f870d573ba5e2429576e6fed0693341f23078c98e55"
"checksum tock-registers 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "50af9c49c55cfb4437dd78c1fada3be5d088cbe1bea641db8171283503606a70"

@ -14,7 +14,6 @@ bsp_rpi3 = ["cortex-a", "register"]
bsp_rpi4 = ["cortex-a", "register"]
[dependencies]
r0 = "0.2.*"
# Optional dependencies
cortex-a = { version = "2.8.x", optional = true }

@ -986,16 +986,4 @@ diff -uNr 11_virtual_memory/src/main.rs 12_cpu_exceptions_part1/src/main.rs
loop {
let c = bsp::console().read_char();
diff -uNr 11_virtual_memory/src/memory.rs 12_cpu_exceptions_part1/src/memory.rs
--- 11_virtual_memory/src/memory.rs
+++ 12_cpu_exceptions_part1/src/memory.rs
@@ -6,6 +6,7 @@
use core::{fmt, ops::RangeInclusive};
+#[allow(dead_code)]
#[derive(Copy, Clone)]
pub enum Translation {
Identity,
```

Binary file not shown.

@ -4,7 +4,28 @@
//! Memory Management.
use core::{fmt, ops::RangeInclusive};
use core::{
fmt,
ops::{Range, RangeInclusive},
};
/// Zero out a memory region.
///
/// # Safety
///
/// - `range.start` and `range.end` must be valid.
/// - `range.start` and `range.end` must be `T` aligned.
pub unsafe fn zero_volatile<T>(range: Range<*mut T>)
where
T: From<u8>,
{
let mut ptr = range.start;
while ptr < range.end {
core::ptr::write_volatile(ptr, T::from(0));
ptr = ptr.offset(1);
}
}
#[allow(dead_code)]
#[derive(Copy, Clone)]

@ -4,6 +4,38 @@
//! Rust runtime initialization code.
use crate::memory;
use core::ops::Range;
/// Return the range spanning the .bss section.
///
/// # Safety
///
/// - The symbol-provided addresses must be valid.
/// - The symbol-provided addresses must be usize aligned.
unsafe fn bss_range() -> Range<*mut usize> {
extern "C" {
// Boundaries of the .bss section, provided by linker script symbols.
static mut __bss_start: usize;
static mut __bss_end: usize;
}
Range {
start: &mut __bss_start,
end: &mut __bss_end,
}
}
/// Zero out the .bss section.
///
/// # Safety
///
/// - Must only be called pre `kernel_init()`.
#[inline(always)]
unsafe fn zero_bss() {
memory::zero_volatile(bss_range());
}
/// Equivalent to `crt0` or `c0` code in C/C++ world. Clears the `bss` section, then jumps to kernel
/// init code.
///
@ -11,14 +43,7 @@
///
/// - Only a single core must be active and running this function.
pub unsafe fn runtime_init() -> ! {
extern "C" {
// Boundaries of the .bss section, provided by the linker script.
static mut __bss_start: u64;
static mut __bss_end: u64;
}
// Zero out the .bss section.
r0::zero_bss(&mut __bss_start, &mut __bss_end);
zero_bss();
crate::kernel_init()
}

@ -41,7 +41,6 @@ dependencies = [
"cortex-a 2.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"patches 0.1.0",
"qemu-exit 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"register 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"test-macros 0.1.0",
"test-types 0.1.0",
@ -80,11 +79,6 @@ dependencies = [
"proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "r0"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "register"
version = "0.4.2"
@ -175,7 +169,6 @@ dependencies = [
"checksum proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27"
"checksum qemu-exit 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6eef8966dfa42074458b801f4ca70c0a070a84a500022584cc11d7a3c1fdb105"
"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
"checksum r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2a38df5b15c8d5c7e8654189744d8e396bddc18ad48041a500ce52d6948941f"
"checksum register 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a51f149d257caa7d9aed1f870d573ba5e2429576e6fed0693341f23078c98e55"
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"

@ -14,7 +14,6 @@ bsp_rpi3 = ["cortex-a", "register"]
bsp_rpi4 = ["cortex-a", "register"]
[dependencies]
r0 = "0.2.*"
qemu-exit = "0.1.x"
test-types = { path = "test-types" }

@ -698,11 +698,13 @@ RUSTFLAGS="-C link-arg=-Tsrc/bsp/rpi/link.ld -C target-cpu=cortex-a53 -D warning
Finished release [optimized] target(s) in 0.74s
Running target/aarch64-unknown-none-softfloat/release/deps/libkernel-a8441de115ec3a67
-------------------------------------------------------------------
🦀 Running 2 tests
🦀 Running 4 tests
-------------------------------------------------------------------
1. test_runner_executes_in_kernel_mode.......................[ok]
2. virt_mem_layout_has_no_overlaps...........................[ok]
2. bss_section_is_sane.......................................[ok]
3. virt_mem_layout_has_no_overlaps...........................[ok]
4. zero_volatile_works.......................................[ok]
-------------------------------------------------------------------
✔️ Success: libkernel
@ -768,10 +770,10 @@ diff -uNr 12_cpu_exceptions_part1/.cargo/config 13_integrated_testing/.cargo/con
diff -uNr 12_cpu_exceptions_part1/Cargo.toml 13_integrated_testing/Cargo.toml
--- 12_cpu_exceptions_part1/Cargo.toml
+++ 13_integrated_testing/Cargo.toml
@@ -15,7 +15,38 @@
@@ -14,7 +14,38 @@
bsp_rpi4 = ["cortex-a", "register"]
[dependencies]
r0 = "0.2.*"
+qemu-exit = "0.1.x"
+test-types = { path = "test-types" }
@ -1156,7 +1158,7 @@ diff -uNr 12_cpu_exceptions_part1/src/bsp.rs 13_integrated_testing/src/bsp.rs
diff -uNr 12_cpu_exceptions_part1/src/lib.rs 13_integrated_testing/src/lib.rs
--- 12_cpu_exceptions_part1/src/lib.rs
+++ 13_integrated_testing/src/lib.rs
@@ -0,0 +1,69 @@
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: MIT OR Apache-2.0
+//
+// Copyright (c) 2018-2020 Andre Richter <andre.o.richter@gmail.com>
@ -1174,6 +1176,7 @@ diff -uNr 12_cpu_exceptions_part1/src/lib.rs 13_integrated_testing/src/lib.rs
+#![feature(global_asm)]
+#![feature(linkage)]
+#![feature(panic_info_message)]
+#![feature(slice_ptr_range)]
+#![feature(trait_alias)]
+#![no_std]
+// Testing
@ -1324,15 +1327,15 @@ diff -uNr 12_cpu_exceptions_part1/src/main.rs 13_integrated_testing/src/main.rs
diff -uNr 12_cpu_exceptions_part1/src/memory.rs 13_integrated_testing/src/memory.rs
--- 12_cpu_exceptions_part1/src/memory.rs
+++ 13_integrated_testing/src/memory.rs
@@ -6,7 +6,6 @@
use core::{fmt, ops::RangeInclusive};
@@ -27,7 +27,6 @@
}
}
-#[allow(dead_code)]
#[derive(Copy, Clone)]
pub enum Translation {
Identity,
@@ -145,4 +144,9 @@
@@ -166,4 +165,30 @@
info!("{}", i);
}
}
@ -1340,6 +1343,27 @@ diff -uNr 12_cpu_exceptions_part1/src/memory.rs 13_integrated_testing/src/memory
+ #[cfg(test)]
+ pub fn inner(&self) -> &[RangeDescriptor; NUM_SPECIAL_RANGES] {
+ &self.inner
+ }
+}
+
+//--------------------------------------------------------------------------------------------------
+// Testing
+//--------------------------------------------------------------------------------------------------
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use test_macros::kernel_test;
+
+ /// Check `zero_volatile()`.
+ #[kernel_test]
+ fn zero_volatile_works() {
+ let mut x: [usize; 3] = [10, 11, 12];
+ let x_range = x.as_mut_ptr_range();
+
+ unsafe { zero_volatile(x_range) };
+
+ assert_eq!(x, [0, 0, 0]);
+ }
}
@ -1392,22 +1416,41 @@ diff -uNr 12_cpu_exceptions_part1/src/panic_wait.rs 13_integrated_testing/src/pa
diff -uNr 12_cpu_exceptions_part1/src/runtime_init.rs 13_integrated_testing/src/runtime_init.rs
--- 12_cpu_exceptions_part1/src/runtime_init.rs
+++ 13_integrated_testing/src/runtime_init.rs
@@ -15,10 +15,15 @@
// Boundaries of the .bss section, provided by the linker script.
static mut __bss_start: u64;
static mut __bss_end: u64;
+
+ }
+
@@ -43,7 +43,34 @@
///
/// - Only a single core must be active and running this function.
pub unsafe fn runtime_init() -> ! {
+ extern "Rust" {
+ fn kernel_init() -> !;
}
// Zero out the .bss section.
r0::zero_bss(&mut __bss_start, &mut __bss_end);
+ }
+
zero_bss();
- crate::kernel_init()
+ kernel_init()
+}
+
+//--------------------------------------------------------------------------------------------------
+// Testing
+//--------------------------------------------------------------------------------------------------
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use test_macros::kernel_test;
+
+ /// Check `bss` section layout.
+ #[kernel_test]
+ fn bss_section_is_sane() {
+ use core::mem;
+
+ let start = unsafe { bss_range().start } as *const _ as usize;
+ let end = unsafe { bss_range().end } as *const _ as usize;
+
+ assert_eq!(start modulo mem::size_of::<usize>(), 0);
+ assert_eq!(end modulo mem::size_of::<usize>(), 0);
+ assert!(end >= start);
+ }
}
diff -uNr 12_cpu_exceptions_part1/test-macros/Cargo.toml 13_integrated_testing/test-macros/Cargo.toml

Binary file not shown.

Binary file not shown.

@ -15,6 +15,7 @@
#![feature(global_asm)]
#![feature(linkage)]
#![feature(panic_info_message)]
#![feature(slice_ptr_range)]
#![feature(trait_alias)]
#![no_std]
// Testing

@ -4,7 +4,28 @@
//! Memory Management.
use core::{fmt, ops::RangeInclusive};
use core::{
fmt,
ops::{Range, RangeInclusive},
};
/// Zero out a memory region.
///
/// # Safety
///
/// - `range.start` and `range.end` must be valid.
/// - `range.start` and `range.end` must be `T` aligned.
pub unsafe fn zero_volatile<T>(range: Range<*mut T>)
where
T: From<u8>,
{
let mut ptr = range.start;
while ptr < range.end {
core::ptr::write_volatile(ptr, T::from(0));
ptr = ptr.offset(1);
}
}
#[derive(Copy, Clone)]
pub enum Translation {
@ -150,3 +171,24 @@ impl<const NUM_SPECIAL_RANGES: usize> KernelVirtualLayout<{ NUM_SPECIAL_RANGES }
&self.inner
}
}
//--------------------------------------------------------------------------------------------------
// Testing
//--------------------------------------------------------------------------------------------------
#[cfg(test)]
mod tests {
use super::*;
use test_macros::kernel_test;
/// Check `zero_volatile()`.
#[kernel_test]
fn zero_volatile_works() {
let mut x: [usize; 3] = [10, 11, 12];
let x_range = x.as_mut_ptr_range();
unsafe { zero_volatile(x_range) };
assert_eq!(x, [0, 0, 0]);
}
}

@ -4,26 +4,73 @@
//! Rust runtime initialization code.
/// Equivalent to `crt0` or `c0` code in C/C++ world. Clears the `bss` section, then jumps to kernel
/// init code.
use crate::memory;
use core::ops::Range;
/// Return the range spanning the .bss section.
///
/// # Safety
///
/// - Only a single core must be active and running this function.
pub unsafe fn runtime_init() -> ! {
/// - The symbol-provided addresses must be valid.
/// - The symbol-provided addresses must be usize aligned.
unsafe fn bss_range() -> Range<*mut usize> {
extern "C" {
// Boundaries of the .bss section, provided by the linker script.
static mut __bss_start: u64;
static mut __bss_end: u64;
// Boundaries of the .bss section, provided by linker script symbols.
static mut __bss_start: usize;
static mut __bss_end: usize;
}
Range {
start: &mut __bss_start,
end: &mut __bss_end,
}
}
/// Zero out the .bss section.
///
/// # Safety
///
/// - Must only be called pre `kernel_init()`.
#[inline(always)]
unsafe fn zero_bss() {
memory::zero_volatile(bss_range());
}
/// Equivalent to `crt0` or `c0` code in C/C++ world. Clears the `bss` section, then jumps to kernel
/// init code.
///
/// # Safety
///
/// - Only a single core must be active and running this function.
pub unsafe fn runtime_init() -> ! {
extern "Rust" {
fn kernel_init() -> !;
}
// Zero out the .bss section.
r0::zero_bss(&mut __bss_start, &mut __bss_end);
zero_bss();
kernel_init()
}
//--------------------------------------------------------------------------------------------------
// Testing
//--------------------------------------------------------------------------------------------------
#[cfg(test)]
mod tests {
use super::*;
use test_macros::kernel_test;
/// Check `bss` section layout.
#[kernel_test]
fn bss_section_is_sane() {
use core::mem;
let start = unsafe { bss_range().start } as *const _ as usize;
let end = unsafe { bss_range().end } as *const _ as usize;
assert_eq!(start % mem::size_of::<usize>(), 0);
assert_eq!(end % mem::size_of::<usize>(), 0);
assert!(end >= start);
}
}

@ -13,15 +13,9 @@ name = "kernel"
version = "0.1.0"
dependencies = [
"cortex-a 2.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"register 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "r0"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "register"
version = "0.4.2"
@ -37,6 +31,5 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum cortex-a 2.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4aab2f5271d9bf17a52b34dd99993648132df3dacb79312a33332f2b6ae1d0fd"
"checksum r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2a38df5b15c8d5c7e8654189744d8e396bddc18ad48041a500ce52d6948941f"
"checksum register 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a51f149d257caa7d9aed1f870d573ba5e2429576e6fed0693341f23078c98e55"
"checksum tock-registers 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "50af9c49c55cfb4437dd78c1fada3be5d088cbe1bea641db8171283503606a70"

@ -14,7 +14,6 @@ bsp_rpi3 = ["cortex-a", "register"]
bsp_rpi4 = ["cortex-a", "register"]
[dependencies]
r0 = "0.2.*"
# Optional dependencies
cortex-a = { version = "2.8.x", optional = true }

Binary file not shown.

Binary file not shown.

@ -36,6 +36,7 @@ mod runtime_init;
mod bsp;
mod interface;
mod memory;
mod panic_wait;
mod print;

@ -0,0 +1,25 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
//
// Copyright (c) 2018-2020 Andre Richter <andre.o.richter@gmail.com>
//! Memory Management.
use core::ops::Range;
/// Zero out a memory region.
///
/// # Safety
///
/// - `range.start` and `range.end` must be valid.
/// - `range.start` and `range.end` must be `T` aligned.
pub unsafe fn zero_volatile<T>(range: Range<*mut T>)
where
T: From<u8>,
{
let mut ptr = range.start;
while ptr < range.end {
core::ptr::write_volatile(ptr, T::from(0));
ptr = ptr.offset(1);
}
}

@ -4,6 +4,38 @@
//! Rust runtime initialization code.
use crate::memory;
use core::ops::Range;
/// Return the range spanning the .bss section.
///
/// # Safety
///
/// - The symbol-provided addresses must be valid.
/// - The symbol-provided addresses must be usize aligned.
unsafe fn bss_range() -> Range<*mut usize> {
extern "C" {
// Boundaries of the .bss section, provided by linker script symbols.
static mut __bss_start: usize;
static mut __bss_end: usize;
}
Range {
start: &mut __bss_start,
end: &mut __bss_end,
}
}
/// Zero out the .bss section.
///
/// # Safety
///
/// - Must only be called pre `kernel_init()`.
#[inline(always)]
unsafe fn zero_bss() {
memory::zero_volatile(bss_range());
}
/// Equivalent to `crt0` or `c0` code in C/C++ world. Clears the `bss` section, then jumps to kernel
/// init code.
///
@ -11,14 +43,7 @@
///
/// - Only a single core must be active and running this function.
pub unsafe fn runtime_init() -> ! {
extern "C" {
// Boundaries of the .bss section, provided by the linker script.
static mut __bss_start: u64;
static mut __bss_end: u64;
}
// Zero out the .bss section.
r0::zero_bss(&mut __bss_start, &mut __bss_end);
zero_bss();
crate::kernel_init()
}

Loading…
Cancel
Save