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 Chip = nrf52840dk_lib::Chip;
32static mut CHIP: Option<&'static Chip> = None;
33
34const FAULT_RESPONSE: capsules_system::process_policies::StopWithDebugFaultPolicy =
36 capsules_system::process_policies::StopWithDebugFaultPolicy {};
37
38const NUM_CREDENTIAL_KEYS: usize = 1;
40const SIGNATURE_KEY_LEN: usize = 64;
42const SIGNATURE_HASH_LEN: usize = 32;
44const SIGNATURE_SIG_LEN: usize = 64;
46
47pub struct PMCapability;
53unsafe impl capabilities::ProcessManagementCapability for PMCapability {}
54unsafe impl capabilities::ProcessStartCapability for PMCapability {}
55
56#[cfg(feature = "screen_ssd1306")]
57type Screen = components::ssd1306::Ssd1306ComponentType<nrf52840::i2c::TWI<'static>>;
58#[cfg(feature = "screen_sh1106")]
59type Screen = components::sh1106::Sh1106ComponentType<nrf52840::i2c::TWI<'static>>;
60type ScreenDriver = components::screen::ScreenSharedComponentType<Screen>;
61
62type ProcessInfoDriver = capsules_extra::process_info_driver::ProcessInfo<PMCapability>;
63
64type IsolatedNonvolatileStorageDriver =
65 capsules_extra::isolated_nonvolatile_storage_driver::IsolatedNonvolatileStorage<
66 'static,
67 {
68 components::isolated_nonvolatile_storage::ISOLATED_NONVOLATILE_STORAGE_APP_REGION_SIZE_DEFAULT
69 },
70 >;
71
72type FlashUser =
73 capsules_core::virtualizers::virtual_flash::FlashUser<'static, nrf52840::nvmc::Nvmc>;
74type NonVolatilePages = components::dynamic_binary_storage::NVPages<FlashUser>;
75
76type DynamicBinaryStorage<'a> = kernel::dynamic_binary_storage::SequentialDynamicBinaryStorage<
77 'static,
78 'static,
79 nrf52840::chip::NRF52<'a, Nrf52840DefaultPeripherals<'a>>,
80 kernel::process::ProcessStandardDebugFull,
81 NonVolatilePages,
82>;
83type AppLoaderDriver = capsules_extra::app_loader::AppLoader<
84 DynamicBinaryStorage<'static>,
85 DynamicBinaryStorage<'static>,
86>;
87
88type Verifier = ecdsa_sw::p256_verifier::EcdsaP256SignatureVerifier<'static>;
89type SignatureVerifyInMemoryKeys =
90 components::signature_verify_in_memory_keys::SignatureVerifyInMemoryKeysComponentType<
91 Verifier,
92 NUM_CREDENTIAL_KEYS,
93 SIGNATURE_KEY_LEN,
94 SIGNATURE_HASH_LEN,
95 SIGNATURE_SIG_LEN,
96 >;
97type SignatureChecker = components::appid::checker_signature::AppCheckerSignatureComponentType<
98 SignatureVerifyInMemoryKeys,
99 capsules_extra::sha256::Sha256Software<'static>,
100 SIGNATURE_HASH_LEN,
101 SIGNATURE_SIG_LEN,
102>;
103
104fn create_short_id_from_name(name: &str, metadata: u8) -> ShortId {
109 let sum = kernel::utilities::helpers::crc32_posix(name.as_bytes());
110
111 let sid = ((metadata as u32) << 28) | (sum & 0xFFFFFFF);
113
114 core::num::NonZeroU32::new(sid).into()
115}
116
117struct Platform {
122 board_kernel: &'static kernel::Kernel,
123 syscall_filter: &'static system_call_filter::DynamicPoliciesCustomFilter,
124 base: nrf52840dk_lib::Platform,
125 screen: &'static ScreenDriver,
126 process_info: &'static ProcessInfoDriver,
127 nonvolatile_storage: &'static IsolatedNonvolatileStorageDriver,
128 dynamic_app_loader: &'static AppLoaderDriver,
129}
130
131impl SyscallDriverLookup for Platform {
133 fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
134 where
135 F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
136 {
137 match driver_num {
138 capsules_extra::screen::DRIVER_NUM => f(Some(self.screen)),
139 capsules_extra::process_info_driver::DRIVER_NUM => f(Some(self.process_info)),
140 capsules_extra::isolated_nonvolatile_storage_driver::DRIVER_NUM => {
141 f(Some(self.nonvolatile_storage))
142 }
143 capsules_extra::app_loader::DRIVER_NUM => f(Some(self.dynamic_app_loader)),
144 _ => self.base.with_driver(driver_num, f),
145 }
146 }
147}
148
149impl KernelResources<Chip> for Platform {
151 type SyscallDriverLookup = Self;
152 type SyscallFilter = system_call_filter::DynamicPoliciesCustomFilter;
153 type ProcessFault = <nrf52840dk_lib::Platform as KernelResources<Chip>>::ProcessFault;
154 type Scheduler = <nrf52840dk_lib::Platform as KernelResources<Chip>>::Scheduler;
155 type SchedulerTimer = <nrf52840dk_lib::Platform as KernelResources<Chip>>::SchedulerTimer;
156 type WatchDog = <nrf52840dk_lib::Platform as KernelResources<Chip>>::WatchDog;
157 type ContextSwitchCallback =
158 <nrf52840dk_lib::Platform as KernelResources<Chip>>::ContextSwitchCallback;
159
160 fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup {
161 self
162 }
163 fn syscall_filter(&self) -> &Self::SyscallFilter {
164 self.syscall_filter
165 }
166 fn process_fault(&self) -> &Self::ProcessFault {
167 self.base.process_fault()
168 }
169 fn scheduler(&self) -> &Self::Scheduler {
170 self.base.scheduler()
171 }
172 fn scheduler_timer(&self) -> &Self::SchedulerTimer {
173 self.base.scheduler_timer()
174 }
175 fn watchdog(&self) -> &Self::WatchDog {
176 self.base.watchdog()
177 }
178 fn context_switch_callback(&self) -> &Self::ContextSwitchCallback {
179 self.base.context_switch_callback()
180 }
181}
182
183impl kernel::process::ProcessLoadingAsyncClient for Platform {
185 fn process_loaded(&self, _result: Result<(), kernel::process::ProcessLoadError>) {}
186
187 fn process_loading_finished(&self) {
188 kernel::debug!("Processes Loaded at Main:");
189
190 for (i, p) in self
191 .board_kernel
192 .process_iter_capability(&create_capability!(
193 capabilities::ProcessManagementCapability
194 ))
195 .enumerate()
196 {
197 kernel::debug!("[{}] {}", i, p.get_process_name());
198 kernel::debug!(" ShortId: {}", p.short_app_id());
199 }
200 }
201}
202
203#[no_mangle]
209pub unsafe fn main() {
210 let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
211
212 let (board_kernel, base_platform, chip, nrf52840_peripherals, _mux_alarm) =
214 nrf52840dk_lib::start();
215
216 CHIP = Some(chip);
217
218 let i2c_bus = components::i2c::I2CMuxComponent::new(&nrf52840_peripherals.nrf52.twi1, None)
223 .finalize(components::i2c_mux_component_static!(nrf52840::i2c::TWI));
224 nrf52840_peripherals.nrf52.twi1.configure(
225 nrf52840::pinmux::Pinmux::new(SCREEN_I2C_SCL_PIN as u32),
226 nrf52840::pinmux::Pinmux::new(SCREEN_I2C_SDA_PIN as u32),
227 );
228 nrf52840_peripherals
229 .nrf52
230 .twi1
231 .set_speed(nrf52840::i2c::Speed::K400);
232
233 let ssd1306_sh1106_i2c = components::i2c::I2CComponent::new(i2c_bus, 0x3c)
235 .finalize(components::i2c_component_static!(nrf52840::i2c::TWI));
236
237 #[cfg(feature = "screen_ssd1306")]
239 let ssd1306_sh1106 = components::ssd1306::Ssd1306Component::new(ssd1306_sh1106_i2c, true)
240 .finalize(components::ssd1306_component_static!(nrf52840::i2c::TWI));
241
242 #[cfg(feature = "screen_sh1106")]
243 let ssd1306_sh1106 = components::sh1106::Sh1106Component::new(ssd1306_sh1106_i2c, true)
244 .finalize(components::sh1106_component_static!(nrf52840::i2c::TWI));
245
246 let apps_regions = kernel::static_init!(
247 [capsules_extra::screen_shared::AppScreenRegion; 3],
248 [
249 capsules_extra::screen_shared::AppScreenRegion::new(
250 create_short_id_from_name("process_manager", 0x0),
251 0, 0, 16 * 8, 7 * 8 ),
256 capsules_extra::screen_shared::AppScreenRegion::new(
257 create_short_id_from_name("counter", 0x0),
258 0, 7 * 8, 8 * 8, 1 * 8 ),
263 capsules_extra::screen_shared::AppScreenRegion::new(
264 create_short_id_from_name("temperature", 0x0),
265 8 * 8, 7 * 8, 8 * 8, 1 * 8 )
270 ]
271 );
272
273 let screen = components::screen::ScreenSharedComponent::new(
274 board_kernel,
275 capsules_extra::screen::DRIVER_NUM,
276 ssd1306_sh1106,
277 apps_regions,
278 )
279 .finalize(components::screen_shared_component_static!(1032, Screen));
280
281 ssd1306_sh1106.init_screen();
282
283 let mux_flash = components::flash::FlashMuxComponent::new(&nrf52840_peripherals.nrf52.nvmc)
288 .finalize(components::flash_mux_component_static!(
289 nrf52840::nvmc::Nvmc
290 ));
291
292 let virtual_flash_dbs = components::flash::FlashUserComponent::new(mux_flash).finalize(
294 components::flash_user_component_static!(nrf52840::nvmc::Nvmc),
295 );
296
297 let virtual_flash_nvm = components::flash::FlashUserComponent::new(mux_flash).finalize(
299 components::flash_user_component_static!(nrf52840::nvmc::Nvmc),
300 );
301
302 kernel::storage_volume!(APP_STORAGE, 32);
308
309 let nonvolatile_storage = components::isolated_nonvolatile_storage::IsolatedNonvolatileStorageComponent::new(
310 board_kernel,
311 capsules_extra::isolated_nonvolatile_storage_driver::DRIVER_NUM,
312 virtual_flash_nvm,
313 core::ptr::addr_of!(APP_STORAGE) as usize,
314 APP_STORAGE.len()
315 )
316 .finalize(components::isolated_nonvolatile_storage_component_static!(
317 capsules_core::virtualizers::virtual_flash::FlashUser<'static, nrf52840::nvmc::Nvmc>,
318 { components::isolated_nonvolatile_storage::ISOLATED_NONVOLATILE_STORAGE_APP_REGION_SIZE_DEFAULT }
319 ));
320
321 let process_info = components::process_info_driver::ProcessInfoComponent::new(
326 board_kernel,
327 capsules_extra::process_info_driver::DRIVER_NUM,
328 PMCapability,
329 )
330 .finalize(components::process_info_component_static!(PMCapability));
331
332 let syscall_filter = static_init!(
337 system_call_filter::DynamicPoliciesCustomFilter,
338 system_call_filter::DynamicPoliciesCustomFilter {}
339 );
340
341 let sha = components::sha::ShaSoftware256Component::new()
347 .finalize(components::sha_software_256_component_static!());
348
349 let verifying_key0 = kernel::static_init!(
376 [u8; SIGNATURE_KEY_LEN],
377 [
378 0xe0, 0x13, 0x3a, 0x90, 0xa7, 0x4a, 0x35, 0x61, 0x51, 0x8e, 0xe1, 0x44, 0x09, 0xf1,
379 0x69, 0xc1, 0xcf, 0x6a, 0xdb, 0x7f, 0x7e, 0x52, 0xf8, 0xb7, 0x41, 0x79, 0xe2, 0x4d,
380 0x57, 0x41, 0x23, 0x52, 0x2e, 0xb6, 0x12, 0x03, 0xb3, 0x85, 0x10, 0xe5, 0xf3, 0x25,
381 0x07, 0x62, 0x8f, 0x54, 0x95, 0x82, 0x57, 0x45, 0x50, 0xbd, 0xa3, 0xe2, 0x17, 0xe8,
382 0x34, 0x30, 0x89, 0x26, 0x4c, 0x23, 0x62, 0xb1
383 ]
384 );
385 let verifying_keys = kernel::static_init!(
386 [&'static mut [u8; SIGNATURE_KEY_LEN]; NUM_CREDENTIAL_KEYS],
387 [verifying_key0]
388 );
389 let ecdsa_p256_verifying_key =
391 kernel::static_init!([u8; SIGNATURE_KEY_LEN], [0; SIGNATURE_KEY_LEN]);
392 let ecdsa_p256_verifier = kernel::static_init!(
393 ecdsa_sw::p256_verifier::EcdsaP256SignatureVerifier<'static>,
394 ecdsa_sw::p256_verifier::EcdsaP256SignatureVerifier::new(ecdsa_p256_verifying_key)
395 );
396 ecdsa_p256_verifier.register();
397
398 let verifier_multiple_keys =
400 components::signature_verify_in_memory_keys::SignatureVerifyInMemoryKeysComponent::new(
401 ecdsa_p256_verifier,
402 verifying_keys,
403 )
404 .finalize(
405 components::signature_verify_in_memory_keys_component_static!(
406 Verifier,
407 NUM_CREDENTIAL_KEYS,
408 SIGNATURE_KEY_LEN,
409 SIGNATURE_HASH_LEN,
410 SIGNATURE_SIG_LEN,
411 ),
412 );
413
414 let checking_policy_signature =
416 components::appid::checker_signature::AppCheckerSignatureComponent::new(
417 sha,
418 verifier_multiple_keys,
419 tock_tbf::types::TbfFooterV2CredentialsType::EcdsaNistP256,
420 )
421 .finalize(components::app_checker_signature_component_static!(
422 SignatureVerifyInMemoryKeys,
423 capsules_extra::sha256::Sha256Software<'static>,
424 SIGNATURE_HASH_LEN,
425 SIGNATURE_SIG_LEN,
426 ));
427
428 let checking_policy = static_init!(
433 checker_credentials_not_required::AppCheckerCredentialsNotRequired<
434 SignatureChecker,
435 >,
436 checker_credentials_not_required::AppCheckerCredentialsNotRequired::new(
437 checking_policy_signature
438 ),
439 );
440
441 let assigner = static_init!(
443 app_id_assigner_name_metadata::AppIdAssignerNameMetadata,
444 app_id_assigner_name_metadata::AppIdAssignerNameMetadata::new()
445 );
446
447 let checker = components::appid::checker::ProcessCheckerMachineComponent::new(checking_policy)
449 .finalize(components::process_checker_machine_component_static!());
450
451 let storage_permissions_policy =
456 components::storage_permissions::null::StoragePermissionsNullComponent::new().finalize(
457 components::storage_permissions_null_component_static!(
458 nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
459 kernel::process::ProcessStandardDebugFull,
460 ),
461 );
462
463 extern "C" {
469 static _sapps: u8;
471 static _eapps: u8;
473 static mut _sappmem: u8;
475 static _eappmem: u8;
477 }
478
479 let app_flash = core::slice::from_raw_parts(
480 core::ptr::addr_of!(_sapps),
481 core::ptr::addr_of!(_eapps) as usize - core::ptr::addr_of!(_sapps) as usize,
482 );
483 let app_memory = core::slice::from_raw_parts_mut(
484 core::ptr::addr_of_mut!(_sappmem),
485 core::ptr::addr_of!(_eappmem) as usize - core::ptr::addr_of!(_sappmem) as usize,
486 );
487
488 let loader = components::loader::sequential::ProcessLoaderSequentialComponent::new(
490 checker,
491 board_kernel,
492 chip,
493 &FAULT_RESPONSE,
494 assigner,
495 storage_permissions_policy,
496 app_flash,
497 app_memory,
498 )
499 .finalize(components::process_loader_sequential_component_static!(
500 nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
501 kernel::process::ProcessStandardDebugFull,
502 NUM_PROCS
503 ));
504
505 let dynamic_binary_storage =
511 components::dynamic_binary_storage::SequentialBinaryStorageComponent::new(
512 virtual_flash_dbs,
513 loader,
514 )
515 .finalize(components::sequential_binary_storage_component_static!(
516 FlashUser,
517 nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
518 kernel::process::ProcessStandardDebugFull,
519 ));
520
521 let dynamic_app_loader = components::app_loader::AppLoaderComponent::new(
523 board_kernel,
524 capsules_extra::app_loader::DRIVER_NUM,
525 dynamic_binary_storage,
526 dynamic_binary_storage,
527 )
528 .finalize(components::app_loader_component_static!(
529 DynamicBinaryStorage<'static>,
530 DynamicBinaryStorage<'static>,
531 ));
532
533 let platform = static_init!(
538 Platform,
539 Platform {
540 board_kernel,
541 syscall_filter,
542 base: base_platform,
543 screen,
544 process_info,
545 nonvolatile_storage,
546 dynamic_app_loader,
547 }
548 );
549 loader.set_client(platform);
550
551 board_kernel.kernel_loop(
552 platform,
553 chip,
554 Some(&platform.base.ipc),
555 &main_loop_capability,
556 );
557}