An hybrid OS design for higher performances

Discussions on more advanced topics such as monolithic vs micro-kernels, transactional memory models, and paging vs segmentation should go here. Use this forum to expand and improve the wiki!
AbstractYouShudNow
Member
Member
Posts: 92
Joined: Tue Aug 14, 2012 8:51 am

An hybrid OS design for higher performances

Post by AbstractYouShudNow »

There are actually several kernel designs (models) such as Microkernel, Exokernel, Modular Kernel, Monolithic Kernel...

However, each has it's own advantages and pitfalls. The idea is to create an OS mixing many models to take advantage of all benefits, while being careful enough not to inherit the pitfalls.

The main kernel would be a block, with a table indexing available functions, and a system that identifies the functions and returns their effective addresses (similar to the hardware interrupts). Then, it would be possible to add blocks to the core kernel, registering their functions, so they can be accessed easily. This is the Modular part of the thing. However, contrarily to modular kernels, kernel modules would be added by the kernel itself or the system configuration, not the user directly. The idea is to load only what we need of the kernel.

For system calls, an application would have a number of unresolved symbols. When the system loads the executable, it matches the unresolved functions to known function names, and maps them in the process' address space, filling the hole with the mapped address of the functions. This is what I call ghost symbols. Then, we could also add kernel modules that provide new functions, for implementing new functionnalities. Finally, those API's that can be implemented in user-space should be implemented this way, pretty like Windows DLLs.

With such a system, the booting is quite difficult. My approach is to load, from the reserved sectors of a disk, a minimal system that would understand some common filesystems. It would then be able to load the kernel, and setup the environment.

I think this kernel design is secure as applications don't really access the kernel, so it is not really possible to corrupt it's code.
But the real fact of that system is that it could load the ghost functions from anything. I thought of making a module for each domain (e.g. a module for Windowing, a module for Printing, a module for Networking...). This system would be extremely easy to update, as the core functionnalities are implemented in independant modules, and the core kernel would not have to be changed that often. My drivers would be implemented as special kernel modules that would run in kernel mode. But as the API's using these drivers are loaded in the kernel, a direct communication is possible.
The only request on executables is that they allow unresolved symbols.

The kernel would then be a central processor. When an application needs a service, it calls upon the kernel using ghost function calls, which in turn call the drivers which actually do the thing. This delegation allows a high level of security as nobody even knows how the kernel does the things.

Concretely, we would have a Kernel process and application processes. How about it ?

PS: I have alreay started to implement it, but have not yet come to a point where it is possible to run it ;)
Congdm
Member
Member
Posts: 48
Joined: Wed Aug 01, 2012 10:53 am

Re: An hybrid OS design for higher performances

Post by Congdm »

Nice idea! But it sounds so much like Windows NT architecture (except for ghost functions), am I wrong?

My design is also modular like your, but I sacrifice protection so application can access hardware directly. There are no kernel or userspace, everything run in ring 0, so it can become chaotic easily if I am not careful (the pain of not having protection) :cry:

But a system is not only APIs, how about threading, multi instances module, hardware resources conflict between modules, multiple modules implement same interface but running concurrently?
Last edited by Congdm on Tue Aug 14, 2012 10:01 am, edited 1 time in total.
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: An hybrid OS design for higher performances

Post by bluemoon »

AbstractYouShudNow wrote:However, contrarily to modular kernels, kernel modules would be added by the kernel itself or the system configuration, not the user directly. The idea is to load only what we need of the kernel.
This has nothing to do with the kernel model, but merely administration policy.

AbstractYouShudNow wrote: For system calls, an application would have a number of unresolved symbols. When the system loads the executable, it matches the unresolved functions to known function names, and maps them in the process' address space, filling the hole with the mapped address of the functions. This is what I call ghost symbols.
A more familiar name would be dynamic linking?
AbstractYouShudNow wrote:Then, we could also add kernel modules that provide new functions, for implementing new functionnalities. Finally, those API's that can be implemented in user-space should be implemented this way, pretty like Windows DLLs.
Again, you just described how modules are loaded and chained, but this still has nothing to to with kernel model.
AbstractYouShudNow wrote:With such a system, the booting is quite difficult. My approach is to load, from the reserved sectors of a disk, a minimal system that would understand some common filesystems. It would then be able to load the kernel, and setup the environment.
Most people do this by static link (or load pre-defined modules by boot loader) which understand a minimum set of device (eg ramdisk and ramdiskfs, or tarball reader),
then call those module to detect/initialize the real storage.
Congdm
Member
Member
Posts: 48
Joined: Wed Aug 01, 2012 10:53 am

Re: An hybrid OS design for higher performances

Post by Congdm »

bluemoon wrote:Again, you just described how modules are loaded and chained, but this still has nothing to to with kernel model.
From my understanding, his model is same as hybrid model of Windows NT.
User avatar
Jezze
Member
Member
Posts: 395
Joined: Thu Jul 26, 2007 1:53 am
Libera.chat IRC: jfu
Contact:

Re: An hybrid OS design for higher performances

Post by Jezze »

Applications wont talk to the kernel? Please elaborate.
Fudge - Simplicity, clarity and speed.
http://github.com/Jezze/fudge/
User avatar
piranha
Member
Member
Posts: 1391
Joined: Thu Dec 21, 2006 7:42 pm
Location: Unknown. Momentum is pretty certain, however.
Contact:

Re: An hybrid OS design for higher performances

Post by piranha »

I think this kernel design is secure as applications don't really access the kernel, so it is not really possible to corrupt it's code.
For system calls, an application would have a number of unresolved symbols. When the system loads the executable, it matches the unresolved functions to known function names, and maps them in the process' address space, filling the hole with the mapped address of the functions
user-space
These three ideas are fundamentally conflicting. The first one conflicts with the second one directly: to call a function that the kernel would dynamically link, the kernel is being "accessed". Each call to the kernel counts as an access to the kernel. The second and third conflict as well. If your application is running in user mode (ring 3) then any call to the kernel that doesn't switch back to ring 0 would result in a GPF. And to switch rings you need to perform a real system call, so why not just do that then? Unless of course you meant that the process will be running in ring 0. If this is the case, then why is it "not really possible to corrupt [the kernel's] code" (quote 1)? If its ring 0, then is could just wipe out the entire section of memory. Unless you decide to use memory protection to section off the kernel, but then the application cant perform said kernel calls as you specified!

Taking the best parts of each architecture/design is a good idea. But there are certain things that need to be worked out.

-JL
SeaOS: Adding VT-x, networking, and ARM support
dbittman on IRC, @danielbittman on twitter
https://dbittman.github.io
User avatar
turdus
Member
Member
Posts: 496
Joined: Tue Feb 08, 2011 1:58 pm

Re: An hybrid OS design for higher performances

Post by turdus »

AbstractYouShudNow wrote:With such a system, the booting is quite difficult. My approach is to load, from the reserved sectors of a disk, a minimal system that would understand some common filesystems. It would then be able to load the kernel, and setup the environment.
How does it differ from standard 2 stage model? Stage1: small, placed on a reserved sector, Stage2: little bigger with fs knowledge to load the kernel...
I think this kernel design is secure ...
it could load the ghost functions from anything.
Any function can be injected from any source? How secure is that?
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: An hybrid OS design for higher performances

Post by gerryg400 »

You think of your kernel as a set of functions, and if that were true your idea might work.

But really a kernel is a set of 'data' and the system calls are methods to manipulate the data. How will you ensure that the 'installed' system calls behave correctly with respect to the concurrency, re-entrancy and locking in your kernel ?
If a trainstation is where trains stop, what is a workstation ?
AbstractYouShudNow
Member
Member
Posts: 92
Joined: Tue Aug 14, 2012 8:51 am

Re: An hybrid OS design for higher performances

Post by AbstractYouShudNow »

But a system is not only APIs, how about threading, multi instances module, hardware resources conflict between modules, multiple modules implement same interface but running concurrently?
The core kernel does the scheduling. It maintains a structure for each application, and an application uses ghost functions to indirectly modify this structure. For example, a ghost function 'CreateThread' would tel the kernel to add a thread.

A module is in fact just a set of functions, so they can't really run concurrently. Else, I thought of a model similar to the famous COM for multiple ones to implement the same interface, so an interface would have an Interface ID (IID) and an implementation would have a Class ID (CLSID).

Modules inside the kernel get the address of system functions using the symbol tables. For example, with a call such as SymbolTable->GetFunction( "CreateThread" ). And the symbol table would have a constant address (or at least, it's address would be shown as being always the same using paging).

Hardware resources will be accessed, in my model, using a locking concept for those that can't be accessed concurrently.
As this is harmful, I am currently designing a model where devices would be treated as regular streams (e.g. have read/write functions etc...) and conccurent accesses would be scheduled by the kernel, so the applications would see it as an asynchronous access.
Nice idea! But it sounds so much like Windows NT architecture (except for ghost functions), am I wrong?
Not really, as Windows NT implements most things in userspace (using it's thousands of DLLs), while I implement them as modules that run in Ring 0. But this is just for fundamental functions. Modules are just parts of the system developped by me, users may not program modules (else, it would be a major security hole).
For interfaces, a class's methods are registered, and then their code is copied in a userspace page, so they can't harm much.
My design is also modular like your, but I sacrifice protection so application can access hardware directly. There are no kernel or userspace, everything run in ring 0, so it can become chaotic easily if I am not careful (the pain of not having protection) :cry:
You must have a very good reason to sacrify security at that point. But I hope that you have memory protection anyways (letting each process having it's own virtual address space, with no access to other process' memory, unless allowed by the kernel). But it could be hard for an application to write directly to the video card instead of just calling 'DrawLine' :cry:
A more familiar name would be dynamic linking?
Not really. Dynamic Linking just has symbols associated with a named library. The code for the functions is then copied to the aplication's virtual space and addresses are substituted.
Ghost Functions are not imported from any library, and are located somewhere in the kernel. When loading the application, the kernel maps the code of these functions (that are in kernel space) to the application's space (in user space) using paging.

When linking to a dynamic library, the linker leaves a note to the loader to load function X from library L and give the loading address. For ghost functions, these symbols are left undefined and the loader resolves them using the kernel's symbol table. It is more an alternative to software interruptions than real dynamic linking, the linker just does not do anything.
The reason for this is simply that it is way faster than dynamic linking (that requires loading a library) or software interruptions (that require traversing a table every call). It also allows the same system code to be loaded only once, while Windows loads the same DLL's several times and wastes memory.

@bluemoon : It's true that many things are more relevant to administration policies. For the boot, I didn't find a better solution.
From my understanding, his model is same as hybrid model of Windows NT.
No, I am not implementing the system functions as thousands of DLLs that decrease disk performance and size, I just use modules and a special form of linking.
IMO Windows NT is more MicroKernel than Modular, and I won't use as much messaging as it does.
Applications wont talk to the kernel? Please elaborate.
Applications don't really talk to the kernel using messaging or interruptions. Instead, they request functions from the kernel, which maps them to their address space. Applications don't talk to the kernel : they access it silently. This way, there can't be a virus that listens to them ;)
Also, the functions from the kernel are in pages that are read-only, so they cannot corrupt it's code.

@piranha : Sorry, by 'don't access the kernel', I just meant that they can't modify it in a hramfl way. They just can read it, and not modify.
If your application is running in user mode (ring 3) then any call to the kernel that doesn't switch back to ring 0 would result in a GPF.
Isn't it possible for a ring 3 process to access a ring 0 page that is read-only ?
That takes me thinking... Would it be possible to have only one system call that switches to the execution of the kernel code ?
I am not using interruptions as they are not the most efficient solution.
But how can Windows applications call the drivers without elevation ? It doesn't look like they are making interruptions.
Any function can be injected from any source? How secure is that?
No, I just mean that any module can provide any function.
You think of your kernel as a set of functions, and if that were true your idea might work.

But really a kernel is a set of 'data' and the system calls are methods to manipulate the data. How will you ensure that the 'installed' system calls behave correctly with respect to the concurrency, re-entrancy and locking in your kernel ?
I will just have locking objects (mutexes, critical sections and all), And my Ghost Functions are not really system calls, they are just an alternative to the functions in Windows DLLs.
AbstractYouShudNow
Member
Member
Posts: 92
Joined: Tue Aug 14, 2012 8:51 am

Re: An hybrid OS design for higher performances

Post by AbstractYouShudNow »

I thought of a thing... I could very well have 2 interfaces !

The first interface would use interruptions that do basic things (as in many other systems). The interruptions, running in ring 0, could call the drivers and low-level things. And my ghost functions would be moved to user-space and just use these interruptions.

I just need one thing. Is there something more efficient than software interruptions ?
User avatar
NickJohnson
Member
Member
Posts: 1249
Joined: Tue Mar 24, 2009 8:11 pm
Location: Sunnyvale, California

Re: An hybrid OS design for higher performances

Post by NickJohnson »

AbstractYouShudNow wrote:I thought of a thing... I could very well have 2 interfaces !

The first interface would use interruptions that do basic things (as in many other systems). The interruptions, running in ring 0, could call the drivers and low-level things. And my ghost functions would be moved to user-space and just use these interruptions.

I just need one thing. Is there something more efficient than software interruptions ?
SYSENTER / SYSEXIT is a much faster way to do a ring 3 / ring 0 switch than software interrupts.

Also, that just sounds like a normal monolithic kernel.
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: An hybrid OS design for higher performances

Post by gerryg400 »

Perhaps you could give an example of a block or module that could be added to the kernel and how it would be installed.
If a trainstation is where trains stop, what is a workstation ?
User avatar
piranha
Member
Member
Posts: 1391
Joined: Thu Dec 21, 2006 7:42 pm
Location: Unknown. Momentum is pretty certain, however.
Contact:

Re: An hybrid OS design for higher performances

Post by piranha »

Isn't it possible for a ring 3 process to access a ring 0 page that is read-only ?
Yes, but you wouldn't be able to do much. Say you need to access the harddrive or map something in memory? You'd need to switch to ring0 somehow (interrupts or sysenter).
They just can read it, and not modify.
Ring 3 processes should not be able to modify the kernel in any system. Thats part of the point of ring 3.

-JL
SeaOS: Adding VT-x, networking, and ARM support
dbittman on IRC, @danielbittman on twitter
https://dbittman.github.io
AbstractYouShudNow
Member
Member
Posts: 92
Joined: Tue Aug 14, 2012 8:51 am

Re: An hybrid OS design for higher performances

Post by AbstractYouShudNow »

My kernel would be in a custom object file format, organised in sections, with every section containing an ELF file. And a module would just be another section in the kernel file. The header of each file block would also contain a checksum of the data in the section, and a digital signature. Thus, installing new modules would just be done for updates, and new modules would simply be appended to the kernel file.

My original model was to have each module in a separate (signed, checksummed) ELF image file but I thought that it would be too risky.
SYSENTER / SYSEXIT is a much faster way to do a ring 3 / ring 0 switch than software interrupts.
How to do SYSENTER/SYSEXIT, please ? Is it available under all x86 architectures ?
Ring 3 processes should not be able to modify the kernel in any system. Thats part of the point of ring 3.
Is it reasonnable to have a function to change priviledge level ? The Operating System would, evidently, evaluate the demand of priviledge based on the current user's priviledge and the destination address (e.g. is it a kernel function ?) and may accept or refuse it.
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: An hybrid OS design for higher performances

Post by bluemoon »

SYSENTER/SYSEXIT/SYSCALL is well documented on processor manual, and their primary usage is to switch privilege level quickly.
But note that this privilege level is not user/root privilege you were talking about.

And no, the OS would not evaluate, but if privilege is not sufficient, an exception is generated.
Locked