Crate kernel

Source
Expand description

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.

Re-exports§

pub use crate::errorcode::ErrorCode;
pub use crate::process::ProcessId;
pub use crate::scheduler::Scheduler;

Modules§

capabilities
Special restricted capabilities.
collections
Data structures.
component
Components extend the functionality of the Tock kernel through a simple factory method interface.
debug
Support for in-kernel debugging.
deferred_call
Hardware-independent kernel interface for deferred calls.
errorcode
Standard errors in Tock.
grant
Support for processes granting memory from their allocations to the kernel.
hil
Public traits for interfaces between Tock components.
introspection
Mechanism for inspecting the status of the kernel.
ipc
Inter-process communication mechanism for Tock.
platform
Traits for implementing various layers and components in Tock.
process
Types for Tock-compatible processes.
process_checker
Traits and types for application credentials checkers, used to decide whether an application can be loaded.
processbuffer
Data structures for passing application memory to the kernel.
scheduler
Interface for Tock kernel schedulers.
storage_permissions
Mechanism for managing storage read & write permissions.
syscall
Mechanisms for handling and defining system calls.
upcall
Data structure for storing an upcall from the kernel to a process.
utilities
Utility functions and macros provided by the kernel crate.

Macros§

count_expressions
Count the number of passed expressions.
create_capability
Create an object with the given capability.
debug
In-kernel println() debugging.
debug_expr
Prints out the expression and its location, then returns it.
debug_gpio
In-kernel gpio debugging that accepts any GPIO HIL method.
debug_process_slice
In-kernel println() debugging that can take a process slice.
debug_verbose
In-kernel println() debugging with filename and line numbers.
static_buf
Allocates an uninitialized statically-sized global region of memory for a data structure.
static_init
Allocates a statically-sized global array of memory and initializes the memory for a particular data structure.
static_named_buf
A version of static_buf!() that adds an exported name to the buffer.
storage_volume
Allocates space in the kernel image for on-chip non-volatile storage.

Structs§

Kernel
Main object for the kernel. Each board will need to create one.

Constants§

KERNEL_MAJOR_VERSION
Kernel major version.
KERNEL_MINOR_VERSION
Kernel minor version.