Switching between monlithic and micro kernel
Posted: Sat Jan 31, 2009 1:17 pm
Hi all,
I like to share the following design idea. What do you think about it?
It allows switching between a monolithic and a micro kernel architecture at link time. The design is basically the (Remote) Proxy pattern [GHJV p207].
The two figures below demonstrate how it would work:
The micro kernel variant contains two extra parts per module:
Some considerations:
Kasper
I like to share the following design idea. What do you think about it?
It allows switching between a monolithic and a micro kernel architecture at link time. The design is basically the (Remote) Proxy pattern [GHJV p207].
The two figures below demonstrate how it would work:
- ModuleX and ModuleY are what would be specific services in a micro kernel architecture (e.g. memory management, filesystem, or drivers).
- The box Kernel represents other parts of the kernel that communicate with these modules. These parts can be the basic services found in a mirco kernel, other modules, or the api layer.
- Each module is split in an interface IModule* and an implementation Module*Impl. Interaction occurs only via the functions defined in the interface. The implementation part implements these functions.
The micro kernel variant contains two extra parts per module:
- ProxyX and ProxyY implement respectively IModuleX and IModuleY by passing messages to the corresponding message service.
- MessageServiceX and MessageServiceY drive the module implementation by calling functions in the modules' interfaces. Both the proxies and the message services are easy to implement and small.
Some considerations:
- Although I used UML and inheritance to explain the idea, you can easily use C (or some other non-object oriented language). Select some functions which define the interface of a module, make sure that the modules and the kernel interact only via these functions and not via global data, and let the linker replace the function symbols with either the poxy implementation or with the actual implementation.
- The traditional proxy pattern relies on late binding (i.e. virtual methods). If you use C++ and don't like the extra level of indirection, you can use templates or a macro to select the concrete type.
- Separate user level (ring 3) code from privileged (ring 0) code.
- Start to develop a monolithic kernel; once you've implemented message passing and module loading switch to a micro kernel.
- Have the flexibility of a micro kernel during development. When you have a stable set of modules and discover that a monolithic kernel is better for a certain production environment, you can switch to a monolithic kernel.
- Apply the design to a modular kernel--micro kernel combination. The computer administrator can decide which modules should be in kernel space and which ones should be in userspace at module load time.
- What to do with the API that applications use to interact with the OS?
- Do all applications have to be recompiled when the kernel architecture is switched?
- Do you add an extra layer of indirection? (e.g. an int21 function that repacks the parameters and dispatches messages or a message service that calls functions in the monolithic kernel.)
Kasper