Skip to content

Kernel Internals

Other documented kernel modules.

src/acpi/rsdp.rs

RSDP struct

rust
struct RSDP { /* … */ }

RSDP

RSDP::get_rsdp_by_searching fn

rust
fn get_rsdp_by_searching(mapper : &mut KernelMapper) -> Option<RSDP>

Search for the RSDP

RSDP::sdt_address fn

rust
fn sdt_address(&self) -> usize

Get the RSDT or XSDT address

src/acpi/sdt.rs

Sdt struct

rust
struct Sdt { /* … */ }

Sdt::data_address fn

rust
fn data_address(&self) -> usize

Get the address of this tables data

Sdt::data_len fn

rust
fn data_len(&self) -> usize

Get the length of this tables data

src/acpi/madt/mod.rs

Madt struct

rust
struct Madt { /* … */ }

The Multiple APIC Descriptor Table

madt fn

rust
fn madt() -> Option<&'static Madt>

FLAG_PCAT const

rust
const FLAG_PCAT : u32

MadtLocalApic struct

rust
struct MadtLocalApic { /* … */ }

MADT Local APIC

MadtIoApic struct

rust
struct MadtIoApic { /* … */ }

MADT I/O APIC

MadtIntSrcOverride struct

rust
struct MadtIntSrcOverride { /* … */ }

MADT Interrupt Source Override

MadtGicc struct

rust
struct MadtGicc { /* … */ }

MADT GICC

MadtGicd struct

rust
struct MadtGicd { /* … */ }

MADT GICD

MadtEntry enum

rust
enum MadtEntry {
    LocalApic,
    InvalidLocalApic,
    IoApic,
    InvalidIoApic,
    IntSrcOverride,
    InvalidIntSrcOverride,
    Gicc,
    InvalidGicc,
    Gicd,
    InvalidGicd,
    Unknown,
}

MADT Entries

MadtIter struct

rust
struct MadtIter { /* … */ }

src/acpi/mod.rs

ACPI

Code to parse the ACPI tables

get_sdt fn

rust
fn get_sdt(sdt_address : usize, mapper : &mut KernelMapper) -> &'static Sdt

GenericAddressStructure struct

rust
struct GenericAddressStructure { /* … */ }

RxsdtEnum enum

rust
enum RxsdtEnum {
    Rsdt,
    Xsdt,
}

init fn

rust
unsafe fn init(already_supplied_rsdp : Option<* const u8>)

Parse the ACPI tables to gather CPU, interrupt, and timer information

SdtSignature type

rust
pub type SdtSignature =(String, [u8; 6], [u8; 8]);

find_sdt fn

rust
fn find_sdt(name : &str) -> Vec<&'static Sdt>

get_sdt_signature fn

rust
fn get_sdt_signature(sdt : &'static Sdt) -> SdtSignature

Acpi struct

rust
struct Acpi { /* … */ }

src/externs.rs

memcpy fn

rust
unsafe extern "C" fn memcpy(dest : * mut u8, src : * const u8, len : usize) -> * mut u8

Memcpy

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

rust
unsafe extern "C" fn memmove(dest : * mut u8, src : * const u8, len : usize) -> * mut u8

Memmove

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

rust
unsafe extern "C" fn memset(dest : * mut u8, byte : i32, len : usize) -> * mut u8

Memset

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

rust
unsafe extern "C" fn memcmp(s1 : * const u8, s2 : * const u8, len : usize) -> i32

Memcmp

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

rust
enum CpuState {
    Idle = 0,
    Kernel = 1,
    User = 2,
}

Current state of a CPU

CpuStats struct

rust
struct CpuStats { /* … */ }

Statistics for the CPUs.

CpuStatsData struct

rust
struct CpuStatsData { /* … */ }

CpuStats::set_state fn

rust
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

rust
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

rust
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

rust
fn add_context_switch()

Add a context switch to the count.

get_context_switch_count fn

rust
fn get_context_switch_count() -> u64

Get the number of context switches.

add_context fn

rust
fn add_context()

Add a context creation to the count.

get_contexts_count fn

rust
fn get_contexts_count() -> u64

Get the number of contexts created.

irq_counts fn

rust
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

rust
struct EventQueue { /* … */ }

EventQueueList type

rust
pub type EventQueueList = HashMap<EventQueueId, Arc<EventQueue>>;

next_queue_id fn

rust
fn next_queue_id() -> EventQueueId

Get next queue id

queues fn

rust
fn queues() -> RwLockReadGuard<'static, EventQueueList>

Get the event queues list, const

queues_mut fn

rust
fn queues_mut() -> RwLockWriteGuard<'static, EventQueueList>

Get the event queues list, mutable

RegKey struct

rust
struct RegKey { /* … */ }

QueueKey struct

rust
struct QueueKey { /* … */ }

registry_mut fn

rust
fn registry_mut() -> RwLockWriteGuard<'static, Registry>

Get the global schemes list, mutable

register fn

rust
fn register(reg_key : RegKey, queue_key : QueueKey, flags : EventFlags)

sync fn

rust
fn sync(reg_key : RegKey) -> Result<EventFlags>

unregister_file fn

rust
fn unregister_file(scheme : SchemeId, number : usize)

trigger fn

rust
fn trigger(scheme : SchemeId, number : usize, flags : EventFlags)

src/cpu_set.rs

LogicalCpuId struct

rust
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

rust
const MAX_CPU_COUNT : u32

MAX_CPU_COUNT const

rust
const MAX_CPU_COUNT : u32

LogicalCpuSet struct

rust
struct LogicalCpuSet { /* … */ }

RawMask type

rust
pub type RawMask = [usize; SET_WORDS];

mask_as_bytes fn

rust
fn mask_as_bytes(mask : &RawMask) -> &[u8]

src/emergency/evac.rs

Evacuate evictable process pages to the emergency disk store.

evacuate_all fn

rust
fn evacuate_all() -> usize

restore_survivors fn

rust
fn restore_survivors(killed_pids : &[usize]) -> usize

discard_killed fn

rust
fn discard_killed(killed_pids : &[usize])

src/emergency/input.rs

Lock-free keyboard input ring for the emergency picker.

push_irq fn

rust
fn push_irq(byte : u8)

Push a byte from an IRQ handler (keyboard / serio / debug).

poll fn

rust
fn poll() -> Option<u8>

Poll one byte, non-blocking.

clear fn

rust
fn clear()

src/emergency/snapshot.rs

Static process snapshot for the emergency picker.

MAX_SNAPSHOT_ENTRIES const

rust
const MAX_SNAPSHOT_ENTRIES : usize

SnapshotEntry struct

rust
struct SnapshotEntry { /* … */ }

Snapshot struct

rust
struct Snapshot { /* … */ }

src/emergency/store.rs

Boot-time emergency disk store layout and block I/O hooks.

STORE_MAGIC const

rust
const STORE_MAGIC : u32

STORE_VERSION const

rust
const STORE_VERSION : u32

MAX_STORE_CONTEXTS const

rust
const MAX_STORE_CONTEXTS : usize

HEADER_SIZE const

rust
const HEADER_SIZE : usize

StoreHeader struct

rust
struct StoreHeader { /* … */ }

SlotEntry struct

rust
struct SlotEntry { /* … */ }

register_block_io fn

rust
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

rust
fn init_from_boot(total_override : Option<usize>)

Initialize metadata for a store sized to hold all physical pages.

is_ready fn

rust
fn is_ready() -> bool

total_page_slots fn

rust
fn total_page_slots() -> usize

write_page fn

rust
fn write_page(slot_index : usize, data : &[u8; PAGE_SIZE]) -> Result<(),()>

read_page fn

rust
fn read_page(slot_index : usize, data : &mut [u8; PAGE_SIZE]) -> Result<(),()>

mark_slot_killed fn

rust
fn mark_slot_killed(pid : u32)

slot_flags_unused fn

rust
fn slot_flags_unused() -> u32

slot_flags_active fn

rust
fn slot_flags_active() -> u32

slot_flags_killed fn

rust
fn slot_flags_killed() -> u32

src/emergency/picker.rs

Kernel emergency process picker (framebuffer text or serial).

PickerAction enum

rust
enum PickerAction {
    Kill,
}

run fn

rust
fn run(snapshot : &mut Snapshot) -> PickerAction

String struct

rust
struct String { /* … */ }

notify_entering_picker fn

rust
fn notify_entering_picker()

src/emergency/mod.rs

Humane memory emergency orchestration.

register_oom_daemon fn

rust
fn register_oom_daemon(pid : usize)

Register a userspace OOM daemon to notify when RAM has been freed by evacuation.

enter fn

rust
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

rust
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

rust
unsafe fn stack_trace()

Get a stack trace

symbol_trace fn

rust
unsafe fn symbol_trace(addr : usize)

Get a symbol

src/percpu.rs

PercpuBlock struct

rust
struct PercpuBlock { /* … */ }

The percpu block, that stored all percpu variables.

init_tlb_shootdown fn

rust
unsafe fn init_tlb_shootdown(id : LogicalCpuId, block : * mut PercpuBlock)

get_all_stats fn

rust
fn get_all_stats() -> Vec<(LogicalCpuId, CpuStatsData)>

shootdown_tlb_ipi fn

rust
fn shootdown_tlb_ipi(_target : Option<LogicalCpuId>)

shootdown_tlb_ipi fn

rust
fn shootdown_tlb_ipi(target : Option<LogicalCpuId>)

switch_arch_hook fn

rust
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

rust
struct SessionData { /* … */ }

SessionData::set_breakpoint fn

rust
fn set_breakpoint(&mut self, flags : Option<PtraceFlags>)

Override the breakpoint for the specified tracee. Pass None to clear breakpoint.

SessionData::is_reached fn

rust
fn is_reached(&self) -> bool

Returns true if the breakpoint is reached, or if there isn't a breakpoint

SessionData::session_fevent_flags fn

rust
fn session_fevent_flags(&self) -> EventFlags

Used for getting the flags in fevent

SessionData::recv_events fn

rust
fn recv_events(&mut self, out : &mut [PtraceEvent]) -> usize

Poll events, return the amount read. This drains events from the queue.

Session struct

rust
struct Session { /* … */ }

close_session fn

rust
fn close_session(session : &Session)

Remove the session from the list of open sessions and notify any waiting processes

close_tracee fn

rust
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

rust
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

rust
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

rust
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

rust
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.

Released under the AWFixer Source Available License v0.4. #linuswasright