Skip to content

Commit 1a40f63

Browse files
authored
Merge pull request tock#4475 from pqcfox/root-of-trust-tutorial
boards: tutorials: Add root of trust tutorial board
2 parents 544b334 + 1ee25f3 commit 1a40f63

8 files changed

Lines changed: 296 additions & 2 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ members = [
6161
"boards/configurations/nrf52840dk/nrf52840dk-test-kernel",
6262
"boards/configurations/nrf52840dk/nrf52840dk-test-dynamic-app-load",
6363
"boards/configurations/microbit_v2/microbit_v2-test-dynamic-app-load",
64+
"boards/tutorials/nrf52840dk-root-of-trust-tutorial",
6465
"boards/tutorials/nrf52840dk-dynamic-apps-and-policies",
6566
"boards/tutorials/nrf52840dk-hotp-tutorial",
6667
"boards/tutorials/nrf52840dk-thread-tutorial",

boards/nordic/nrf52840dk/src/lib.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ pub unsafe fn ieee802154_udp(
396396
/// removed when this function returns. Otherwise, the stack space used for
397397
/// these static_inits is wasted.
398398
#[inline(never)]
399-
pub unsafe fn start() -> (
399+
pub unsafe fn start_no_pconsole() -> (
400400
&'static kernel::Kernel,
401401
Platform,
402402
&'static Chip,
@@ -915,7 +915,6 @@ pub unsafe fn start() -> (
915915
systick: cortexm4::systick::SysTick::new_with_calibration(64000000),
916916
};
917917

918-
let _ = platform.pconsole.start();
919918
base_peripherals.adc.calibrate();
920919

921920
debug!("Initialization complete. Entering main loop\r");
@@ -929,3 +928,19 @@ pub unsafe fn start() -> (
929928
mux_alarm,
930929
)
931930
}
931+
932+
/// This is in a separate, inline(never) function so that its stack frame is
933+
/// removed when this function returns. Otherwise, the stack space used for
934+
/// these static_inits is wasted.
935+
#[inline(never)]
936+
pub unsafe fn start() -> (
937+
&'static kernel::Kernel,
938+
Platform,
939+
&'static Chip,
940+
&'static Nrf52840DefaultPeripherals<'static>,
941+
&'static MuxAlarm<'static, nrf52840::rtc::Rtc<'static>>,
942+
) {
943+
let (kernel, platform, chip, peripherals, mux_alarm) = start_no_pconsole();
944+
let _ = platform.pconsole.start();
945+
(kernel, platform, chip, peripherals, mux_alarm)
946+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Licensed under the Apache License, Version 2.0 or the MIT License.
2+
# SPDX-License-Identifier: Apache-2.0 OR MIT
3+
# Copyright Tock Contributors 2024.
4+
5+
include = [
6+
"../../../cargo/tock_flags.toml",
7+
"../../../cargo/unstable_flags.toml",
8+
]
9+
10+
[build]
11+
target = "thumbv7em-none-eabi"
12+
13+
[unstable]
14+
config-include = true
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Licensed under the Apache License, Version 2.0 or the MIT License.
2+
# SPDX-License-Identifier: Apache-2.0 OR MIT
3+
# Copyright Tock Contributors 2024.
4+
5+
[package]
6+
name = "nrf52840dk-root-of-trust-tutorial"
7+
version.workspace = true
8+
authors.workspace = true
9+
build = "../../build.rs"
10+
edition.workspace = true
11+
12+
[features]
13+
default = ["screen_ssd1306"]
14+
screen_ssd1306 = []
15+
screen_sh1106 = []
16+
17+
[dependencies]
18+
kernel = { path = "../../../kernel" }
19+
nrf52840 = { path = "../../../chips/nrf52840" }
20+
nrf52840dk = { path = "../../nordic/nrf52840dk" }
21+
capsules-core = { path = "../../../capsules/core" }
22+
capsules-extra = { path = "../../../capsules/extra" }
23+
capsules-system = { path = "../../../capsules/system" }
24+
components = { path = "../../components" }
25+
26+
[build-dependencies]
27+
tock_build_scripts = { path = "../../build_scripts" }
28+
29+
[lints]
30+
workspace = true
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Licensed under the Apache License, Version 2.0 or the MIT License.
2+
# SPDX-License-Identifier: Apache-2.0 OR MIT
3+
# Copyright Tock Contributors 2024.
4+
5+
include ../../Makefile.common
6+
include ../../configurations/nrf52840dk/nrf52840dk.mk
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
nRF52840DK Board Definition for the Tock Attestation Tutorial
2+
=============================================================
3+
4+
This is the board definition for the nRF52840DK target used in the
5+
[attestation tutorial](https://book.tockos.org/course/attestation/overview).
6+
7+
Please follow the instructions in that tutorial. You may also want to look at
8+
the documentation of the base nRF52840DK board definition
9+
[here](../../nordic/nrf52840dk/README.md).
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/* Licensed under the Apache License, Version 2.0 or the MIT License. */
2+
/* SPDX-License-Identifier: Apache-2.0 OR MIT */
3+
/* Copyright Tock Contributors 2024. */
4+
5+
INCLUDE ../../nordic/nrf52840_chip_layout.ld
6+
INCLUDE tock_kernel_layout.ld
Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
// Licensed under the Apache License, Version 2.0 or the MIT License.
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
// Copyright Tock Contributors 2024.
4+
5+
//! Tock kernel for the Nordic Semiconductor nRF52840 development kit (DK).
6+
7+
#![no_std]
8+
#![no_main]
9+
#![deny(missing_docs)]
10+
11+
use core::ptr::addr_of_mut;
12+
use kernel::component::Component;
13+
use kernel::debug;
14+
use kernel::platform::{KernelResources, SyscallDriverLookup};
15+
use kernel::static_init;
16+
use kernel::{capabilities, create_capability};
17+
use nrf52840::gpio::Pin;
18+
use nrf52840dk_lib::{self, PROCESSES};
19+
20+
// State for loading and holding applications.
21+
// How should the kernel respond when a process faults.
22+
const FAULT_RESPONSE: capsules_system::process_policies::PanicFaultPolicy =
23+
capsules_system::process_policies::PanicFaultPolicy {};
24+
25+
const CRYPT_SIZE: usize = 7 * kernel::hil::symmetric_encryption::AES128_BLOCK_SIZE;
26+
27+
// Screen
28+
type ScreenDriver = components::screen::ScreenComponentType;
29+
30+
struct Platform {
31+
base: nrf52840dk_lib::Platform,
32+
screen: &'static ScreenDriver,
33+
oracle: &'static capsules_extra::tutorials::encryption_oracle_chkpt5::EncryptionOracleDriver<
34+
'static,
35+
nrf52840::aes::AesECB<'static>,
36+
>,
37+
}
38+
39+
impl SyscallDriverLookup for Platform {
40+
fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
41+
where
42+
F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
43+
{
44+
match driver_num {
45+
capsules_extra::screen::DRIVER_NUM => f(Some(self.screen)),
46+
capsules_extra::tutorials::encryption_oracle_chkpt5::DRIVER_NUM => f(Some(self.oracle)),
47+
_ => self.base.with_driver(driver_num, f),
48+
}
49+
}
50+
}
51+
52+
type Chip = nrf52840dk_lib::Chip;
53+
54+
impl KernelResources<Chip> for Platform {
55+
type SyscallDriverLookup = Self;
56+
type SyscallFilter = <nrf52840dk_lib::Platform as KernelResources<Chip>>::SyscallFilter;
57+
type ProcessFault = <nrf52840dk_lib::Platform as KernelResources<Chip>>::ProcessFault;
58+
type Scheduler = <nrf52840dk_lib::Platform as KernelResources<Chip>>::Scheduler;
59+
type SchedulerTimer = <nrf52840dk_lib::Platform as KernelResources<Chip>>::SchedulerTimer;
60+
type WatchDog = <nrf52840dk_lib::Platform as KernelResources<Chip>>::WatchDog;
61+
type ContextSwitchCallback =
62+
<nrf52840dk_lib::Platform as KernelResources<Chip>>::ContextSwitchCallback;
63+
64+
fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup {
65+
self
66+
}
67+
fn syscall_filter(&self) -> &Self::SyscallFilter {
68+
self.base.syscall_filter()
69+
}
70+
fn process_fault(&self) -> &Self::ProcessFault {
71+
self.base.process_fault()
72+
}
73+
fn scheduler(&self) -> &Self::Scheduler {
74+
self.base.scheduler()
75+
}
76+
fn scheduler_timer(&self) -> &Self::SchedulerTimer {
77+
self.base.scheduler_timer()
78+
}
79+
fn watchdog(&self) -> &Self::WatchDog {
80+
self.base.watchdog()
81+
}
82+
fn context_switch_callback(&self) -> &Self::ContextSwitchCallback {
83+
self.base.context_switch_callback()
84+
}
85+
}
86+
87+
/// Main function called after RAM initialized.
88+
#[no_mangle]
89+
pub unsafe fn main() {
90+
let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
91+
92+
// Create the base board:
93+
let (board_kernel, base_platform, chip, nrf52840_peripherals, _mux_alarm) =
94+
nrf52840dk_lib::start_no_pconsole();
95+
96+
//--------------------------------------------------------------------------
97+
// SCREEN
98+
//--------------------------------------------------------------------------
99+
100+
const SCREEN_I2C_SDA_PIN: Pin = Pin::P1_10;
101+
const SCREEN_I2C_SCL_PIN: Pin = Pin::P1_11;
102+
103+
let i2c_bus = components::i2c::I2CMuxComponent::new(&nrf52840_peripherals.nrf52.twi1, None)
104+
.finalize(components::i2c_mux_component_static!(nrf52840::i2c::TWI));
105+
nrf52840_peripherals.nrf52.twi1.configure(
106+
nrf52840::pinmux::Pinmux::new(SCREEN_I2C_SCL_PIN as u32),
107+
nrf52840::pinmux::Pinmux::new(SCREEN_I2C_SDA_PIN as u32),
108+
);
109+
nrf52840_peripherals
110+
.nrf52
111+
.twi1
112+
.set_speed(nrf52840::i2c::Speed::K400);
113+
114+
// I2C address is b011110X, and on this board D/C̅ is GND.
115+
let ssd1306_sh1106_i2c = components::i2c::I2CComponent::new(i2c_bus, 0x3c)
116+
.finalize(components::i2c_component_static!(nrf52840::i2c::TWI));
117+
118+
// Create the ssd1306 object for the actual screen driver.
119+
#[cfg(feature = "screen_ssd1306")]
120+
let ssd1306_sh1106 = components::ssd1306::Ssd1306Component::new(ssd1306_sh1106_i2c, true)
121+
.finalize(components::ssd1306_component_static!(nrf52840::i2c::TWI));
122+
123+
#[cfg(feature = "screen_sh1106")]
124+
let ssd1306_sh1106 = components::sh1106::Sh1106Component::new(ssd1306_sh1106_i2c, true)
125+
.finalize(components::sh1106_component_static!(nrf52840::i2c::TWI));
126+
127+
let screen = components::screen::ScreenComponent::new(
128+
board_kernel,
129+
capsules_extra::screen::DRIVER_NUM,
130+
ssd1306_sh1106,
131+
None,
132+
)
133+
.finalize(components::screen_component_static!(1032));
134+
135+
ssd1306_sh1106.init_screen();
136+
137+
//--------------------------------------------------------------------------
138+
// ENCRYPTION ORACLE
139+
//--------------------------------------------------------------------------
140+
141+
let aes_src_buffer = kernel::static_init!([u8; 16], [0; 16]);
142+
let aes_dst_buffer = kernel::static_init!([u8; CRYPT_SIZE], [0; CRYPT_SIZE]);
143+
144+
let oracle = static_init!(
145+
capsules_extra::tutorials::encryption_oracle_chkpt5::EncryptionOracleDriver<
146+
'static,
147+
nrf52840::aes::AesECB<'static>,
148+
>,
149+
capsules_extra::tutorials::encryption_oracle_chkpt5::EncryptionOracleDriver::new(
150+
&nrf52840_peripherals.nrf52.ecb,
151+
aes_src_buffer,
152+
aes_dst_buffer,
153+
board_kernel.create_grant(
154+
capsules_extra::tutorials::encryption_oracle_chkpt5::DRIVER_NUM, // our driver number
155+
&create_capability!(capabilities::MemoryAllocationCapability)
156+
),
157+
),
158+
);
159+
160+
kernel::hil::symmetric_encryption::AES128::set_client(&nrf52840_peripherals.nrf52.ecb, oracle);
161+
162+
//--------------------------------------------------------------------------
163+
// PLATFORM SETUP, SCHEDULER, AND START KERNEL LOOP
164+
//--------------------------------------------------------------------------
165+
166+
let platform = Platform {
167+
base: base_platform,
168+
screen,
169+
oracle,
170+
};
171+
172+
// These symbols are defined in the linker script.
173+
extern "C" {
174+
/// Beginning of the ROM region containing app images.
175+
static _sapps: u8;
176+
/// End of the ROM region containing app images.
177+
static _eapps: u8;
178+
/// Beginning of the RAM region for app memory.
179+
static mut _sappmem: u8;
180+
/// End of the RAM region for app memory.
181+
static _eappmem: u8;
182+
}
183+
184+
let process_management_capability =
185+
create_capability!(capabilities::ProcessManagementCapability);
186+
187+
kernel::process::load_processes(
188+
board_kernel,
189+
chip,
190+
core::slice::from_raw_parts(
191+
core::ptr::addr_of!(_sapps),
192+
core::ptr::addr_of!(_eapps) as usize - core::ptr::addr_of!(_sapps) as usize,
193+
),
194+
core::slice::from_raw_parts_mut(
195+
core::ptr::addr_of_mut!(_sappmem),
196+
core::ptr::addr_of!(_eappmem) as usize - core::ptr::addr_of!(_sappmem) as usize,
197+
),
198+
&mut *addr_of_mut!(PROCESSES),
199+
&FAULT_RESPONSE,
200+
&process_management_capability,
201+
)
202+
.unwrap_or_else(|err| {
203+
debug!("Error loading processes!");
204+
debug!("{:?}", err);
205+
});
206+
207+
board_kernel.kernel_loop(
208+
&platform,
209+
chip,
210+
Some(&platform.base.ipc),
211+
&main_loop_capability,
212+
);
213+
}

0 commit comments

Comments
 (0)