1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
//! Core Tock Kernel
//!
//! The kernel crate implements the core features of Tock as well as shared
//! code that many chips, capsules, and boards use. It also holds the Hardware
//! Interface Layer (HIL) definitions.
//!
//! Most `unsafe` code is in this kernel crate.
//!
//!
//! ## Core Kernel Visibility
//!
//! As the root crate in the Tock operating system, this crate serves multiple
//! purposes:
//!
//! 1. It includes the logic for the core kernel, including process management,
//!    grants, scheduling, etc.
//!
//! 2. It includes important interfaces for hardware and other device
//!    abstractions. These are generally in the HIL and platform folders.
//!
//! 3. It includes utility functions used elsewhere in the kernel, generally by
//!    multiple different crates such that it makes sense to have shared
//!    implementations in the core kernel crate.
//!
//! Because of these different features of the core kernel, managing visibility
//! of the various objects and functions is a bit tricky. In general, the kernel
//! crate only exposes what it absolutely needs to. However, there are three
//! cases where resources in this crate _must_ be exposed.
//!
//! 1. The shared utility functions and structs must be exposed. These are
//!    marked `pub` and are used by many other kernel crates.
//!
//!    Some utility objects and abstractions, however, expose memory unsafe
//!    behavior. These are marked as `unsafe`, and require an `unsafe` block to
//!    use them. One example of this is `StaticRef` which is used for accessing
//!    memory-mapped I/O registers. Since accessing the addresses through just a
//!    memory address is potentially very unsafe, instantiating a `StaticRef`
//!    requires an `unsafe` block.
//!
//! 2. The core kernel types generally have to be exposed as other layers of the
//!    OS need to use them. However, generally only a very small interface is
//!    exposed, and using that interface cannot compromise the overall system or
//!    the core kernel. These functions are also marked `pub`. For example, the
//!    `ProcessBuffer` abstraction must be exposed to capsules to use shared memory
//!    between a process and the kernel. However, the constructor is not public,
//!    and the API exposed to capsules is very limited and confined by the Rust
//!    type system. The constructor and other sensitive interfaces are
//!    restricted to use only inside the kernel crate and are marked
//!    `pub(crate)`.
//!
//!    In some cases, more sensitive core kernel interfaces must be exposed. For
//!    example, the kernel exposes a function for starting the main scheduling
//!    loop in the kernel. Since board crates must be able to start this loop
//!    after all initialization is finished, the kernel loop function must be
//!    exposed and marked `pub`. However, this interface is not generally safe
//!    to use, since starting the loop a second time would compromise the
//!    stability of the overall system. It's also not necessarily memory unsafe
//!    to call the start loop function again, so we do not mark it as `unsafe`.
//!    Instead, we require that the caller hold a `Capability` to call the
//!    public but sensitive functions. More information is in `capabilities.rs`.
//!    This allows the kernel crate to still expose functions as public while
//!    restricting their use. Another example of this is the `Grant`
//!    constructor, which must be called outside of the core kernel, but should
//!    not be called except during the board setup.
//!
//! 3. Certain internal core kernel interfaces must also be exposed. These are
//!    needed for extensions of the core kernel that happen to be implemented in
//!    crates outside of the kernel crate. For example, additional
//!    implementations of `Process` may live outside of the kernel crate. To
//!    successfully implement a new `Process` requires access to certain
//!    in-core-kernel APIs, and these must be marked `pub` so that outside
//!    crates can access them.
//!
//!    These interfaces are highly sensitive, so again we require the caller
//!    hold a Capability to call them. This helps restrict their use and makes
//!    it very clear that calling them requires special permissions.
//!    Additionally, to differentiate these interfaces, which are for external
//!    extensions of core kernel functionality, from the other public but
//!    sensitive interfaces (item 2 above), we append the name `_external` to
//!    the function name.
//!
//!    One note is that there are currently very few extensions to the core
//!    kernel that live outside of the kernel crate. That means we have not
//!    necessarily created `_extern` functions for all the interfaces needed for
//!    this use case. It is likely we will have to create new interfaces as new
//!    use cases are discovered.

#![feature(core_intrinsics, const_fn_trait_bound)]
#![warn(unreachable_pub)]
#![no_std]

// Define the kernel major and minor versions
pub const MAJOR: u16 = 2;
pub const MINOR: u16 = 0;

pub mod capabilities;
pub mod collections;
pub mod component;
pub mod debug;
pub mod deferred_call;
pub mod dynamic_deferred_call;
pub mod errorcode;
pub mod grant;
pub mod hil;
pub mod introspection;
pub mod ipc;
pub mod platform;
pub mod process;
pub mod processbuffer;
pub mod scheduler;
pub mod syscall;
pub mod upcall;
pub mod utilities;

mod config;
mod kernel;
mod memop;
mod process_policies;
mod process_standard;
mod process_utilities;
mod syscall_driver;

// Core resources exposed as `kernel::Type`.
pub use crate::errorcode::ErrorCode;
pub use crate::kernel::Kernel;
pub use crate::process::ProcessId;
pub use crate::scheduler::Scheduler;