KrnAddExceptionHandler()
Synopsis
void * KrnAddExceptionHandler(
uint8_t num,
exhandler_t * handler,
void * handlerData,
void * handlerData2 );
Function
Register a CPU exception handler.
Result
Opaque handler handle, or NULL if registration fails.
Notes
The ctx callback argument is an opaque CPU context handle.
Return a nonzero value from the callback to handle the exception and
continue execution. If every handler returns zero, the exception is
passed to the task's tc_TrapCode handler.
This interface is preliminary and should be treated as private.
KrnAddIRQHandler()
Synopsis
void * KrnAddIRQHandler(
uint32_t irq,
irqhandler_t * handler,
void * handlerData,
void * handlerData2 );
Function
Register a hardware IRQ handler.
Result
Opaque handler handle, or NULL if registration fails.
KrnAllocIRQ()
Synopsis
ULONG KrnAllocIRQ(
ULONG irq_type,
ULONG count );
Function
Allocate a consecutive range of interrupt identifiers.
Result
First allocated interrupt identifier, or (ULONG)-1 on failure.
KrnAllocPages()
Synopsis
void * KrnAllocPages(
void * addr,
uintptr_t length,
uint32_t flags );
Function
Allocate physical memory pages
Result
Real starting address of the allocated region.
Notes
Since this allocator is page-based, length will always be round up
to system's memory page size. The same applies to starting address
(if specified), it will be rounded down to page boundary.
This function works only on systems with MMU support. Without MMU
it will always return NULL.
KrnBacktraceFromFrame()
Synopsis
ULONG KrnBacktraceFromFrame(
APTR frame_in,
APTR * out_pcs,
ULONG max_depth );
Function
Walks the current call stack using frame-pointer chaining and stores
the return addresses into the provided array. The function starts from
the frame pointer value supplied in frame_in and follows the saved
link fields until the maximum depth is reached or the chain becomes
invalid.
This is a low-level helper used to capture a stack backtrace for
diagnostic and crash reporting purposes.
Result
Returns the number of valid entries written into the output array.
Example
APTR pcs[64];
ULONG depth;
depth = KrnBacktraceFromFrame((APTR)__builtin_frame_address(0), pcs, 64);
KrnPrintBacktrace("[Kernel] ", pcs, depth);
Notes
This function relies on standard frame-link conventions and requires
code to be compiled with frame pointers enabled (for GCC or Clang,
use -fno-omit-frame-pointer).
The function performs basic safety checks on the frame chain and stops
if the next frame pointer is invalid, unaligned, or lower than the
previous one. It is safe to call from an exception or trap context.
Bugs
The function may produce incomplete results if compiler optimizations
omit frame pointers, or if stack corruption has occurred prior to the
call.
KrnBug()
Synopsis
int KrnBug(
const char * format,
va_list args );
Function
Output a formatted string to low-level debug output stream.
The function supports the same set of formatting specifiers
as standard C printf() function.
Result
Number of successfully printed characters
KrnCreateContext()
Synopsis
void * KrnCreateContext();
Function
Allocate and initialize CPU context storage area.
Result
A pointer to a CPU context storage area.
Notes
CPU context storage is considered private and accessible
only from within supevisor mode.
KrnDeleteContext()
Synopsis
void KrnDeleteContext(
void * context );
Function
Free CPU context storage area
KrnDispatch()
Synopsis
void KrnDispatch();
Function
Run the next available task
Notes
This entry point directly calls task dispatch routine in supervisor mode.
It neither performs any checks of caller status nor obeys interrupt enable
state. After calling this function, caller's task will be replaced by
another one, and caller's state will be lost.
This function is safe to call only from within user mode.
This function is considered internal, and not meant to be called
by user's software.
KrnDisplayAlert()
Synopsis
void KrnDisplayAlert(
uint32_t code,
const char * text );
Function
Inform the user about critical system failure.
Result
None. This function is not guaranteed to return.
Notes
This function exists for system internal purposes. Please do not
call it from within regular applications! In 99% of cases this function
will halt or reboot the machine. Certain structures in RAM, as well as
video hardware state, will be irreversibly destroyed.
'code' parameter is passed for convenience. Based on it, the system
can make a decision to log the alert in debug output and continue,
instead of displaying a message and halting.
This function is currently experimental. Its definition may change.
KrnExitInterrupt()
Synopsis
void KrnExitInterrupt(
APTR ctx );
Function
Leave an interrupt using an architecture-defined saved context.
Notes
The architecture-specific implementation owns context restoration.
The generic fallback performs no operation.
KrnFmtAlertInfo()
Synopsis
void KrnFmtAlertInfo(
STRPTR * TemplatePtr,
IPTR * ParamPtr );
Function
Supply architecture-specific details for an alert message.
Notes
The generic implementation leaves both outputs unchanged.
The all-pc implementation may replace the template and two
parameter entries when an interrupt context is available.
ParamPtr must provide space for at least two IPTR values.
KrnFreeIRQ()
Synopsis
void KrnFreeIRQ(
ULONG start,
ULONG count );
Function
Release a range of interrupt identifiers allocated by KrnAllocIRQ().
Notes
Release support depends on the target.
KrnFreePages()
Synopsis
void KrnFreePages(
void * addr,
uintptr_t length );
Function
Release a region allocated by KrnAllocPages().
Notes
This function works only on systems with MMU support.
KrnGetCPUAttr()
Synopsis
intptr_t KrnGetCPUAttr(
uint32_t id,
uint32_t cpu );
Function
Get the value of a per-CPU attribute, for the given CPU.
Currently defined attributes are:
KATTR_CPULoad [.G] (ULONG) - Load of the CPU, 0 - 0xffffffff.
KATTR_CPUFrequencyKHz [.G] (IPTR) - Current core clock, in kHz.
Result
Value of the attribute, or -1 when the attribute (or the CPU) is
not known.
Notes
This supersedes querying KrnGetSystemAttr() with the
KATTR_CPULoad + n attribute range, which cannot scale beyond the
range's size.
KrnGetSystemAttr()
Synopsis
intptr_t KrnGetSystemAttr(
uint32_t id );
Function
Get value of internal system attributes.
Currently defined attributes are:
KATTR_Architecture [.G] (char *) - Name of architecture the kernel built for.
KATTR_ClockSource [.G] APTR - Used Time Source Resource, or -1 if not set.
KATTR_SystemLoad [.G]
KATTR_CPULoad [.G] - Base of the legacy per-CPU load
attribute range. Add the CPU index;
KATTR_CPULoad_END is exclusive.
KATTR_AffinityMask [.G]
KATTR_PeripheralBase [.G] IPTR - (ARM only) peripheral IO Base address.
Result
Value of the attribute
KrnIsSuper()
Synopsis
int KrnIsSuper();
Function
Determine if the caller is running in supervisor mode
Result
Nonzero for supervisor mode, zero for user mode
Notes
Callers should only test the return value against zero.
Nonzero values may actually be different, since they
may carry some private implementation-dependent information
(like CPU privilege level, for example).
KrnMapGlobal()
Synopsis
int KrnMapGlobal(
void * virt,
void * phys,
uint32_t length,
KRN_MapAttr flags );
Function
Map a physical memory region into the virtual address space.
Result
Port specific. On x86_64, 0 on success and -1 on failure; on aarch64
and riscv64, 0 on failure and a non-zero value on success. Callers
that work across ports must not assume either; see BUGS.
Notes
The range is rounded out to whole pages, and virt and phys must
agree below the page size (4 KiB on most ports). Mapping over an
existing mapping replaces it.
On x86_64 the local TLB is reloaded before the call returns and the
other CPUs are asked to reload theirs. That request is asynchronous
when the caller is inside Disable(), or when it was already in
supervisor state, so on that path the other CPUs' TLBs are not
updated before the call returns - the shootdown completes later.
On x86_64 page tables created by the call, including the 4 KiB table
made when part of a 2 MiB mapping is replaced, are never freed: the
cost is bounded at one table per 2 MiB region ever split.
On x86_64 a call that fails partway leaves the part of the range it
had already processed mapped.
On architectures without an MMU, or where this is not implemented,
the call does nothing and returns 0.
Bugs
The return value convention is not consistent across ports: x86_64
returns 0 on success, aarch64 and riscv64 return non-zero on success.
A caller written for one convention misreads the other. Reconciling
the ports is a separate change; until then, check the port you are
building for.
KrnModifyIRQA()
Synopsis
ULONG KrnModifyIRQA(
ULONG irq,
struct TagItem * attribs );
ULONG KrnModifyIRQ(
ULONG irq,
TAG tag, ... );
Function
Configure platform-specific attributes of an interrupt source.
KrnModifyIRQHandler()
Synopsis
void KrnModifyIRQHandler(
void * handle,
void * handlerData,
void * handlerData2 );
Function
Update the arguments passed to a registered IRQ handler.
KrnPrintBacktrace()
Synopsis
void KrnPrintBacktrace(
const STRPTR prefix,
APTR * pcs,
ULONG depth );
Function
Prints a formatted stack backtrace to the kernel debug output. Each
entry in the provided address list is optionally resolved to a module
and symbol name using the currently registered symbol resolver (if any).
The output includes one line per program counter, showing the address
and, when available, the function or symbol name with offset.
Example
APTR pcs[64];
ULONG depth = KrnBacktraceFromFrame((APTR)__builtin_frame_address(0), pcs, 64);
KrnPrintBacktrace("[Crash] ", pcs, depth);
Notes
The function relies on an optional symbol resolver that can be
registered with KrnRegisterSymResolver(). If no resolver is present,
only raw addresses are printed.
This function is safe to call from exception and trap context.
KrnRegisterClockSource()
Synopsis
void KrnRegisterClockSource(
APTR CSBase,
struct TagItem * tstags );
void KrnRegisterClockSourceTags(
APTR CSBase,
TAG tag, ... );
Function
Select a clock source for the kernel when none is registered.
Notes
A NULL CSBase or an existing clock source leaves the selection
unchanged. Registration also requires AllocCSUnit() to succeed.
KrnRegisterSymResolver()
Synopsis
LONG KrnRegisterSymResolver(
KrnSymResolver_t resolver,
APTR priv );
Function
Registers a global kernel symbol resolver callback used for decoding
instruction addresses into symbolic names.
The resolver is used by the kernel when printing diagnostic backtraces
or exception dumps. Only one resolver can be active at any time. The
function fails if a resolver is already registered.
Result
Returns 0 on success, or a negative value on error:
-1 resolver argument was NULL
-2 a resolver is already registered
Example
static LONG MyResolver(APTR addr, struct KrnSymResolve *out, APTR priv)
{
return DecodeLocationA(addr, priv);
}
if (KrnRegisterSymResolver(MyResolver, DebugBase) == 0)
KrnBug("Symbol resolver registered.\n");
Notes
This API allows an external component (typically debug.library) to
provide symbol resolution for kernel stack traces. Once registered,
the resolver will be used automatically by KrnPrintBacktrace() and
the kernel crash handler.
The function is safe to call from user or supervisor context.
Bugs
Only one resolver can be registered globally. There is currently no
queuing or stacking mechanism.
KrnScheduleCPU()
Synopsis
void KrnScheduleCPU(
void * cpu_mask );
Function
Run task scheduling sequence on all CPUs given in the cpu_mask
Notes
This entry point directly calls task scheduling routine
in supervisor mode. It neither performs any checks of caller status
nor obeys interrupt enable state.
This function is safe to call only from within user mode.
This function is considered internal, and not meant to be called
by user's software.
KrnSetProtection()
Synopsis
void KrnSetProtection(
void * address,
uint32_t length,
KRN_MapAttr flags );
Function
Set the access permissions of a memory region.
KrnSpinLock()
Synopsis
spinlock_t * KrnSpinLock(
spinlock_t * lock,
struct Hook * failhook,
ULONG mode );
Function
Acquire a spinlock in read or write mode, waiting if it is
held on supported architectures.
Result
The supplied spinlock pointer.
Notes
The all-pc implementation invokes failhook while waiting for a
contended lock. ARM implementations do not invoke it.
The generic fallback returns lock without acquiring it.
KrnSpinTryLock()
Synopsis
spinlock_t * KrnSpinTryLock(
spinlock_t * lock,
ULONG mode );
Function
Attempt to acquire a spinlock in read or write mode without
waiting for a current lock holder to release it.
Result
Lock pointer if acquired; NULL if the requested mode cannot
be obtained on an implementation with spinlock support.
Notes
The generic fallback returns lock without acquiring it.
The implementation and availability are architecture-specific.
KrnStatMemoryA()
Synopsis
ULONG KrnStatMemoryA(
ULONG flags,
struct TagItem * query );
ULONG KrnStatMemory(
ULONG flags,
TAG tag, ... );
Function
Get various statistics about memory usage
Result
TRUE if the function worked, FALSE if MMU is not up and running on the system.
If the function returns FALSE, values will stay uninitialized.
Notes
For all unknown tag IDs result values will be set to 0.
KrnSwitch()
Synopsis
void KrnSwitch();
Function
Save context of caller's task and dispatch the next available task
Notes
This entry point directly calls task switch routine
in supervisor mode. It neither performs any checks of caller status
nor obeys interrupt enable state. After calling this function, caller's
task will be replaced by another one, and it's caller's responsibility
to do anything to prevent task loss.
This function is safe to call only from within user mode.
This function is considered internal, and not meant to be called
by user's software.
KrnUnmapGlobal()
Synopsis
int KrnUnmapGlobal(
void * virt,
uint32_t length );
Function
Unmap a region of virtual address space.
Result
Port specific. On x86_64, 0 on success and -1 on failure; on aarch64
and riscv64, 0 on failure and a non-zero value on success. Callers
that work across ports must not assume either; see KrnMapGlobal().
Notes
The range is rounded out to whole pages; accessing it afterwards
faults. Parts of the range that are not mapped are skipped.
On x86_64 the local TLB is reloaded before the call returns and the
other CPUs are asked to reload theirs. That request is asynchronous
when the caller is inside Disable(), or when it was already in
supervisor state, so on that path the other CPUs' TLBs are not
updated before the call returns - the shootdown completes later.
A 2 MiB mapping that is only partly unmapped is split into 4 KiB
pages first; the page table this creates is not freed. A call that
fails partway leaves the part of the range it had already processed
unmapped.
On architectures without an MMU, or where this is not implemented,
the call does nothing and returns 0.
KrnUnregisterSymResolver()
Synopsis
LONG KrnUnregisterSymResolver(
KrnSymResolver_t resolver );
Function
Unregisters the previously installed kernel symbol resolver callback.
The resolver function is used by the kernel to translate instruction
addresses into module and symbol information when printing diagnostic
or crash reports. Only one resolver can be active at a time.
Result
0 if resolver matches the stored callback; -1 otherwise.
Example
if (old_resolver && KrnUnregisterSymResolver(old_resolver) == 0)
KrnBug("Symbol resolver removed.\n");
Notes
The resolver is typically implemented by debug.library and used by the
kernel to produce symbolic backtraces when handling traps or exceptions.
The function performs no locking and is safe to call from within the
resolver itself, or from kernel exception context.
KrnVirtualToPhysical()
Synopsis
void * KrnVirtualToPhysical(
void * virtual );
Function
Translate a virtual address to a physical address.
Result
Translated address, or the original address when the target's
translation rules leave it unchanged.