diff --git a/00_before_we_start/README.md b/00_before_we_start/README.md new file mode 100644 index 00000000..0ee75bdd --- /dev/null +++ b/00_before_we_start/README.md @@ -0,0 +1,98 @@ +# Before we start + +The following text is a 1:1 copy of the documentation that can be found at the top of the kernel's +main source code file in each tutorial. It describes the general structure of the source code, and +tries to convey the philosophy behind the respective approach. Please read it to make yourself +familiar with what you will encounter during the tutorials. It will help you to navigate the code +better and understand the differences and additions beteween the separate tutorials. + +Please also note that the following text will reference source code files (e.g. `**/memory.rs`) or +functions that won't exist yet in the first bunch of the tutorials. They will be added gradually as +the tutorials advance. + +Have fun! + +## Code organization and architecture + +The code is divided into different *modules*, each representing a typical **subsystem** of the +`kernel`. Top-level module files of subsystems reside directly in the `src` folder. For example, +`src/memory.rs` contains code that is concerned with all things memory management. + +## Visibility of processor architecture code + +Some of the `kernel`'s subsystems depend on low-level code that is specific to the target processor +architecture. For each supported processor architecture, there exists a subfolder in `src/_arch`, +for example, `src/_arch/aarch64`. + +The architecture folders mirror the subsystem modules laid out in `src`. For example, architectural +code that belongs to the `kernel`'s memory subsystem (`src/memory.rs`) would go into +`src/_arch/aarch64/memory.rs`. The latter file is directly included and re-exported in +`src/memory.rs`, so that the architectural code parts are transparent with respect to the code's +module organization. That means a public function `foo()` defined in `src/_arch/aarch64/memory.rs` +would be reachable as `crate::memory::foo()` only. + +The `_` in `_arch` denotes that this folder is not part of the standard module hierarchy. Rather, +it's contents are conditionally pulled into respective files using the `#[path = +"_arch/xxx/yyy.rs"]` attribute. + +## BSP code + +`BSP` stands for Board Support Package. `BSP` code is organized under `src/bsp.rs` and contains +target board specific definitions and functions. These are things such as the board's memory map or +instances of drivers for devices that are featured on the respective board. + +Just like processor architecture code, the `BSP` code's module structure tries to mirror the +`kernel`'s subsystem modules, but there is no transparent re-exporting this time. That means +whatever is provided must be called starting from the `bsp` namespace, e.g. +`bsp::driver::driver_manager()`. + +## Kernel interfaces + +Both `arch` and `bsp` contain code that is conditionally compiled depending on the actual target and +board for which the kernel is compiled. For example, the `interrupt controller` hardware of the +`Raspberry Pi 3` and the `Raspberry Pi 4` is different, but we want the rest of the `kernel` code to +play nicely with any of the two without much hassle. + +In order to provide a clean abstraction between `arch`, `bsp` and `generic kernel code`, `interface` +traits are provided *whenever possible* and *where it makes sense*. They are defined in the +respective subsystem module and help to enforce the idiom of *program to an interface, not an +implementation*. For example, there will be a common IRQ handling interface which the two different +interrupt controller `drivers` of both Raspberrys will implement, and only export the interface to +the rest of the `kernel`. + +``` + +-------------------+ + | Interface (Trait) | + | | + +--+-------------+--+ + ^ ^ + | | + | | ++----------+--+ +--+----------+ +| kernel code | | bsp code | +| | | arch code | ++-------------+ +-------------+ +``` + +# Summary + +For a logical `kernel` subsystem, corresponding code can be distributed over several physical +locations. Here is an example for the **memory** subsystem: + +- `src/memory.rs` and `src/memory/**/*` + - Common code that is agnostic of target processor architecture and `BSP` characteristics. + - Example: A function to zero a chunk of memory. + - Interfaces for the memory subsystem that are implemented by `arch` or `BSP` code. + - Example: An `MMU` interface that defines `MMU` function prototypes. +- `src/bsp/__board_name__/memory.rs` and `src/bsp/__board_name__/memory/**/*` + - `BSP` specific code. + - Example: The board's memory map (physical addresses of DRAM and MMIO devices). +- `src/_arch/__arch_name__/memory.rs` and `src/_arch/__arch_name__/memory/**/*` + - Processor architecture specific code. + - Example: Implementation of the `MMU` interface for the `__arch_name__` processor + architecture. + +From a namespace perspective, **memory** subsystem code lives in: + +- `crate::memory::*` +- `crate::bsp::memory::*`