The Pedigree Project
0.1
|
Pedigree offers a native API alongside the more-portable POSIX API. While the POSIX API facilitates writing portable software, it is also a heavy abstraction over the core Pedigree functionality. The native API is able to avoid many of the compromises that this abstraction forces.
The native API consists exclusively of C++ objects that can be instantiated by applications. Method calls on these instances automatically handle calling into the kernel if that is necessary.
The main set of operations that become simpler when using the native API rather than the POSIX API include, but are not limited to, the following:
Each application class in the native API has a globally unique identifier. When the class is instantiated, the new instance is registered with the kernel using this identifier. The kernel allocates resources for the request and maps the new instance to the kernel instance. This allows for state to be kept both in the kernel and in the application, as needed.
Objects are automatically unregistered when they are destroyed. This allows for the use of RAII by applications to ensure resources are cleaned up when the application is finished with them.
System calls are made when needed by the application class. These consist of a method ID which is specific to the class, and a parameter block. It is recommended that the parameter block always contain a version field so that past revisions of the parameter block can be handled properly. The kernel class implements a syscall() method that receives the method ID and the parameter block and determines what to do as a result.
A object is provided for all native calls which allows for rich metadata about the result of a call to be provided. This is especially useful for allowing the kernel to report exceptions to be raised by the application class. Indeed, all errors should be reported using C++ exceptions rather than integral statuses.
The process for adding a new API to the native API is reasonably simple.
First, define a global unique identifier in nativeSyscallNumbers.h.
Having created this identifier, create the kernel and application classes. The kernel class should inherit from NativeBase
, and the application class should inherit from Object
. Override Object::guid
on the application class.
Add the creation of an instance of the kernel class to NativeSyscallManager::factory
Override NativeBase::syscall
on the kernel class. It is acceptable to initially write a stub which always returns 'unsuccessful'.
Implement functionality in the application and kernel classes as needed.
The following are a list of general API categories in which most APIs fit.
...