Inline Documentation Fixes

This commit is contained in:
Pascal Reich
2026-01-10 23:19:34 +00:00
committed by Jeremy Soller
parent ea06685903
commit a919d2626b
10 changed files with 62 additions and 62 deletions
+38 -38
View File
@@ -26,54 +26,54 @@ Once the core kernel port is complete a similar follow on document will be creat
## Boot protocol elements
Item | Notes
-----|-------
[Linux kernel boot protocol for AArch64](https://www.kernel.org/doc/Documentation/arm64/booting.txt) | The linked document describes assumptions made from the bootloader which are field tested and worthwhile to have for Redox an AArch64. <br/> The intent is to consider most of the document except anything tied to the Linux kernel itself.
[Flattened Device Tree](https://elinux.org/Device_Tree_Reference) | FDT binary blobs supplied by the bootloader shall provide the Redox kernel with misc platform \{memory, interrupt, devicemem} maps. Qemu's virt machine platform synthetically creates an FDT blob at a specific address which is very handy.
| Item | Notes |
|------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [Linux kernel boot protocol for AArch64](https://www.kernel.org/doc/Documentation/arm64/booting.txt) | The linked document describes assumptions made from the bootloader which are field tested and worthwhile to have for Redox an AArch64. <br/> The intent is to consider most of the document except anything tied to the Linux kernel itself. |
| [Flattened Device Tree](https://elinux.org/Device_Tree_Reference) | FDT binary blobs supplied by the bootloader shall provide the Redox kernel with misc platform \{memory, interrupt, devicemem} maps. Qemu's virt machine platform synthetically creates an FDT blob at a specific address which is very handy. |
## Boot flow elements
The following table lists the boot flow in order.
Item | Notes
-----|-------
[ARM Trusted Firmware (TF-A)](https://github.com/ARM-software/arm-trusted-firmware) | TF-A is a de-facto standard reference firmware implementation and proven in the field. <br/> TF-A runs post power-on on Armv8-A implementations and eventually hands off to further stages of the boot flow.<br />For qemu's virt machine platform, it is essentially absent but I mean to rely on it heavily for silicon bring up hence mentioning it here.
[u-boot](https://www.denx.de/wiki/U-Boot) | u-boot will handle early console access, media access for fetching redox kernel images from non-volatile storage/misc disk subsystems/off the network. <br /> u-boot supports loading EFI applications. If EFI support to AArch64 Redox is added in the future that should essentially work out of the box. <br /> u-boot will load redox and FDT binary blobs into RAM and jump to the redox kernel.
Redox early-init stub | For AArch64, the redox kernel will contain an A64 assembly stub that will setup the MMU from scratch. This is akin to the [x86_64 redox bootloader](https://github.com/redox-os/bootloader/blob/master/x86_64/startup-x86_64.asm). <br /> This stub sets up identity maps for MMU initialization, maps the kernel image itself as well as the device memory for the UART console. At present this stub shall be a part of the kernel itself for simplicity.
Redox kstart entry | The early init stub hands off here. kstart will then re-init the MMU more comprehensively.
| Item | Notes |
|-------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [ARM Trusted Firmware (TF-A)](https://github.com/ARM-software/arm-trusted-firmware) | TF-A is a de-facto standard reference firmware implementation and proven in the field. <br/> TF-A runs post power-on on Armv8-A implementations and eventually hands off to further stages of the boot flow.<br />For qemu's virt machine platform, it is essentially absent but I mean to rely on it heavily for silicon bring up hence mentioning it here. |
| [u-boot](https://www.denx.de/wiki/U-Boot) | u-boot will handle early console access, media access for fetching redox kernel images from non-volatile storage/misc disk subsystems/off the network. <br /> u-boot supports loading EFI applications. If EFI support to AArch64 Redox is added in the future that should essentially work out of the box. <br /> u-boot will load redox and FDT binary blobs into RAM and jump to the redox kernel. |
| Redox early-init stub | For AArch64, the redox kernel will contain an A64 assembly stub that will setup the MMU from scratch. This is akin to the [x86_64 redox bootloader](https://github.com/redox-os/bootloader/blob/master/x86_64/startup-x86_64.asm). <br /> This stub sets up identity maps for MMU initialization, maps the kernel image itself as well as the device memory for the UART console. At present this stub shall be a part of the kernel itself for simplicity. |
| Redox kstart entry | The early init stub hands off here. kstart will then re-init the MMU more comprehensively. |
## Supported devices
The following devices shall be supported. All necessary information specific to these devices will be provided to the redox kernel by the platform specific FDT binary blob.
Device | Notes
-------|-------
[Generic Interrupt Controller v2](https://developer.arm.com/products/architecture/a-profile/docs/ihi0048/b/arm-generic-interrupt-controller-architecture-version-20-architecture-specification) | The GIC is an Arm-v8A architectural element and is supported by all architecturally compliant processor implementations. GICv2 is supported by qemu's virt machine emulation and most subsequent GIC implementations are backward compatible to GICv2.
[Generic Timer](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0500d/BGBBIJCB.html) | The Generic Timer Architecture is an Arm-v8A architectural element and is implemented by all compliant processor implementations. It is supported by qemu.
[PrimeCell UART PL011](http://infocenter.arm.com/help/topic/com.arm.doc.ddi0183f/DDI0183.pdf) | The PL011 UART is supported by qemu and most ARM systems.
| Device | Notes |
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [Generic Interrupt Controller v2](https://developer.arm.com/products/architecture/a-profile/docs/ihi0048/b/arm-generic-interrupt-controller-architecture-version-20-architecture-specification) | The GIC is an Arm-v8A architectural element and is supported by all architecturally compliant processor implementations. GICv2 is supported by qemu's virt machine emulation and most subsequent GIC implementations are backward compatible to GICv2. |
| [Generic Timer](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0500d/BGBBIJCB.html) | The Generic Timer Architecture is an Arm-v8A architectural element and is implemented by all compliant processor implementations. It is supported by qemu. |
| [PrimeCell UART PL011](http://infocenter.arm.com/help/topic/com.arm.doc.ddi0183f/DDI0183.pdf) | The PL011 UART is supported by qemu and most ARM systems. |
## Intended development sequence and status
Item | Description | Status | Notes
-----|-------|-----|-----
Redox AArch64 toolchain | Create an usable redox AArch64 toolchain specification | Done | Using this JSON spec in isolated tests produces valid AArch64 soft float code
Stubbed kernel image | Stub out AArch64 kernel support using the existing x86_64 arch code as a template <br /> Modify redox kernel build glue and work iteratively to get a linkable (non-functional) image | Not done yet |
Boot flow | Create a self hosted u-boot -> redox kernel workflow <br /> Should obtain the stubbed image from a local TFTP server, load it into RAM and jump to it | Not done yet |
GDB Debug flow | Create a debug workflow centered around qemu's GDB stub <br /> This should allow connecting to qemu's GDB stub and debug u-boot/redox stub via a GDB client and single stepping through code | Not done yet |
Verify Redox entry | Verify that control reaches the redox kernel from u-boot | Not done yet |
AArch64 early init stub | Add support for raw asm code for early AArch64 init in the redox kernel <br /> Verify that this code is located appropriately in the link map and that control reaches this code from u-boot | Not done yet |
Basic DTB support | Integrate the [device_tree crate](https://mbr.github.io/device_tree-rs/device_tree/) <br /> Use the crate to access the qemu supplied DTB image and extract the memory map | Not done yet |
Basic UART support | Use the device_tree crate to get the UART address from the DTB image and set up the initial console <br /> This is a polling mode only setup | Not done yet |
Initial MMU support | Implement initial MMU support in the early init stub <br /> This forces the MMU into a clean state overriding any bootloader specific setup <br /> Create an identity map for MMU init <br /> Create a mapping for the kernel image <br /> Create a mapping for any devices needed at this stage (UART)| Not done yet |
kmain entry | Verify that kmain entry works post early MMU init | Not done yet |
Basic Redox MMU support | Get Redox to create a final set of mappings for everything <br /> Verify that this works as expected| Not done yet |
Basic libc support | Flesh out a basic set of libc calls as required for simple user-land apps | Not done yet |
userspace_init entry | Verify user-space entry and /sbin/init invocation | Not done yet |
Basic Interrupt controller support | Add a GIC driver <br /> Verify functionality | Not done yet |
Basic Timer support | Add a Generic Timer driver <br /> Verify functionality | Not done yet |
UART interrupt support | Add support for UART interrupts | Not done yet |
Task context switch support | Add context switching support <br /> Verify functionality | Not done yet |
Login shell | Iteratively add and verify multi-user login shell support | Not done yet |
Publish development branch on github | Work with the community to post work done after employer approval | Not done yet |
Break out the Bubbly | Drink copious quantities of alcohol to celebrate | Not done yet |
Silicon bring-up | Plan silicon bring-up | Not done yet |
| Item | Description | Status | Notes |
|--------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------|-------------------------------------------------------------------------------|
| Redox AArch64 toolchain | Create an usable redox AArch64 toolchain specification | Done | Using this JSON spec in isolated tests produces valid AArch64 soft float code |
| Stubbed kernel image | Stub out AArch64 kernel support using the existing x86_64 arch code as a template <br /> Modify redox kernel build glue and work iteratively to get a linkable (non-functional) image | Not done yet | |
| Boot flow | Create a self hosted u-boot -> redox kernel workflow <br /> Should obtain the stubbed image from a local TFTP server, load it into RAM and jump to it | Not done yet | |
| GDB Debug flow | Create a debug workflow centered around qemu's GDB stub <br /> This should allow connecting to qemu's GDB stub and debug u-boot/redox stub via a GDB client and single stepping through code | Not done yet | |
| Verify Redox entry | Verify that control reaches the redox kernel from u-boot | Not done yet | |
| AArch64 early init stub | Add support for raw asm code for early AArch64 init in the redox kernel <br /> Verify that this code is located appropriately in the link map and that control reaches this code from u-boot | Not done yet | |
| Basic DTB support | Integrate the [device_tree crate](https://mbr.github.io/device_tree-rs/device_tree/) <br /> Use the crate to access the qemu supplied DTB image and extract the memory map | Not done yet | |
| Basic UART support | Use the device_tree crate to get the UART address from the DTB image and set up the initial console <br /> This is a polling mode only setup | Not done yet | |
| Initial MMU support | Implement initial MMU support in the early init stub <br /> This forces the MMU into a clean state overriding any bootloader specific setup <br /> Create an identity map for MMU init <br /> Create a mapping for the kernel image <br /> Create a mapping for any devices needed at this stage (UART) | Not done yet | |
| kmain entry | Verify that kmain entry works post early MMU init | Not done yet | |
| Basic Redox MMU support | Get Redox to create a final set of mappings for everything <br /> Verify that this works as expected | Not done yet | |
| Basic libc support | Flesh out a basic set of libc calls as required for simple user-land apps | Not done yet | |
| userspace_init entry | Verify user-space entry and /sbin/init invocation | Not done yet | |
| Basic Interrupt controller support | Add a GIC driver <br /> Verify functionality | Not done yet | |
| Basic Timer support | Add a Generic Timer driver <br /> Verify functionality | Not done yet | |
| UART interrupt support | Add support for UART interrupts | Not done yet | |
| Task context switch support | Add context switching support <br /> Verify functionality | Not done yet | |
| Login shell | Iteratively add and verify multi-user login shell support | Not done yet | |
| Publish development branch on github | Work with the community to post work done after employer approval | Not done yet | |
| Break out the Bubbly | Drink copious quantities of alcohol to celebrate | Not done yet | |
| Silicon bring-up | Plan silicon bring-up | Not done yet | |
+1 -1
View File
@@ -17,7 +17,7 @@ pub unsafe fn init() {
// IA32_STAR[31:0] are reserved.
// The base selector of the two consecutive segments for kernel code and the immediately
// suceeding stack (data).
// succeeding stack (data).
let syscall_cs_ss_base = (gdt::GDT_KERNEL_CODE as u16) << 3;
// The base selector of the three consecutive segments (of which two are used) for user code
// and user data. It points to a 32-bit code segment, which must be followed by a data segment
+1 -1
View File
@@ -20,7 +20,7 @@ pub unsafe fn init() {
pic::init();
local_apic::init(&mut KernelMapper::lock());
// Run here for the side-effect of printing if KVM was used to avoid interleaved logs.
// Run here for the side effect of printing if KVM was used to avoid interleaved logs.
tsc::get_kvm_support();
}
}
+1 -1
View File
@@ -27,7 +27,7 @@ pub unsafe fn enable_and_halt() {
/// Set interrupts and nop
/// This will enable interrupts and allow the IF flag to be processed
/// Simply enabling interrupts does not gurantee that they will trigger, use this instead!
/// Simply enabling interrupts does not guarantee that they will trigger, use this instead!
#[inline(always)]
pub unsafe fn enable_and_nop() {
unsafe {
+2 -2
View File
@@ -721,9 +721,9 @@ impl AddrSpace {
#[derive(Debug)]
pub struct UserGrants {
// Using a BTreeMap for it's range method.
// Using a BTreeMap for its range method.
inner: BTreeMap<Page, GrantInfo>,
// Using a BTreeMap for it's range method.
// Using a BTreeMap for its range method.
holes: BTreeMap<VirtualAddress, usize>,
// TODO: Would an additional map ordered by (size,start) to allow for O(log n) allocations be
// beneficial?
+1 -1
View File
@@ -18,7 +18,7 @@ pub enum CpuState {
/// Waiting for runnable context
#[default]
Idle = 0,
/// Runnnig a kernel context
/// Running a kernel context
Kernel = 1,
/// Running a context in the userspace
User = 2,
+1 -1
View File
@@ -222,7 +222,7 @@ fn trigger_inner(
}
pub fn trigger(scheme: SchemeId, number: usize, flags: EventFlags) {
//TODO: propogate this lock token
//TODO: propagate this lock token
let mut token = unsafe { CleanLockToken::new() };
// First trigger with the original file
+6 -6
View File
@@ -19,27 +19,27 @@
#![allow(clippy::too_many_arguments)]
// Used to allow stuff like 1 << 0 and 1 * 1024 * 1024
#![allow(clippy::identity_op)]
// TODO: address ocurrances and then deny
// TODO: address occurrences and then deny
#![warn(clippy::not_unsafe_ptr_arg_deref)]
// TODO: address ocurrances and then deny
// TODO: address occurrences and then deny
#![warn(clippy::cast_ptr_alignment)]
// Indexing a slice can cause panics and that is something we always want to avoid
// in kernel code. Use .get and return an error instead
// TODO: address ocurrances and then deny
// TODO: address occurrences and then deny
#![warn(clippy::indexing_slicing)]
// Overflows are very, very bad in kernel code as it may provide an attack vector for
// userspace applications, and it is only checked in debug builds
// TODO: address ocurrances and then deny
// TODO: address occurrences and then deny
#![warn(clippy::arithmetic_side_effects)]
// Avoid panicking in the kernel without information about the panic. Use expect
// TODO: address ocurrances and then deny
// TODO: address occurrences and then deny
#![warn(clippy::unwrap_used)]
// This is usually a serious issue - a missing import of a define where it is interpreted
// as a catch-all variable in a match, for example
#![deny(unreachable_patterns)]
// Ensure that all must_use results are used
#![deny(unused_must_use)]
#![warn(static_mut_refs)] // FIXME deny once all occurences are fixed
#![warn(static_mut_refs)] // FIXME deny once all occurrences are fixed
#![feature(if_let_guard)]
#![feature(int_roundings)]
#![feature(iter_next_chunk)]
+2 -2
View File
@@ -486,11 +486,11 @@ impl UserInner {
map_flags.set(MapFlags::PROT_WRITE, WRITE);
if user_buf.is_empty() {
// NOTE: Rather than returning NULL, we return a dummy dangling address, that is
// NOTE: Rather than returning NULL, we return a dummy dangling address, which
// happens to be non-canonical on x86. This relieves scheme handlers from having to
// check the length before e.g. creating nonnull Rust references (when an empty length
// still requires a nonnull but possibly dangling pointer, and this has in practice
// made nulld errorneously confuse an empty Some("") with None (invalid UTF-8), due to
// made nulld erroneously confuse an empty Some("") with None (invalid UTF-8), due to
// enum layout optimization, as the pointer was null and not dangling). A good choice
// is thus to simply set the most-significant bit to be compatible with all alignments.
return Ok(CaptureGuard {
+9 -9
View File
@@ -3,13 +3,13 @@
#![allow(dead_code)]
//! This create implement compiletime ordering of locks into levels, [`L1`], [`L2`], [`L3`], [`L4`] and [`L5`].
//! This crate implements compiletime ordering of locks into levels, [`L1`], [`L2`], [`L3`], [`L4`] and [`L5`].
//! In order to acquire a lock at level `i` only locks at level `i-1` or below may be held.
//!
//! If locks are alwayes acquired in level order on all threads, then one cannot have a deadlock
//! involving only acquireng locks.
//! If locks are always acquired in level order on all threads, then one cannot have a deadlock
//! involving only acquired locks.
//!
//! In the following example we create two [muteces](Mutex) at level [`L1`] and [`L2`] and lock them
//! In the following example we create two [mutexes](Mutex) at level [`L1`] and [`L2`] and lock them
//! in the propper order.
//! ```
//! use ordered_locks::{L1, L2, Mutex, CleanLockToken};
@@ -21,7 +21,7 @@
//! let mut token = unsafe {CleanLockToken::new()};
//!
//! {
//! // We can aquire the locks for v1 and v2 at the same time
//! // We can acquire the locks for v1 and v2 at the same time
//! let mut g1 = v1.lock(token.token());
//! let (g1, token) = g1.token_split();
//! let mut g2 = v2.lock(token);
@@ -32,7 +32,7 @@
//! *v2.lock(token.token()) = 13;
//! ```
//!
//! In the following example we create two [muteces](Mutex) at level [`L1`] and [`L2`] and try to lock
//! In the following example we create two [mutexes](Mutex) at level [`L1`] and [`L2`] and try to lock
//! the mutex at [`L1`] while already holding a [`Mutex`] at [`L2`] which failes to compile.
//! ```compile_fail
//! use ordered_locks::{L1, L2, Mutex, CleanLockToken};
@@ -57,7 +57,7 @@ use core::marker::PhantomData;
/// Lock level of a mutex
///
/// While a mutex of L1 is locked on a thread, only mutexes of L2 or higher may be locked.
/// This lock hierarchy prevents deadlocks from occurring. For a dead lock to occour
/// This lock hierarchy prevents deadlocks from occurring. For a deadlock to occur
/// We need some thread TA to hold a resource RA, and request a resource RB, while
/// another thread TB holds RB, and requests RA. This is not possible with a lock
/// hierarchy either RA or RB must be on a level that the other.
@@ -121,7 +121,7 @@ pub trait Higher<O: Level>: Level {}
impl<L1: Level, L2: Level> Higher<L2> for L1 where L2: Lower<L1> {}
/// While this exists only locks with a level higher than L, may be locked.
/// These tokens are carried around the call stack to indicate tho current locking level.
/// These tokens are carried around the call stack to indicate the current locking level.
/// They have no size and should disappear at runtime.
pub struct LockToken<'a, L: Level>(PhantomData<&'a mut L>);
@@ -293,7 +293,7 @@ impl<L: Level, T: Default> Default for RwLock<L, T> {
/// The type parameter T represents the data that this lock protects. It is required that T satisfies
/// Send to be shared across threads and Sync to allow concurrent access through readers.
/// The RAII guards returned from the locking methods implement Deref (and DerefMut for the write methods)
/// to allow access to the contained of the lock.
/// to allow access to the container of the lock.
impl<L: Level, T> RwLock<L, T> {
/// Creates a new instance of an RwLock<T> which is unlocked.
pub const fn new(val: T) -> Self {