-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
kernel: initial thread, module, instance data structures
- Loading branch information
Showing
7 changed files
with
159 additions
and
55 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
//! Module instance types and functionality. | ||
use crate::{module::Module, registry::Handle, ring::Ring}; | ||
|
||
/// A singular module instance. | ||
/// | ||
/// Modules are effectively executables in the Oro ecosystem, | ||
/// loading similarly to processes in a traditional operating system. | ||
/// By themselves, modules do not do anything - it is when they are | ||
/// mounted onto a ring as an instance (hence "module instance") | ||
/// that they are effectively spawned and executed. | ||
/// | ||
/// The kernel does not keep modules in memory; only module instances. | ||
/// | ||
/// Further, not every module instance comes from a discrete module; | ||
/// on the root ring, the kernel mounts several built-in modules | ||
/// as instances to interact with system resources at a very low level. | ||
/// These are often referred to as "built-in modules" or "kernel modules". | ||
/// Unlike e.g. Linux, kernel modules are not extensible nor can they be | ||
/// added via user configuration; they are hard-coded into the kernel, | ||
/// and are often architecture-specific. | ||
/// | ||
/// Typically the bootloader will have some means by which to load modules | ||
/// as instances onto the root ring, since without any additional application- | ||
/// specific modules, the kernel is effectively useless (will do nothing on | ||
/// boot). The preboot routine (that jumps to the kernel, see `oro_boot::boot_to_kernel()`) | ||
/// provides a means for memory-mapped portable executables (PEs) to be loaded | ||
/// onto the root ring as instances. | ||
/// | ||
/// Those instances will have the highest privilege level, and will be able | ||
/// to interact with the kernel directly via the built-in modules, and | ||
/// from there can spawn additional rings and instances as needed to | ||
/// bootstrap the rest of the system as they see fit. | ||
pub struct Instance { | ||
/// The module instance ID. | ||
id: usize, | ||
/// The module from which this instance was spawned. | ||
module: Handle<Module>, | ||
/// The ring on which this instance resides. | ||
ring: Handle<Ring>, | ||
} | ||
|
||
impl Instance { | ||
/// Returns the instance ID. | ||
/// | ||
/// # Safety | ||
/// **DO NOT USE THIS ID FOR ANYTHING SECURITY RELATED.** | ||
/// | ||
/// IDs are recycled when instances are dropped from the registry, | ||
/// meaning functions that accept numeric IDs might return or work | ||
/// with [`Handle`]s that refer to unintended instances that have | ||
/// been inserted into the same slot. | ||
#[must_use] | ||
pub unsafe fn id(&self) -> usize { | ||
self.id | ||
} | ||
|
||
/// The [`Handle`] to the module from which this instance was spawned. | ||
pub fn module(&self) -> Handle<Module> { | ||
self.module.clone() | ||
} | ||
|
||
/// The [`Handle`] to the ring on which this instance resides. | ||
pub fn ring(&self) -> Handle<Ring> { | ||
self.ring.clone() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,59 +1,39 @@ | ||
//! Implements Oro module instances in the kernel. | ||
#![expect(clippy::module_name_repetitions)] | ||
use crate::id::{Id, IdType}; | ||
|
||
/// A singular module instance. | ||
/// | ||
/// Modules are effectively executables in the Oro ecosystem, | ||
/// loading similarly to processes in a traditional operating system. | ||
/// By themselves, modules do not do anything - it is when they are | ||
/// mounted onto a ring as an instance (hence "module instance") | ||
/// that they are effectively spawned and executed. | ||
/// | ||
/// The kernel does not keep modules in memory; only module instances. | ||
/// | ||
/// Further, not every module instance comes from a discrete module; | ||
/// on the root ring, the kernel mounts several built-in modules | ||
/// as instances to interact with system resources at a very low level. | ||
/// These are often referred to as "built-in modules" or "kernel modules". | ||
/// Unlike e.g. Linux, kernel modules are not extensible nor can they be | ||
/// added via user configuration; they are hard-coded into the kernel, | ||
/// and are often architecture-specific. | ||
/// | ||
/// Typically the bootloader will have some means by which to load modules | ||
/// as instances onto the root ring, since without any additional application- | ||
/// specific modules, the kernel is effectively useless (will do nothing on | ||
/// boot). The preboot routine (that jumps to the kernel, see `oro_boot::boot_to_kernel()`) | ||
/// provides a means for memory-mapped portable executables (PEs) to be loaded | ||
/// onto the root ring as instances. | ||
/// | ||
/// Those instances will have the highest privilege level, and will be able | ||
/// to interact with the kernel directly via the built-in modules, and | ||
/// from there can spawn additional rings and instances as needed to | ||
/// bootstrap the rest of the system as they see fit. | ||
/// | ||
/// # Module IDs | ||
/// Module IDs internally are just the offset of the module instance | ||
/// in the arena pool, divided by the size of the arena slot. Put simply, | ||
/// if you think of the arena pool as an array of module instances, | ||
/// the module ID is the index of the module instance in that array. | ||
/// | ||
/// Module instances, rings, and ports all have their own ID spaces. | ||
/// This means that a module instance, ring, and port can all have the | ||
/// same ID, and they will not conflict with each other. | ||
/// | ||
/// In no case should a module's ID be used to indicate its functionality, | ||
/// version, or other metadata. It is purely an internal identifier, and | ||
/// should be treated as random. It is only valid for the lifetime of the | ||
/// module instance, and should not be stored or used outside of that context. | ||
/// They should be treated like process IDs in a traditional operating system. | ||
pub struct ModuleInstance { | ||
/// Module metadata. | ||
pub struct Module { | ||
/// The instance ID. This is unique for each module instance, | ||
/// but can be re-used if instances are destroyed. | ||
/// | ||
/// It is the offset of the arena slot into the arena pool. | ||
pub id: u32, | ||
/// The module ID from which this instance was spawned. | ||
pub module_id: Id<{ IdType::Module }>, | ||
/// | ||
/// **DO NOT USE THIS ID FOR ANYTHING SECURITY RELATED.** | ||
pub(crate) id: usize, | ||
/// The module ID. Provided by the ring spawner and used | ||
/// to refer to the module during module loading. | ||
pub(crate) module_id: Id<{ IdType::Module }>, | ||
} | ||
|
||
impl Module { | ||
/// Returns the instance ID. | ||
/// | ||
/// # Safety | ||
/// **DO NOT USE THIS ID FOR ANYTHING SECURITY RELATED.** | ||
/// | ||
/// IDs are re-used by registries when items are dropped, so | ||
/// functions that take numeric IDs to return [`crate::registry::Handle`]s | ||
/// may return a new item unexpectedly if the old one was dropped | ||
/// and the slot was re-used. | ||
#[must_use] | ||
pub unsafe fn id(&self) -> usize { | ||
self.id | ||
} | ||
|
||
/// Returns the module ID. | ||
#[must_use] | ||
pub fn module_id(&self) -> &Id<{ IdType::Module }> { | ||
&self.module_id | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
//! Thread management types and functions. | ||
use crate::{instance::Instance, registry::Handle}; | ||
use oro_mem::mapper::AddressSpace; | ||
|
||
/// A singular system thread. | ||
/// | ||
/// Threads are the primary unit of 'execution' in the | ||
/// Oro kernel. They are scheduled by the kernel, | ||
/// owned by a single core's [`crate::Kernel`] instance's | ||
/// scheduler at any given time. | ||
/// | ||
/// Threads belong to module [`Instance`]s and, unlike | ||
/// other OSes, are not nested (i.e. a thread does not | ||
/// have a parent thread). | ||
pub struct Thread<AddrSpace: AddressSpace> { | ||
/// The thread's ID. | ||
pub(crate) id: usize, | ||
/// The module instance to which this thread belongs. | ||
pub(crate) instance: Handle<Instance>, | ||
/// The thread's address space handle. | ||
pub(crate) space: AddrSpace::UserHandle, | ||
} | ||
|
||
impl<AddrSpace: AddressSpace> Thread<AddrSpace> { | ||
/// Returns the thread's ID. | ||
/// | ||
/// # Safety | ||
/// **DO NOT USE THIS FUNCTION FOR ANYTHING SECURITY RELATED.** | ||
/// | ||
/// IDs are re-used by registries when items are dropped, so | ||
/// multiple calls to an ID lookup function may return handles to | ||
/// different thread items as the IDs get recycled. | ||
/// | ||
/// Only use this function for debugging or logging purposes, or | ||
/// for handing IDs to the user. | ||
#[must_use] | ||
pub unsafe fn id(&self) -> usize { | ||
self.id | ||
} | ||
|
||
/// Returns module instance [`Handle`] to which this thread belongs. | ||
pub fn instance(&self) -> Handle<Instance> { | ||
self.instance.clone() | ||
} | ||
|
||
/// Returns the thread's address space handle. | ||
#[must_use] | ||
pub fn space(&self) -> &AddrSpace::UserHandle { | ||
&self.space | ||
} | ||
} |