Hi,
mystran wrote:
My current interest is in microkernels. I'd like to build a small kernel with simple IPC system that's fast but practical. And maybe build some OS on top of that.
I've always liked the simple, consistant design of a pure micro-kernel, where as much as possible is a user-level process that can be dynamically loaded/unloaded & replaced. This model has a few practical problems though.
IMHO the physical memory manager, the linear memory manager, the scheduler and code to handle critical errors (exceptions, kernel panic) should be in the kernel for performance/sanity reasons. It's hard to get the first process into it's own address space and spawn a thread for it otherwise. Also I see no benefit of having these things outside the kernel - it's not like you'd be able to replace any of them after boot anyway.
On top of this I've got "kernel modules" which run at cpl=0 in the kernel's part of the address space even though they use their own threads and address spaces. These modules are loaded directly from a boot image during boot and contain the basic functionality needed to get device drivers and things going, as well as providing the OS's security systems. None of them can easily be replaced after boot.
There are only 3 kernel modules. The "Primary User Interface" handles user login & passwords, and provides an interface between other code and user related devices (video, sound, keyboard, mouse, etc). The Primary User Interface uses a "user interface protocol" that is also used by GUIs and applications, so that an application connected to a GUI (e.g. running in a window) uses the same protocol as it would if it was connected directly the the primary user interface (e.g. running full screen). GUIs also use the same protocol to communicate with the Primary User Interface, and it's possible to have GUIs cascaded (where you've got a GUI running in a window of another GUI, running in a window of another GUI, up to 7 levels). If there's 2 keyboards and 2 video cards the Primary User Interface will spawn another thread to handle a second (completely seperate) user. If there's N keyboards and N video cards then you can have N users.
The "Virtual File System" handles file system security, mount/unmount, etc and provides an interface to all files (including a file cache) and any devices (except user related devices - video, sound, keyboard, mouse, etc).
Lastly there's "Device Manager" which handles all hardware resources (IRQs, IO ports, ISA DMA, etc), power management, device auto-detection and loading suitable device drivers. To do this the device manager uses CPL=0 for access to all hardware resources to scan every possible bus, where "bus" includes anything that can have other devices attached to it, except for SCSI controllers, IDE/ATA/ATAPI controllers and floppy controllers. This means that when a device driver is started it's automatically sent a list of resources that have been assigned to it. It also emulates IO ports, so the real IO ports used by a device can be changed without effecting/notifying the device driver (consider hot plug PCI devices and resource conflict resolution).
Everything else is a user-level multi-threaded process, including device drivers, GUIs, applications, etc.
Cheers,
Brendan