Kernel Internals
Other documented kernel modules.
src/acpi/rsdp.rs
RSDP struct
struct RSDP { /* … */ }RSDP
RSDP::get_rsdp_by_searching fn
fn get_rsdp_by_searching(mapper : &mut KernelMapper) -> Option<RSDP>Search for the RSDP
RSDP::sdt_address fn
fn sdt_address(&self) -> usizeGet the RSDT or XSDT address
src/acpi/sdt.rs
Sdt struct
struct Sdt { /* … */ }Sdt::data_address fn
fn data_address(&self) -> usizeGet the address of this tables data
Sdt::data_len fn
fn data_len(&self) -> usizeGet the length of this tables data
src/acpi/madt/mod.rs
Madt struct
struct Madt { /* … */ }The Multiple APIC Descriptor Table
madt fn
fn madt() -> Option<&'static Madt>FLAG_PCAT const
const FLAG_PCAT : u32MadtLocalApic struct
struct MadtLocalApic { /* … */ }MADT Local APIC
MadtIoApic struct
struct MadtIoApic { /* … */ }MADT I/O APIC
MadtIntSrcOverride struct
struct MadtIntSrcOverride { /* … */ }MADT Interrupt Source Override
MadtGicc struct
struct MadtGicc { /* … */ }MADT GICC
MadtGicd struct
struct MadtGicd { /* … */ }MADT GICD
MadtEntry enum
enum MadtEntry {
LocalApic,
InvalidLocalApic,
IoApic,
InvalidIoApic,
IntSrcOverride,
InvalidIntSrcOverride,
Gicc,
InvalidGicc,
Gicd,
InvalidGicd,
Unknown,
}MADT Entries
MadtIter struct
struct MadtIter { /* … */ }src/acpi/mod.rs
ACPI
Code to parse the ACPI tables
get_sdt fn
fn get_sdt(sdt_address : usize, mapper : &mut KernelMapper) -> &'static SdtGenericAddressStructure struct
struct GenericAddressStructure { /* … */ }RxsdtEnum enum
enum RxsdtEnum {
Rsdt,
Xsdt,
}init fn
unsafe fn init(already_supplied_rsdp : Option<* const u8>)Parse the ACPI tables to gather CPU, interrupt, and timer information
SdtSignature type
pub type SdtSignature =(String, [u8; 6], [u8; 8]);find_sdt fn
fn find_sdt(name : &str) -> Vec<&'static Sdt>get_sdt_signature fn
fn get_sdt_signature(sdt : &'static Sdt) -> SdtSignatureAcpi struct
struct Acpi { /* … */ }src/externs.rs
memcpy fn
unsafe extern "C" fn memcpy(dest : * mut u8, src : * const u8, len : usize) -> * mut u8Memcpy
Copy N bytes of memory from one location to another.
This faster implementation works by copying bytes not one-by-one, but in groups of 8 bytes (or 4 bytes in the case of 32-bit architectures).
memmove fn
unsafe extern "C" fn memmove(dest : * mut u8, src : * const u8, len : usize) -> * mut u8Memmove
Copy N bytes of memory from src to dest. The memory areas may overlap.
This faster implementation works by copying bytes not one-by-one, but in groups of 8 bytes (or 4 bytes in the case of 32-bit architectures).
memset fn
unsafe extern "C" fn memset(dest : * mut u8, byte : i32, len : usize) -> * mut u8Memset
Fill a block of memory with a specified value.
This faster implementation works by setting bytes not one-by-one, but in groups of 8 bytes (or 4 bytes in the case of 32-bit architectures).
memcmp fn
unsafe extern "C" fn memcmp(s1 : * const u8, s2 : * const u8, len : usize) -> i32Memcmp
Compare two blocks of memory.
This faster implementation works by comparing bytes not one-by-one, but in groups of 8 bytes (or 4 bytes in the case of 32-bit architectures).
src/cpu_stats.rs
CpuState enum
enum CpuState {
Idle = 0,
Kernel = 1,
User = 2,
}Current state of a CPU
CpuStats struct
struct CpuStats { /* … */ }Statistics for the CPUs.
CpuStatsData struct
struct CpuStatsData { /* … */ }CpuStats::set_state fn
fn set_state(&self, new_state : CpuState)Set the CPU's current state
Parameters
new_state- The state of the CPU for the following ticks.
CpuStats::add_time fn
fn add_time(&self, ticks : usize)Increments time statistics of a CPU
Which statistic is incremented depends on the [State] of the CPU.
Parameters
ticks- NUmber of ticks to add.
CpuStats::add_irq fn
fn add_irq(&self, irq : u8)Add an IRQ event to both the global count and the CPU that handled it.
This should be called in all [crate::arch::interrupt:irq::eoi], for all architectures.
Parameters
irq- The ID of the interrupt that happened.
add_context_switch fn
fn add_context_switch()Add a context switch to the count.
get_context_switch_count fn
fn get_context_switch_count() -> u64Get the number of context switches.
add_context fn
fn add_context()Add a context creation to the count.
get_contexts_count fn
fn get_contexts_count() -> u64Get the number of contexts created.
irq_counts fn
fn irq_counts() -> Vec<u64>Get the count of each interrupt.
src/main.rs
The Microkernel
The Microkernel is a microkernel that supports x86_64 systems and provides Unix-like syscalls for primarily Rust applications
src/event.rs
EventQueue struct
struct EventQueue { /* … */ }EventQueueList type
pub type EventQueueList = HashMap<EventQueueId, Arc<EventQueue>>;next_queue_id fn
fn next_queue_id() -> EventQueueIdGet next queue id
queues fn
fn queues() -> RwLockReadGuard<'static, EventQueueList>Get the event queues list, const
queues_mut fn
fn queues_mut() -> RwLockWriteGuard<'static, EventQueueList>Get the event queues list, mutable
RegKey struct
struct RegKey { /* … */ }QueueKey struct
struct QueueKey { /* … */ }registry_mut fn
fn registry_mut() -> RwLockWriteGuard<'static, Registry>Get the global schemes list, mutable
register fn
fn register(reg_key : RegKey, queue_key : QueueKey, flags : EventFlags)sync fn
fn sync(reg_key : RegKey) -> Result<EventFlags>unregister_file fn
fn unregister_file(scheme : SchemeId, number : usize)trigger fn
fn trigger(scheme : SchemeId, number : usize, flags : EventFlags)src/cpu_set.rs
LogicalCpuId struct
struct LogicalCpuId { /* … */ }A unique number used internally by the kernel to identify CPUs.
This is usually but not necessarily the same as the APIC ID.
MAX_CPU_COUNT const
const MAX_CPU_COUNT : u32MAX_CPU_COUNT const
const MAX_CPU_COUNT : u32LogicalCpuSet struct
struct LogicalCpuSet { /* … */ }RawMask type
pub type RawMask = [usize; SET_WORDS];mask_as_bytes fn
fn mask_as_bytes(mask : &RawMask) -> &[u8]src/emergency/evac.rs
Evacuate evictable process pages to the emergency disk store.
evacuate_all fn
fn evacuate_all() -> usizerestore_survivors fn
fn restore_survivors(killed_pids : &[usize]) -> usizediscard_killed fn
fn discard_killed(killed_pids : &[usize])src/emergency/input.rs
Lock-free keyboard input ring for the emergency picker.
push_irq fn
fn push_irq(byte : u8)Push a byte from an IRQ handler (keyboard / serio / debug).
poll fn
fn poll() -> Option<u8>Poll one byte, non-blocking.
clear fn
fn clear()src/emergency/snapshot.rs
Static process snapshot for the emergency picker.
MAX_SNAPSHOT_ENTRIES const
const MAX_SNAPSHOT_ENTRIES : usizeSnapshotEntry struct
struct SnapshotEntry { /* … */ }Snapshot struct
struct Snapshot { /* … */ }src/emergency/store.rs
Boot-time emergency disk store layout and block I/O hooks.
STORE_MAGIC const
const STORE_MAGIC : u32STORE_VERSION const
const STORE_VERSION : u32MAX_STORE_CONTEXTS const
const MAX_STORE_CONTEXTS : usizeHEADER_SIZE const
const HEADER_SIZE : usizeStoreHeader struct
struct StoreHeader { /* … */ }SlotEntry struct
struct SlotEntry { /* … */ }register_block_io fn
unsafe fn register_block_io(write : fn(offset : u64, data : &[u8; PAGE_SIZE]) -> Result<(),()>, read : fn(offset : u64, data : &mut [u8; PAGE_SIZE]) -> Result<(),()>,)Register kernel block read/write for the emergency store.
init_from_boot fn
fn init_from_boot(total_override : Option<usize>)Initialize metadata for a store sized to hold all physical pages.
is_ready fn
fn is_ready() -> booltotal_page_slots fn
fn total_page_slots() -> usizewrite_page fn
fn write_page(slot_index : usize, data : &[u8; PAGE_SIZE]) -> Result<(),()>read_page fn
fn read_page(slot_index : usize, data : &mut [u8; PAGE_SIZE]) -> Result<(),()>mark_slot_killed fn
fn mark_slot_killed(pid : u32)slot_flags_unused fn
fn slot_flags_unused() -> u32slot_flags_active fn
fn slot_flags_active() -> u32slot_flags_killed fn
fn slot_flags_killed() -> u32src/emergency/picker.rs
Kernel emergency process picker (framebuffer text or serial).
PickerAction enum
enum PickerAction {
Kill,
}run fn
fn run(snapshot : &mut Snapshot) -> PickerActionString struct
struct String { /* … */ }notify_entering_picker fn
fn notify_entering_picker()src/emergency/mod.rs
Humane memory emergency orchestration.
register_oom_daemon fn
fn register_oom_daemon(pid : usize)Register a userspace OOM daemon to notify when RAM has been freed by evacuation.
enter fn
fn enter()Enter the emergency handler. Blocks until memory pressure is relieved.
src/common/int_like.rs
Helpers used to define types that are backed by integers (typically usize), without compromising safety.
Example
/// Define an opaque type `Pid` backed by a `usize`.
int_like!(Pid, usize);
const ZERO: Pid = Pid::from(0);Example
/// Define opaque types `Pid` and `AtomicPid`, backed respectively by a `usize`
/// and a `AtomicUsize`.
int_like!(Pid, AtomicPid, usize, AtomicUsize);
const ZERO: Pid = Pid::from(0);
let ATOMIC_PID: AtomicPid = AtomicPid::default();src/common/unique.rs
Unique struct
struct Unique { /* … */ }A small wrapper around NonNull<T> that is Send + Sync, which is only correct if the pointer is never accessed from multiple locations across threads. Which is always, if the pointer is unique.
src/panic.rs
Intrinsics for panic handling
stack_trace fn
unsafe fn stack_trace()Get a stack trace
symbol_trace fn
unsafe fn symbol_trace(addr : usize)Get a symbol
src/percpu.rs
PercpuBlock struct
struct PercpuBlock { /* … */ }The percpu block, that stored all percpu variables.
init_tlb_shootdown fn
unsafe fn init_tlb_shootdown(id : LogicalCpuId, block : * mut PercpuBlock)get_all_stats fn
fn get_all_stats() -> Vec<(LogicalCpuId, CpuStatsData)>shootdown_tlb_ipi fn
fn shootdown_tlb_ipi(_target : Option<LogicalCpuId>)shootdown_tlb_ipi fn
fn shootdown_tlb_ipi(target : Option<LogicalCpuId>)switch_arch_hook fn
unsafe fn switch_arch_hook()src/ptrace.rs
The backend of the "proc:" scheme. Most internal breakpoint handling should go here, unless they closely depend on the design of the scheme.
SessionData struct
struct SessionData { /* … */ }SessionData::set_breakpoint fn
fn set_breakpoint(&mut self, flags : Option<PtraceFlags>)Override the breakpoint for the specified tracee. Pass None to clear breakpoint.
SessionData::is_reached fn
fn is_reached(&self) -> boolReturns true if the breakpoint is reached, or if there isn't a breakpoint
SessionData::session_fevent_flags fn
fn session_fevent_flags(&self) -> EventFlagsUsed for getting the flags in fevent
SessionData::recv_events fn
fn recv_events(&mut self, out : &mut [PtraceEvent]) -> usizePoll events, return the amount read. This drains events from the queue.
Session struct
struct Session { /* … */ }close_session fn
fn close_session(session : &Session)Remove the session from the list of open sessions and notify any waiting processes
close_tracee fn
fn close_tracee(session : &Session)Wake up the tracer to make sure it catches on that the tracee is dead. This is different from close_session in that it doesn't actually close the session, and instead waits for the file handle to be closed, where the session will actually be closed. This is partly to ensure ENOSRCH is returned rather than ENODEV (which occurs when there's no session - should never really happen).
send_event fn
fn send_event(event : PtraceEvent) -> Option<()>Dispatch an event to any tracer tracing self. This will cause the tracer to wake up and poll for events. Returns Some(()) if an event was sent.
wait fn
fn wait(session : Arc<Session>) -> Result<()>Wait for the tracee to stop, or return immediately if there's an unread event.
Note: Don't call while holding any locks or allocated data, this will switch contexts and may in fact just never terminate.
breakpoint_callback fn
fn breakpoint_callback(match_flags : PtraceFlags, event : Option<PtraceEvent>,) -> Option<PtraceFlags>Notify the tracer and await green flag to continue. If the breakpoint was set and reached, return the flags which the user waited for. Otherwise, None.
Note: Don't call while holding any locks or allocated data, this will switch contexts and may in fact just never terminate.
next_breakpoint fn
fn next_breakpoint() -> Option<PtraceFlags>Obtain the next breakpoint flags for the current process. This is used for detecting whether or not the tracer decided to use sysemu mode.