The QNX Neutrino RTOS kernel and process manager
(procnto) is designed to be as platform-independent as
possible. Each release provides a procnto version for each
supported hardware architecture (see procnto* in the Utilities
Reference).
The kernel callouts are standalone pieces of code (or code fragments) that the kernel
uses to perform hardware-specific functions. These callouts don't need to be
statically linked to the kernel.
The startup code can include multiple versions of the same kernel callout. For
example, it can include a generic kernel callout as well as kernel callouts that are
specific to an architecture and board. During hardware discovery, the startup can
determine which kernel callout is most appropriate for the current hardware and make
that version of the callout available to the kernel. However, it is simpler and more
efficient to eliminate the discovery process and include only a single version of
each kernel callout in the startup code and have the startup code tell the kernel
which callouts to use.
Note:
Note the following about how kernel callout code is used:
- The startup program copies the kernel callout code from the startup program
into the system
page. When this copy is complete, the memory used for the startup
program is freed up.
- For all but two routines, the kernel uses normal function-calling
conventions to invoke the kernel callouts. For information about these two
exceptions, see interrupt_id_*() and interrupt_eoi_*().
Common characteristics
For information about the different categories of kernel callouts and what they are
used for, see Kernel callout categories in this
chapter.
All kernel callouts share some common characteristcs, including:
- Assembly code
-
Kernel callouts are written in assembly because:
- They must be position-independent (see Interrupt controller below).
- There is no portable method for controlling preamble and postamble
creation, or code generation; a change to an Application binary
interface (ABI) or build configuration problem might create a latent
bug in code that isn't fully self-contained and position
independent.
- Position independent code (PIC)
- Position independence is required because kernel callouts are provided in
the startup code, which is overwritten when the kernel starts up.
- To keep the kernel callouts after the kernel has started, the startup
library copies them to a location where they won't be overwritten when the
kernel starts. Since after this copy the kernel callouts are in a location
other than the one where they were loaded, they must be written to be
position-independent. This position independence requires that they be
written in assembly.
- In-line in kernel source
- Kernel callouts are copied in-line to the kernel code and don't use the C
language return keyword. However, they can provide the kernel with
information in CPU registers.
- Interrupt ID and EOI
- The interrupt ID and EOI used for kernel callouts are specific to kernel
callouts.
- No static read/write storage
- Kernel callouts can't specify any static read/write storage space for
themselves. However, you can allocate a small amount of storage space in the
system page for a specific kernel callout.
Passing data to and from kernel callouts
The kernel uses the SoC's Application Binary Interface (ABI) to pass data to and get
data from kernel callouts. You should become familiar with the ABI documentation for
your board before you attempt to write kernel callouts for the board.
In many cases, the kernel puts inputs to kernel callouts in general purpose
registers. You can also use INTR_GENFLAG_* flags to have the kernel
pass in additional input values. These and other flags are in the
intrinfo structure that is set up by the init_intrinfo() function.
Similarly, you may need to have kernel callouts place their output into
registers.
Note: QNX kernel callout source code usually has comments right in the source code files
that provide details about which registers to use for kernel callout input and
output. If these comments are absent or unclear, refer to the ABI documentation for
your board.