Kore ABI
Clock, boot and status pages
The read-only pages every task can read without a call: the published clock, the founding record, execution advice and processor status.
Source: clock.rsRead without asking
Some facts every task needs constantly: the time, what booted, where it is running. Kore publishes them on read-only pages the task maps at founding, so reading them costs no system call and confers no authority. The kernel writes them; a task can't.
The clock page
ClockPage is 64 bytes (CLOCK_PAGE_ABI = 1): a sequence counter, the ABI stamp, flags, the counter frequency, the boot epoch in ticks, the boot time as Unix nanoseconds, and a multiplier and shift for converting ticks to nanoseconds. With CLOCK_FLAG_USER_COUNTER set, a task reads time by sampling the CPU's user-mode counter (RDTSC, CNTVCT_EL0 or RISC-V's time CSR) and projecting it through the page under the sequence lock.
Monotonic time (Uptime) and wall time (UnixTime) are distinct types and never convert implicitly. Every session's return word also carries the kernel's monotonic clock in milliseconds.
Reading time is ambient; controlling timers is not. A wait folds a deadline into a park (SleepReq), and physical timer control needs a Timer capability. Timeout encodes a timeout submission (after a duration, or at a monotonic or wall instant), and SetWallClock disciplines the wall-clock anchor. Timer errors say why: Unsupported, Unconfigured, Uncalibrated, WrongCpu, ControllerUnavailable or OutOfRange.
Execution advice
Each task has one kernel-written ExecutionHint word on the read-only page after its arena alias:
| Bits | Field |
|---|---|
| 0–7 | Current CPU |
| 8–15 | Core class |
| 16–23 | Vector width in bytes: 0, 16, 32 or 64 |
| 24–31, 32–39, 40–47 | log₂ of the L1, L2 and L3 sizes; 0 when unknown |
| 48–55 | Capacity, in sixteenths of the boot CPU's calibrated throughput |
| 56–63 | Version (1) |
Unknown fields are zero, and cache sizes are rounded down to powers of two. ExecutionHint::from_bits refuses a word with the wrong version or out-of-range fields.
It is advice. It may be stale the moment it is read, because the task can migrate, so code must stay correct on every CPU it may run on. It carries no capability and nothing about other tasks, and it grants no instruction-set authority: a wide vector width doesn't permit an instruction the CPU or the task's state doesn't.
Two related surfaces describe the machine. MachineBlock on the boot page carries the logical CPU count, the population of each core class (performance, efficient, standard and low-power), a calibrated SPMD width and whether hardware performance feedback is present. processor_status defines bounded per-CPU snapshots, sampled every 250 ms, served by the monitor service to tools that hold the right capability.
The founding record
FoundingBlock is the boot chain's testimony, kept so a machine whose console scrolled away, or never had one, can still say which services came up and why not. It holds up to 32 rows, each with a name of up to 32 bytes and flags for present, ready, beaconed and refused, plus service-specific readiness bits.
The kernel keeps one ledger and stamps a consistent snapshot into each new task's boot page under a sequence lock, so a task's copy is immutable and needs no retry loop. Services founded after boot update the ledger too. Diagnostics read their own boot page; no service call is involved.
Crash records
CrashRecord is 1024 bytes (magic KORECRSH, version 2): the architecture as its ELF machine number, the fault kind, capture flags, up to 32 registers with a validity bitmap, up to 16 frame-pointer return addresses, 256 bytes of panic text, the task's name and its identity. Missing observations are marked as missing rather than zeroed. See crash reports for the parent-side workflow.