The code composing xlib is organized in three different layers: the fist layer, containing the boot code and the hardware structures access code, must be linked by any application using OSLib to run in Protect Mode. If a simple application is not concerned with multiprogramming and uses its own code to manage hardware interrupts and exceptions, it has not to link any other code. The xlib is organized so that all the other unused code is not linked. The programming interface provided by the boot code and the hardware structures access code is very raw and difficult to use, so a second layer provides a more usable programming interface (comprehensive of some assembler stubs that make interrupt management easy), together with the code for accessing the hardware context switch mechanism. Although the CPU identification code resides in this layer, it can be linked (independently from the rest of the layer) by applications that use only the first layer. The third layer, that only some particular applications need to link, is composed of the VM86 and RM code, and also provides the functionalities to access an MSDOS filesystem. In general, most of the applications using xlib does not need this layer, and only links the first two.
An exception is represented by the cprintf function, that has the same syntax of the standard printf function (not provided by OSLib) and can be used to outptut informations on the screen. Being OS dependent, an output function should not be implemented in this library, but since all the applications or OS kernels need to perform some output (at least for diagnostic purpose), we decided to provide cprintf (console printf). It is similar to the printf function, but it does not perform any buffering, and since it directly writes on the screen it cannot be redirected. In order to work in the xlib framework, cprintf assumes a ``flat'' memory model, with a single data segment that covers all the physical memory from address 0.
Exceptions are handled through a standard routine that displays the exception number, some debug informations, and aborts the program in a clean way (without crashing the system); user defined exception handlers can be set to recover from some hardware exceptions without aborting the program.
Hardware interrupts are mapped in events, that can be handled by user-defined routines (callbacks). A generic event-handler routine can be called with interrupts disabled, or enabled (in order to develop full preemptive kernels).
The multithreading code uses the context switch functions provided by xlib to implement thread objects. In particular, functions to create, terminate and schedule threads are provided. Moreover, a function to associate a new address space to a thread enables programs using kl to create task objects.
For what concerns time management, kl hides PIC programming to the user programs. In particular, the time management code programs two internal PC counters to provide functions for reading the time elapsed from the kl initialization, and to permit to program time events. A time event is an event that will invoke an user defined handler at a specified time.
Last but not least, kl permits to create address spaces and bind physical memory to them. An address space is a portion of logical memory in which one or more threads can execute and share data. Each address space is linear and can overlap or not with other address spaces. A flat address space, mapping all the physical memory 1->1 (and hence having the visibility of any other address space) is provided as a default (and is assumed by the cprintf function).