Skip to content

Commit

Permalink
multiboot2-common: doc improvement with figures
Browse files Browse the repository at this point in the history
  • Loading branch information
phip1611 committed Aug 22, 2024
1 parent aadcf8b commit 82b93e7
Show file tree
Hide file tree
Showing 7 changed files with 386 additions and 8 deletions.
2 changes: 1 addition & 1 deletion .typos.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[files]
extend-exclude = [
# "uefi/src/table/boot.rs"
"*.drawio.xml"
]

[default.extend-words]
Expand Down
17 changes: 17 additions & 0 deletions multiboot2-common/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,23 @@

Common helpers for the `multiboot2` and `multiboot2-header` crates.

## Architecture

The following figures, not displayable in `lib.rs` / on `docs.rs` unfortunately,
outline the design of this crate:

![Overview Multiboot2 Structures](./overview-multiboot2-structures.drawio.png "Overview Multiboot2 Structures")

Overview of Multiboot2 structures: Multiboot2 boot information, boot
information tags, Multiboot2 headers, and Multiboot2 header tags all share the
same technical foundation: They have a common header and a possible dynamic
size, depending on the header.

![Crate Architecture Overview](./architecture.drawio.png "Crate Architecture Overview")

Overview of how raw bytes are modelled to be representable by high-level rusty
types.

## MSRV

The MSRV is 1.70.0 stable.
Expand Down
Binary file added multiboot2-common/architecture.drawio.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
217 changes: 217 additions & 0 deletions multiboot2-common/architecture.drawio.xml

Large diffs are not rendered by default.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
97 changes: 97 additions & 0 deletions multiboot2-common/overview-multiboot2-structures.drawio.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<mxfile host="app.diagrams.net" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36" version="24.7.7">
<diagram name="Seite-1" id="t28IrSg9-075dSeR9zn3">
<mxGraphModel dx="989" dy="487" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="Sv76AHv-8cPqDwbSuwtx-1" value="" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=top;" vertex="1" parent="1">
<mxGeometry x="80" y="40" width="140" height="380" as="geometry" />
</mxCell>
<mxCell id="Sv76AHv-8cPqDwbSuwtx-2" value="" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=top;" vertex="1" parent="1">
<mxGeometry x="240" y="40" width="140" height="380" as="geometry" />
</mxCell>
<mxCell id="Sv76AHv-8cPqDwbSuwtx-4" value="&lt;b&gt;&lt;font data-font-src=&quot;https://fonts.googleapis.com/css?family=Roboto&quot; face=&quot;Roboto&quot;&gt;CommandLineTag&lt;/font&gt;&lt;/b&gt;&lt;br&gt;&amp;nbsp;&lt;font color=&quot;#0000cc&quot;&gt;type: u32 = 1&lt;br&gt;&amp;nbsp;size: u32 = 11&lt;/font&gt;&lt;br&gt;&amp;nbsp;str: [u8] = [&lt;br&gt;&amp;nbsp; &#39;h&#39;&lt;br&gt;&amp;nbsp; &#39;i&#39;&lt;br&gt;&amp;nbsp; &#39;\0&#39;&lt;br&gt;&amp;nbsp;]" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=Source Code Pro;fontSource=https%3A%2F%2Ffonts.googleapis.com%2Fcss%3Ffamily%3DSource%2BCode%2BPro;align=left;" vertex="1" parent="1">
<mxGeometry x="90" y="110" width="120" height="130" as="geometry" />
</mxCell>
<mxCell id="Sv76AHv-8cPqDwbSuwtx-7" value="&lt;b&gt;&lt;font data-font-src=&quot;https://fonts.googleapis.com/css?family=Roboto&quot; face=&quot;Roboto&quot;&gt;Multiboot2&lt;br&gt;Boot Information&lt;/font&gt;&lt;/b&gt;" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=top;" vertex="1" parent="1">
<mxGeometry x="80" y="40" width="140" height="40" as="geometry" />
</mxCell>
<mxCell id="Sv76AHv-8cPqDwbSuwtx-8" value="&lt;b&gt;Multiboot2&lt;br&gt;Header&lt;/b&gt;" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=top;" vertex="1" parent="1">
<mxGeometry x="240" y="40" width="140" height="40" as="geometry" />
</mxCell>
<mxCell id="Sv76AHv-8cPqDwbSuwtx-10" value="size: u32" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=Source Code Pro;fontSource=https%3A%2F%2Ffonts.googleapis.com%2Fcss%3Ffamily%3DSource%2BCode%2BPro;" vertex="1" parent="1">
<mxGeometry x="80" y="80" width="140" height="20" as="geometry" />
</mxCell>
<mxCell id="Sv76AHv-8cPqDwbSuwtx-11" value="size: u32" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=Source Code Pro;fontSource=https%3A%2F%2Ffonts.googleapis.com%2Fcss%3Ffamily%3DSource%2BCode%2BPro;" vertex="1" parent="1">
<mxGeometry x="240" y="80" width="140" height="20" as="geometry" />
</mxCell>
<mxCell id="Sv76AHv-8cPqDwbSuwtx-12" value="&amp;nbsp; &amp;nbsp; &lt;b&gt;&lt;font data-font-src=&quot;https://fonts.googleapis.com/css?family=Roboto&quot; face=&quot;Roboto&quot;&gt;Tag X&lt;/font&gt;&lt;/b&gt;&lt;br&gt;&amp;nbsp;&lt;font color=&quot;#0000cc&quot;&gt;type: u32 = x&lt;br&gt;&lt;/font&gt;&lt;div&gt;&lt;font color=&quot;#0000cc&quot;&gt;&amp;nbsp;size: u32 = y&lt;/font&gt;&lt;div&gt;&amp;nbsp;a: u16 = z&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=Source Code Pro;fontSource=https%3A%2F%2Ffonts.googleapis.com%2Fcss%3Ffamily%3DSource%2BCode%2BPro;verticalAlign=top;align=left;" vertex="1" parent="1">
<mxGeometry x="90" y="250" width="120" height="70" as="geometry" />
</mxCell>
<mxCell id="Sv76AHv-8cPqDwbSuwtx-14" value="&lt;b&gt;&lt;font face=&quot;Roboto&quot;&gt;InformationReq&lt;/font&gt;&lt;/b&gt;&lt;br&gt;&amp;nbsp;&lt;font color=&quot;#007fff&quot;&gt;type: u16 = 1&lt;br&gt;&amp;nbsp;flags: u16 = 0&lt;br&gt;&amp;nbsp;size: u32 = 11&lt;/font&gt;&lt;br&gt;&amp;nbsp;reqs: [u32] = [&lt;br&gt;&amp;nbsp; 1&lt;br&gt;&amp;nbsp;];" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=Source Code Pro;fontSource=https%3A%2F%2Ffonts.googleapis.com%2Fcss%3Ffamily%3DSource%2BCode%2BPro;align=left;verticalAlign=top;" vertex="1" parent="1">
<mxGeometry x="250" y="110" width="120" height="110" as="geometry" />
</mxCell>
<mxCell id="Sv76AHv-8cPqDwbSuwtx-15" value="&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;b&gt;&lt;font data-font-src=&quot;https://fonts.googleapis.com/css?family=Roboto&quot; face=&quot;Roboto&quot;&gt;Tag Y&lt;/font&gt;&lt;/b&gt;&lt;br&gt;&amp;nbsp;&lt;font color=&quot;#007fff&quot;&gt;type: u16 = x&lt;br&gt;&amp;nbsp;flags: u16 = y&lt;br&gt;&amp;nbsp;size: u32 = z&lt;/font&gt;&lt;br&gt;&amp;nbsp;bar: u64 = x&lt;br&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=Source Code Pro;fontSource=https%3A%2F%2Ffonts.googleapis.com%2Fcss%3Ffamily%3DSource%2BCode%2BPro;verticalAlign=top;align=left;" vertex="1" parent="1">
<mxGeometry x="250" y="250" width="120" height="90" as="geometry" />
</mxCell>
<mxCell id="Sv76AHv-8cPqDwbSuwtx-16" value="&lt;div&gt;&lt;div&gt;&lt;div&gt;...&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=Source Code Pro;fontSource=https%3A%2F%2Ffonts.googleapis.com%2Fcss%3Ffamily%3DSource%2BCode%2BPro;verticalAlign=middle;align=center;" vertex="1" parent="1">
<mxGeometry x="90" y="390" width="120" height="20" as="geometry" />
</mxCell>
<mxCell id="Sv76AHv-8cPqDwbSuwtx-20" value="" style="endArrow=none;dashed=1;html=1;dashPattern=1 2;strokeWidth=2;rounded=0;strokeColor=#FF9999;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="30" y="250" as="sourcePoint" />
<mxPoint x="400" y="250" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="Sv76AHv-8cPqDwbSuwtx-22" value="&lt;font data-font-src=&quot;https://fonts.googleapis.com/css?family=Roboto&quot; style=&quot;font-size: 10px;&quot;&gt;8-byte&lt;br style=&quot;font-size: 10px;&quot;&gt;alignment&lt;/font&gt;" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Source Code Pro;fontSource=https%3A%2F%2Ffonts.googleapis.com%2Fcss%3Ffamily%3DSource%2BCode%2BPro;fontSize=10;fontColor=#FF3333;" vertex="1" parent="1">
<mxGeometry x="10" y="250" width="60" height="30" as="geometry" />
</mxCell>
<mxCell id="Sv76AHv-8cPqDwbSuwtx-23" value="&lt;font data-font-src=&quot;https://fonts.googleapis.com/css?family=Roboto&quot; style=&quot;font-size: 10px;&quot;&gt;8-byte&lt;br style=&quot;font-size: 10px;&quot;&gt;alignment&lt;/font&gt;" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Source Code Pro;fontSource=https%3A%2F%2Ffonts.googleapis.com%2Fcss%3Ffamily%3DSource%2BCode%2BPro;fontSize=10;fontColor=#FF3333;" vertex="1" parent="1">
<mxGeometry x="10" y="110" width="60" height="30" as="geometry" />
</mxCell>
<mxCell id="Sv76AHv-8cPqDwbSuwtx-24" value="&lt;font data-font-src=&quot;https://fonts.googleapis.com/css?family=Roboto&quot; style=&quot;font-size: 10px;&quot;&gt;8-byte&lt;br style=&quot;font-size: 10px;&quot;&gt;alignment&lt;/font&gt;" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Source Code Pro;fontSource=https%3A%2F%2Ffonts.googleapis.com%2Fcss%3Ffamily%3DSource%2BCode%2BPro;fontSize=10;fontColor=#FF3333;" vertex="1" parent="1">
<mxGeometry x="10" y="40" width="60" height="30" as="geometry" />
</mxCell>
<mxCell id="Sv76AHv-8cPqDwbSuwtx-26" value="" style="endArrow=none;dashed=1;html=1;dashPattern=1 2;strokeWidth=2;rounded=0;strokeColor=#FF9999;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="30" y="110" as="sourcePoint" />
<mxPoint x="400" y="110" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="Sv76AHv-8cPqDwbSuwtx-27" value="" style="endArrow=none;dashed=1;html=1;dashPattern=1 2;strokeWidth=2;rounded=0;strokeColor=#FF9999;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="30" y="39.31" as="sourcePoint" />
<mxPoint x="400" y="39.31" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="Sv76AHv-8cPqDwbSuwtx-28" value="" style="endArrow=none;dashed=1;html=1;dashPattern=1 2;strokeWidth=2;rounded=0;strokeColor=#FF9999;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="30" y="420" as="sourcePoint" />
<mxPoint x="400" y="420" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="Sv76AHv-8cPqDwbSuwtx-29" value="&lt;font data-font-src=&quot;https://fonts.googleapis.com/css?family=Roboto&quot; style=&quot;font-size: 10px;&quot;&gt;8-byte&lt;br style=&quot;font-size: 10px;&quot;&gt;alignment&lt;/font&gt;" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Source Code Pro;fontSource=https%3A%2F%2Ffonts.googleapis.com%2Fcss%3Ffamily%3DSource%2BCode%2BPro;fontSize=10;fontColor=#FF3333;" vertex="1" parent="1">
<mxGeometry x="10" y="390" width="60" height="30" as="geometry" />
</mxCell>
<mxCell id="Sv76AHv-8cPqDwbSuwtx-32" value="Overview of Multiboot2 Structures" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Roboto;fontSource=https%3A%2F%2Ffonts.googleapis.com%2Fcss%3Ffamily%3DRoboto;fontSize=14;fontStyle=1" vertex="1" parent="1">
<mxGeometry x="80" width="300" height="30" as="geometry" />
</mxCell>
<mxCell id="Sv76AHv-8cPqDwbSuwtx-33" value="&lt;div&gt;&lt;div&gt;&lt;div&gt;...&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=Source Code Pro;fontSource=https%3A%2F%2Ffonts.googleapis.com%2Fcss%3Ffamily%3DSource%2BCode%2BPro;verticalAlign=middle;align=center;" vertex="1" parent="1">
<mxGeometry x="250" y="390" width="120" height="20" as="geometry" />
</mxCell>
<mxCell id="Sv76AHv-8cPqDwbSuwtx-34" value="&lt;div&gt;&lt;div&gt;&lt;div&gt;...&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=Source Code Pro;fontSource=https%3A%2F%2Ffonts.googleapis.com%2Fcss%3Ffamily%3DSource%2BCode%2BPro;verticalAlign=middle;align=center;" vertex="1" parent="1">
<mxGeometry x="250" y="360" width="120" height="20" as="geometry" />
</mxCell>
<mxCell id="Sv76AHv-8cPqDwbSuwtx-35" value="&lt;div&gt;&lt;div&gt;&lt;div&gt;...&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=Source Code Pro;fontSource=https%3A%2F%2Ffonts.googleapis.com%2Fcss%3Ffamily%3DSource%2BCode%2BPro;verticalAlign=middle;align=center;" vertex="1" parent="1">
<mxGeometry x="90" y="360" width="120" height="20" as="geometry" />
</mxCell>
<mxCell id="Sv76AHv-8cPqDwbSuwtx-36" value="&lt;div&gt;&lt;div&gt;&lt;div&gt;...&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=Source Code Pro;fontSource=https%3A%2F%2Ffonts.googleapis.com%2Fcss%3Ffamily%3DSource%2BCode%2BPro;verticalAlign=middle;align=center;" vertex="1" parent="1">
<mxGeometry x="90" y="330" width="120" height="20" as="geometry" />
</mxCell>
<mxCell id="Sv76AHv-8cPqDwbSuwtx-39" value="Padding" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=Source Code Pro;fontSource=https%3A%2F%2Ffonts.googleapis.com%2Fcss%3Ffamily%3DSource%2BCode%2BPro;verticalAlign=middle;align=center;" vertex="1" parent="1">
<mxGeometry x="250" y="230" width="120" height="10" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>
61 changes: 54 additions & 7 deletions multiboot2-common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
//! - header structure (whole)
//! - header tags
//!
//! # The Problem / Difficulties
//! # Solved Problem & Difficulties Along the Way
//!
//! ## Multiboot2 Structures
//!
Expand All @@ -34,15 +34,21 @@
//!
//! Note that these structures can also be nested. So for example, the
//! Multiboot2 boot information contains Multiboot2 tags, and the Multiboot2
//! header contains Multiboot2 header tags - both are itself dynamic structures.
//! header contains Multiboot2 header tags - both are itself **dynamically
//! sized** structures. This means, you can know the size (and amount of
//! elements) **only at runtime!**
//!
//! A final `[u8]` field in the structs is the most rusty way to model this.
//! However, this makes the type a Dynamically Sized Type (DST). To create
//! references to these types from a byte slice, one needs fat pointers. They
//! are a language feature currently not constructable with stable Rust.
//! Luckily, we can utilize [`ptr_meta`].
//!
//! ## Dynamic and Sized Structs
//! Figure 1 in the [README](https://crates.io/crates/multiboot2-common)
//! (currently not embeddable in lib.rs unfortunately) provides an overview of
//! Multiboot2 structures.
//!
//! ## Dynamic and Sized Structs in Rust
//!
//! Note that we also have structures (tags) in Multiboot2 that looks like this:
//!
Expand All @@ -68,17 +74,49 @@
//! }
//! ```
//!
//! ## Fat Pointer Requirements
//! ## Chosen Design
//!
//! The overall common abstractions needed to solve the problems mentioned in
//! this section are also mainly influenced by the fact that the `multiboot2`
//! and `multiboot2-header` crates use a **zero-copy** design for parsing
//! the corresponding structures.
//!
//! Further, by having **ABI-compatible types** that fully represent the
//! reality, we can use the same type for parsing **and** for construction,
//! as modelled in the following simplified example:
//!
//! ```rust,ignore
//! /// ABI-compatible tag for parsing.
//! pub struct MemoryMapTag {
//! header: TagHeader,
//! entry_size: u32,
//! entry_version: u32,
//! areas: [MemoryArea],
//! }
//!
//! impl MemoryMapTag {
//! // We can also create an ABI-compatible structure of that type.
//! pub fn new(areas: &[MemoryArea]) -> Box<Self> {
//! // omitted
//! }
//! }
//! ```
//!
//! Hence, the structures can also be build at runtime. This is what we
//! consider **idiomatic and rusty**.
//!
//! ## Creating Fat Pointers with [`ptr_meta`]
//!
//! To create fat pointers with [`ptr_meta`], each tag needs a `Metadata` type
//! which is either `usize` (for DSTs) or `()`. A trait is needed to abstract
//! above sized or unsized types.
//!
//! ## Multiboot2 Requirements
//!
//! All tags must be 8-byte aligned. Space between multiple tags may be
//! filled with zeroes if necessary. These zeroes are not reflected in the
//! previous tag's size.
//! All tags must be 8-byte aligned. The actual payload of tags may be followed
//! by padding zeroes to fill the gap until the next alignment boundary, if
//! necessary. These zeroes are not reflected in the tag's size, but for Rust,
//! must be reflected in the memory allocation size.
//!
//! ## Rustc Requirements
//!
Expand All @@ -91,8 +129,15 @@
//!
//! See <https://doc.rust-lang.org/reference/type-layout.html> for information.
//!
//! Further, the [`Layout`]
//!
//! # Provided Abstractions
//!
//! Figure 2 in the [README](https://crates.io/crates/multiboot2-common)
//! (currently not embeddable in lib.rs unfortunately) provides an overview of
//! the parsing of Multiboot2 structures and how the definitions from this
//! crate are used.
//!
//! ## Parsing and Casting
//!
//! First, we need byte slices which are guaranteed to be aligned and are a
Expand Down Expand Up @@ -122,6 +167,8 @@
//! # No Public API
//!
//! Not meant as stable public API for others outside Multiboot2.
//!
//! [`Layout`]: core::alloc::Layout
#![no_std]
#![cfg_attr(feature = "unstable", feature(error_in_core))]
Expand Down

0 comments on commit 82b93e7

Please sign in to comment.