I've decided to detail my adventures in building my own kernel here. First I should detail why, and the answer is two fold: 1 - I'm sick of the "source only no binary" approach in Linux, and 2 - it's a fun way of learning how this stuff works. Looking at Linux, it strikes me it's success is not so much in the amount of innovation, but the amount of functionality. The Linux kernel can do just about anything you need it to, scale how you need it to, even slice fries and juice fruit. Now, there is a lot of innovation going on now, but it's more coming out of commercial code dumps and work from the likes of Sun, SGI, and IBM.
My own kernel finally passed the huge milestone of having the full boot process and transition completed. That means at this point, the kernel loads itself, relocates to a good place in virtual address space, sets up the segment descriptor tables, and enables paging. Further, there is a full boot loader I'm using now that is tried and tested and works. Getting this to work involved a bit of pain and work with AS, and GCC. Now that I have that I'm working on the memory management subsystem, and ELF relocating/loading. The basic design is something that I might call a true "hybrid-kernel". The same service/driver can be implemented in user space or kernel space depending on need. To keep things simple, there will be a select few types of kernel space driver types. The intention is that if you REALLY need it, you can write a kernel mode portions of a user space service driver. The vast majority of user space services will use an L4 type approach. Only things that deal directly with hardware will be allowed in pure kernel space.
Unlike Unix/Plan 9, I'm taking the approach that instead of everything is a file, everything is a service, including files. Services are opened via the kernel. A user space program asks the kernel for a service using a URI, and the kernel then brokers the request to the proper device driver/service manager/etc... Every request has associated with it a context that is given to both the broker and the service. Once the service is opened, the user can contact the kernel to look up capabilities (or RPCs), and then send requests to the service (like ioctls). At this point, even files are services, and modifying the context can change how they are opened and accessed.
So, kernel drivers are implemented as services, and the kernel predefines operations that certain services are required to have.
16 hours ago