1#![no_std]
8#![no_main]
9#![deny(missing_docs)]
10
11use kernel::component::Component;
12use kernel::deferred_call::DeferredCallClient;
13use kernel::platform::{KernelResources, SyscallDriverLookup};
14use kernel::process::ProcessLoadingAsync;
15use kernel::process::ShortId;
16use kernel::{capabilities, create_capability, static_init};
17use nrf52840::gpio::Pin;
18use nrf52840::interrupt_service::Nrf52840DefaultPeripherals;
19
20mod app_id_assigner_name_metadata;
21mod checker_credentials_not_required;
22mod system_call_filter;
23
24const SCREEN_I2C_SDA_PIN: Pin = Pin::P1_10;
26const SCREEN_I2C_SCL_PIN: Pin = Pin::P1_11;
27
28const NUM_PROCS: usize = 8;
30
31type ChipHw = nrf52840dk_lib::ChipHw;
32
33const FAULT_RESPONSE: capsules_system::process_policies::StopWithDebugFaultPolicy =
35 capsules_system::process_policies::StopWithDebugFaultPolicy {};
36
37const NUM_CREDENTIAL_KEYS: usize = 1;
39const SIGNATURE_KEY_LEN: usize = 64;
41const SIGNATURE_HASH_LEN: usize = 32;
43const SIGNATURE_SIG_LEN: usize = 64;
45
46pub struct PMCapability;
52unsafe impl capabilities::ProcessManagementCapability for PMCapability {}
53unsafe impl capabilities::ProcessStartCapability for PMCapability {}
54
55#[cfg(feature = "screen_ssd1306")]
56type Screen = components::ssd1306::Ssd1306ComponentType<nrf52840::i2c::TWI<'static>>;
57#[cfg(feature = "screen_sh1106")]
58type Screen = components::sh1106::Sh1106ComponentType<nrf52840::i2c::TWI<'static>>;
59type ScreenDriver = components::screen::ScreenSharedComponentType<Screen>;
60
61type ProcessInfoDriver = capsules_extra::process_info_driver::ProcessInfo<PMCapability>;
62
63type IsolatedNonvolatileStorageDriver =
64 capsules_extra::isolated_nonvolatile_storage_driver::IsolatedNonvolatileStorage<
65 'static,
66 {
67 components::isolated_nonvolatile_storage::ISOLATED_NONVOLATILE_STORAGE_APP_REGION_SIZE_DEFAULT
68 },
69 >;
70
71type FlashUser =
72 capsules_core::virtualizers::virtual_flash::FlashUser<'static, nrf52840::nvmc::Nvmc>;
73type NonVolatilePages = components::dynamic_binary_storage::NVPages<FlashUser>;
74
75type DynamicBinaryStorage<'a> = kernel::dynamic_binary_storage::SequentialDynamicBinaryStorage<
76 'static,
77 'static,
78 nrf52840::chip::NRF52<'a, Nrf52840DefaultPeripherals<'a>>,
79 kernel::process::ProcessStandardDebugFull,
80 NonVolatilePages,
81>;
82type AppLoaderDriver = capsules_extra::app_loader::AppLoader<
83 DynamicBinaryStorage<'static>,
84 DynamicBinaryStorage<'static>,
85>;
86
87type Verifier = ecdsa_sw::p256_verifier::EcdsaP256SignatureVerifier<'static>;
88type SignatureVerifyInMemoryKeys =
89 components::signature_verify_in_memory_keys::SignatureVerifyInMemoryKeysComponentType<
90 Verifier,
91 NUM_CREDENTIAL_KEYS,
92 SIGNATURE_KEY_LEN,
93 SIGNATURE_HASH_LEN,
94 SIGNATURE_SIG_LEN,
95 >;
96type SignatureChecker = components::appid::checker_signature::AppCheckerSignatureComponentType<
97 SignatureVerifyInMemoryKeys,
98 capsules_extra::sha256::Sha256Software<'static>,
99 SIGNATURE_HASH_LEN,
100 SIGNATURE_SIG_LEN,
101>;
102
103fn create_short_id_from_name(name: &str, metadata: u8) -> ShortId {
108 let sum = kernel::utilities::helpers::crc32_posix(name.as_bytes());
109
110 let sid = ((metadata as u32) << 28) | (sum & 0xFFFFFFF);
112
113 core::num::NonZeroU32::new(sid).into()
114}
115
116struct Platform {
121 board_kernel: &'static kernel::Kernel,
122 syscall_filter: &'static system_call_filter::DynamicPoliciesCustomFilter,
123 base: nrf52840dk_lib::Platform,
124 screen: &'static ScreenDriver,
125 process_info: &'static ProcessInfoDriver,
126 nonvolatile_storage: &'static IsolatedNonvolatileStorageDriver,
127 dynamic_app_loader: &'static AppLoaderDriver,
128}
129
130impl SyscallDriverLookup for Platform {
132 fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
133 where
134 F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
135 {
136 match driver_num {
137 capsules_extra::screen::screen::DRIVER_NUM => f(Some(self.screen)),
138 capsules_extra::process_info_driver::DRIVER_NUM => f(Some(self.process_info)),
139 capsules_extra::isolated_nonvolatile_storage_driver::DRIVER_NUM => {
140 f(Some(self.nonvolatile_storage))
141 }
142 capsules_extra::app_loader::DRIVER_NUM => f(Some(self.dynamic_app_loader)),
143 _ => self.base.with_driver(driver_num, f),
144 }
145 }
146}
147
148impl KernelResources<ChipHw> for Platform {
150 type SyscallDriverLookup = Self;
151 type SyscallFilter = system_call_filter::DynamicPoliciesCustomFilter;
152 type ProcessFault = <nrf52840dk_lib::Platform as KernelResources<ChipHw>>::ProcessFault;
153 type Scheduler = <nrf52840dk_lib::Platform as KernelResources<ChipHw>>::Scheduler;
154 type SchedulerTimer = <nrf52840dk_lib::Platform as KernelResources<ChipHw>>::SchedulerTimer;
155 type WatchDog = <nrf52840dk_lib::Platform as KernelResources<ChipHw>>::WatchDog;
156 type ContextSwitchCallback =
157 <nrf52840dk_lib::Platform as KernelResources<ChipHw>>::ContextSwitchCallback;
158
159 fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup {
160 self
161 }
162 fn syscall_filter(&self) -> &Self::SyscallFilter {
163 self.syscall_filter
164 }
165 fn process_fault(&self) -> &Self::ProcessFault {
166 self.base.process_fault()
167 }
168 fn scheduler(&self) -> &Self::Scheduler {
169 self.base.scheduler()
170 }
171 fn scheduler_timer(&self) -> &Self::SchedulerTimer {
172 self.base.scheduler_timer()
173 }
174 fn watchdog(&self) -> &Self::WatchDog {
175 self.base.watchdog()
176 }
177 fn context_switch_callback(&self) -> &Self::ContextSwitchCallback {
178 self.base.context_switch_callback()
179 }
180}
181
182impl kernel::process::ProcessLoadingAsyncClient for Platform {
184 fn process_loaded(&self, _result: Result<(), kernel::process::ProcessLoadError>) {}
185
186 fn process_loading_finished(&self) {
187 kernel::debug!("Processes Loaded at Main:");
188
189 for (i, p) in self
190 .board_kernel
191 .process_iter_capability(&create_capability!(
192 capabilities::ProcessManagementCapability
193 ))
194 .enumerate()
195 {
196 kernel::debug!("[{}] {}", i, p.get_process_name());
197 kernel::debug!(" ShortId: {}", p.short_app_id());
198 }
199 }
200}
201
202#[no_mangle]
208pub unsafe fn main() {
209 let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
210
211 let (board_kernel, base_platform, chip, nrf52840_peripherals, _mux_alarm) =
213 nrf52840dk_lib::start();
214
215 let i2c_bus = components::i2c::I2CMuxComponent::new(&nrf52840_peripherals.nrf52.twi1, None)
220 .finalize(components::i2c_mux_component_static!(nrf52840::i2c::TWI));
221 nrf52840_peripherals.nrf52.twi1.configure(
222 nrf52840::pinmux::Pinmux::new(SCREEN_I2C_SCL_PIN as u32),
223 nrf52840::pinmux::Pinmux::new(SCREEN_I2C_SDA_PIN as u32),
224 );
225 nrf52840_peripherals
226 .nrf52
227 .twi1
228 .set_speed(nrf52840::i2c::Speed::K400);
229
230 let ssd1306_sh1106_i2c = components::i2c::I2CComponent::new(i2c_bus, 0x3c)
232 .finalize(components::i2c_component_static!(nrf52840::i2c::TWI));
233
234 #[cfg(feature = "screen_ssd1306")]
236 let ssd1306_sh1106 = components::ssd1306::Ssd1306Component::new(ssd1306_sh1106_i2c, true)
237 .finalize(components::ssd1306_component_static!(nrf52840::i2c::TWI));
238
239 #[cfg(feature = "screen_sh1106")]
240 let ssd1306_sh1106 = components::sh1106::Sh1106Component::new(ssd1306_sh1106_i2c, true)
241 .finalize(components::sh1106_component_static!(nrf52840::i2c::TWI));
242
243 let apps_regions = kernel::static_init!(
244 [capsules_extra::screen::screen_shared::AppScreenRegion; 3],
245 [
246 capsules_extra::screen::screen_shared::AppScreenRegion::new(
247 create_short_id_from_name("process_manager", 0x0),
248 0, 0, 16 * 8, 7 * 8 ),
253 capsules_extra::screen::screen_shared::AppScreenRegion::new(
254 create_short_id_from_name("counter", 0x0),
255 0, 7 * 8, 8 * 8, 1 * 8 ),
260 capsules_extra::screen::screen_shared::AppScreenRegion::new(
261 create_short_id_from_name("temperature", 0x0),
262 8 * 8, 7 * 8, 8 * 8, 1 * 8 )
267 ]
268 );
269
270 let screen = components::screen::ScreenSharedComponent::new(
271 board_kernel,
272 capsules_extra::screen::screen::DRIVER_NUM,
273 ssd1306_sh1106,
274 apps_regions,
275 )
276 .finalize(components::screen_shared_component_static!(1032, Screen));
277
278 ssd1306_sh1106.init_screen();
279
280 let mux_flash = components::flash::FlashMuxComponent::new(&nrf52840_peripherals.nrf52.nvmc)
285 .finalize(components::flash_mux_component_static!(
286 nrf52840::nvmc::Nvmc
287 ));
288
289 let virtual_flash_dbs = components::flash::FlashUserComponent::new(mux_flash).finalize(
291 components::flash_user_component_static!(nrf52840::nvmc::Nvmc),
292 );
293
294 let virtual_flash_nvm = components::flash::FlashUserComponent::new(mux_flash).finalize(
296 components::flash_user_component_static!(nrf52840::nvmc::Nvmc),
297 );
298
299 kernel::storage_volume!(APP_STORAGE, 32);
305
306 let nonvolatile_storage = components::isolated_nonvolatile_storage::IsolatedNonvolatileStorageComponent::new(
307 board_kernel,
308 capsules_extra::isolated_nonvolatile_storage_driver::DRIVER_NUM,
309 virtual_flash_nvm,
310 core::ptr::addr_of!(APP_STORAGE) as usize,
311 APP_STORAGE.len()
312 )
313 .finalize(components::isolated_nonvolatile_storage_component_static!(
314 capsules_core::virtualizers::virtual_flash::FlashUser<'static, nrf52840::nvmc::Nvmc>,
315 { components::isolated_nonvolatile_storage::ISOLATED_NONVOLATILE_STORAGE_APP_REGION_SIZE_DEFAULT }
316 ));
317
318 let process_info = components::process_info_driver::ProcessInfoComponent::new(
323 board_kernel,
324 capsules_extra::process_info_driver::DRIVER_NUM,
325 PMCapability,
326 )
327 .finalize(components::process_info_component_static!(PMCapability));
328
329 let syscall_filter = static_init!(
334 system_call_filter::DynamicPoliciesCustomFilter,
335 system_call_filter::DynamicPoliciesCustomFilter {}
336 );
337
338 let sha = components::sha::ShaSoftware256Component::new()
344 .finalize(components::sha_software_256_component_static!());
345
346 let verifying_key0 = kernel::static_init!(
373 [u8; SIGNATURE_KEY_LEN],
374 [
375 0xe0, 0x13, 0x3a, 0x90, 0xa7, 0x4a, 0x35, 0x61, 0x51, 0x8e, 0xe1, 0x44, 0x09, 0xf1,
376 0x69, 0xc1, 0xcf, 0x6a, 0xdb, 0x7f, 0x7e, 0x52, 0xf8, 0xb7, 0x41, 0x79, 0xe2, 0x4d,
377 0x57, 0x41, 0x23, 0x52, 0x2e, 0xb6, 0x12, 0x03, 0xb3, 0x85, 0x10, 0xe5, 0xf3, 0x25,
378 0x07, 0x62, 0x8f, 0x54, 0x95, 0x82, 0x57, 0x45, 0x50, 0xbd, 0xa3, 0xe2, 0x17, 0xe8,
379 0x34, 0x30, 0x89, 0x26, 0x4c, 0x23, 0x62, 0xb1
380 ]
381 );
382 let verifying_keys = kernel::static_init!(
383 [&'static mut [u8; SIGNATURE_KEY_LEN]; NUM_CREDENTIAL_KEYS],
384 [verifying_key0]
385 );
386 let ecdsa_p256_verifying_key =
388 kernel::static_init!([u8; SIGNATURE_KEY_LEN], [0; SIGNATURE_KEY_LEN]);
389 let ecdsa_p256_verifier = kernel::static_init!(
390 ecdsa_sw::p256_verifier::EcdsaP256SignatureVerifier<'static>,
391 ecdsa_sw::p256_verifier::EcdsaP256SignatureVerifier::new(ecdsa_p256_verifying_key)
392 );
393 ecdsa_p256_verifier.register();
394
395 let verifier_multiple_keys =
397 components::signature_verify_in_memory_keys::SignatureVerifyInMemoryKeysComponent::new(
398 ecdsa_p256_verifier,
399 verifying_keys,
400 )
401 .finalize(
402 components::signature_verify_in_memory_keys_component_static!(
403 Verifier,
404 NUM_CREDENTIAL_KEYS,
405 SIGNATURE_KEY_LEN,
406 SIGNATURE_HASH_LEN,
407 SIGNATURE_SIG_LEN,
408 ),
409 );
410
411 let checking_policy_signature =
413 components::appid::checker_signature::AppCheckerSignatureComponent::new(
414 sha,
415 verifier_multiple_keys,
416 tock_tbf::types::TbfFooterV2CredentialsType::EcdsaNistP256,
417 )
418 .finalize(components::app_checker_signature_component_static!(
419 SignatureVerifyInMemoryKeys,
420 capsules_extra::sha256::Sha256Software<'static>,
421 SIGNATURE_HASH_LEN,
422 SIGNATURE_SIG_LEN,
423 ));
424
425 let checking_policy = static_init!(
430 checker_credentials_not_required::AppCheckerCredentialsNotRequired<
431 SignatureChecker,
432 >,
433 checker_credentials_not_required::AppCheckerCredentialsNotRequired::new(
434 checking_policy_signature
435 ),
436 );
437
438 let assigner = static_init!(
440 app_id_assigner_name_metadata::AppIdAssignerNameMetadata,
441 app_id_assigner_name_metadata::AppIdAssignerNameMetadata::new()
442 );
443
444 let checker = components::appid::checker::ProcessCheckerMachineComponent::new(checking_policy)
446 .finalize(components::process_checker_machine_component_static!());
447
448 let storage_permissions_policy =
453 components::storage_permissions::null::StoragePermissionsNullComponent::new().finalize(
454 components::storage_permissions_null_component_static!(
455 nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
456 kernel::process::ProcessStandardDebugFull,
457 ),
458 );
459
460 extern "C" {
466 static _sapps: u8;
468 static _eapps: u8;
470 static mut _sappmem: u8;
472 static _eappmem: u8;
474 }
475
476 let app_flash = core::slice::from_raw_parts(
477 core::ptr::addr_of!(_sapps),
478 core::ptr::addr_of!(_eapps) as usize - core::ptr::addr_of!(_sapps) as usize,
479 );
480 let app_memory = core::slice::from_raw_parts_mut(
481 core::ptr::addr_of_mut!(_sappmem),
482 core::ptr::addr_of!(_eappmem) as usize - core::ptr::addr_of!(_sappmem) as usize,
483 );
484
485 let loader = components::loader::sequential::ProcessLoaderSequentialComponent::new(
487 checker,
488 board_kernel,
489 chip,
490 &FAULT_RESPONSE,
491 assigner,
492 storage_permissions_policy,
493 app_flash,
494 app_memory,
495 )
496 .finalize(components::process_loader_sequential_component_static!(
497 nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
498 kernel::process::ProcessStandardDebugFull,
499 NUM_PROCS
500 ));
501
502 let dynamic_binary_storage =
508 components::dynamic_binary_storage::SequentialBinaryStorageComponent::new(
509 virtual_flash_dbs,
510 loader,
511 )
512 .finalize(components::sequential_binary_storage_component_static!(
513 FlashUser,
514 nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
515 kernel::process::ProcessStandardDebugFull,
516 ));
517
518 let dynamic_app_loader = components::app_loader::AppLoaderComponent::new(
520 board_kernel,
521 capsules_extra::app_loader::DRIVER_NUM,
522 dynamic_binary_storage,
523 dynamic_binary_storage,
524 )
525 .finalize(components::app_loader_component_static!(
526 DynamicBinaryStorage<'static>,
527 DynamicBinaryStorage<'static>,
528 ));
529
530 let platform = static_init!(
535 Platform,
536 Platform {
537 board_kernel,
538 syscall_filter,
539 base: base_platform,
540 screen,
541 process_info,
542 nonvolatile_storage,
543 dynamic_app_loader,
544 }
545 );
546 loader.set_client(platform);
547
548 board_kernel.kernel_loop(
549 platform,
550 chip,
551 Some(&platform.base.ipc),
552 &main_loop_capability,
553 );
554}