|
| 1 | +# Before we start |
| 2 | + |
| 3 | +The following text is a 1:1 copy of the documentation that can be found at the top of the kernel's |
| 4 | +main source code file in each tutorial. It describes the general structure of the source code, and |
| 5 | +tries to convey the philosophy behind the respective approach. Please read it to make yourself |
| 6 | +familiar with what you will encounter during the tutorials. It will help you to navigate the code |
| 7 | +better and understand the differences and additions beteween the separate tutorials. |
| 8 | + |
| 9 | +Please also note that the following text will reference source code files (e.g. `**/memory.rs`) or |
| 10 | +functions that won't exist yet in the first bunch of the tutorials. They will be added gradually as |
| 11 | +the tutorials advance. |
| 12 | + |
| 13 | +Have fun! |
| 14 | + |
| 15 | +## Code organization and architecture |
| 16 | + |
| 17 | +The code is divided into different *modules*, each representing a typical **subsystem** of the |
| 18 | +`kernel`. Top-level module files of subsystems reside directly in the `src` folder. For example, |
| 19 | +`src/memory.rs` contains code that is concerned with all things memory management. |
| 20 | + |
| 21 | +## Visibility of processor architecture code |
| 22 | + |
| 23 | +Some of the `kernel`'s subsystems depend on low-level code that is specific to the target processor |
| 24 | +architecture. For each supported processor architecture, there exists a subfolder in `src/_arch`, |
| 25 | +for example, `src/_arch/aarch64`. |
| 26 | + |
| 27 | +The architecture folders mirror the subsystem modules laid out in `src`. For example, architectural |
| 28 | +code that belongs to the `kernel`'s memory subsystem (`src/memory.rs`) would go into |
| 29 | +`src/_arch/aarch64/memory.rs`. The latter file is directly included and re-exported in |
| 30 | +`src/memory.rs`, so that the architectural code parts are transparent with respect to the code's |
| 31 | +module organization. That means a public function `foo()` defined in `src/_arch/aarch64/memory.rs` |
| 32 | +would be reachable as `crate::memory::foo()` only. |
| 33 | + |
| 34 | +The `_` in `_arch` denotes that this folder is not part of the standard module hierarchy. Rather, |
| 35 | +it's contents are conditionally pulled into respective files using the `#[path = |
| 36 | +"_arch/xxx/yyy.rs"]` attribute. |
| 37 | + |
| 38 | +## BSP code |
| 39 | + |
| 40 | +`BSP` stands for Board Support Package. `BSP` code is organized under `src/bsp.rs` and contains |
| 41 | +target board specific definitions and functions. These are things such as the board's memory map or |
| 42 | +instances of drivers for devices that are featured on the respective board. |
| 43 | + |
| 44 | +Just like processor architecture code, the `BSP` code's module structure tries to mirror the |
| 45 | +`kernel`'s subsystem modules, but there is no transparent re-exporting this time. That means |
| 46 | +whatever is provided must be called starting from the `bsp` namespace, e.g. |
| 47 | +`bsp::driver::driver_manager()`. |
| 48 | + |
| 49 | +## Kernel interfaces |
| 50 | + |
| 51 | +Both `arch` and `bsp` contain code that is conditionally compiled depending on the actual target and |
| 52 | +board for which the kernel is compiled. For example, the `interrupt controller` hardware of the |
| 53 | +`Raspberry Pi 3` and the `Raspberry Pi 4` is different, but we want the rest of the `kernel` code to |
| 54 | +play nicely with any of the two without much hassle. |
| 55 | + |
| 56 | +In order to provide a clean abstraction between `arch`, `bsp` and `generic kernel code`, `interface` |
| 57 | +traits are provided *whenever possible* and *where it makes sense*. They are defined in the |
| 58 | +respective subsystem module and help to enforce the idiom of *program to an interface, not an |
| 59 | +implementation*. For example, there will be a common IRQ handling interface which the two different |
| 60 | +interrupt controller `drivers` of both Raspberrys will implement, and only export the interface to |
| 61 | +the rest of the `kernel`. |
| 62 | + |
| 63 | +``` |
| 64 | + +-------------------+ |
| 65 | + | Interface (Trait) | |
| 66 | + | | |
| 67 | + +--+-------------+--+ |
| 68 | + ^ ^ |
| 69 | + | | |
| 70 | + | | |
| 71 | ++----------+--+ +--+----------+ |
| 72 | +| kernel code | | bsp code | |
| 73 | +| | | arch code | |
| 74 | ++-------------+ +-------------+ |
| 75 | +``` |
| 76 | + |
| 77 | +# Summary |
| 78 | + |
| 79 | +For a logical `kernel` subsystem, corresponding code can be distributed over several physical |
| 80 | +locations. Here is an example for the **memory** subsystem: |
| 81 | + |
| 82 | +- `src/memory.rs` and `src/memory/**/*` |
| 83 | + - Common code that is agnostic of target processor architecture and `BSP` characteristics. |
| 84 | + - Example: A function to zero a chunk of memory. |
| 85 | + - Interfaces for the memory subsystem that are implemented by `arch` or `BSP` code. |
| 86 | + - Example: An `MMU` interface that defines `MMU` function prototypes. |
| 87 | +- `src/bsp/__board_name__/memory.rs` and `src/bsp/__board_name__/memory/**/*` |
| 88 | + - `BSP` specific code. |
| 89 | + - Example: The board's memory map (physical addresses of DRAM and MMIO devices). |
| 90 | +- `src/_arch/__arch_name__/memory.rs` and `src/_arch/__arch_name__/memory/**/*` |
| 91 | + - Processor architecture specific code. |
| 92 | + - Example: Implementation of the `MMU` interface for the `__arch_name__` processor |
| 93 | + architecture. |
| 94 | + |
| 95 | +From a namespace perspective, **memory** subsystem code lives in: |
| 96 | + |
| 97 | +- `crate::memory::*` |
| 98 | +- `crate::bsp::memory::*` |
0 commit comments