A layer between the OS(kernel only) and the CPU

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!
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

A layer between the OS(kernel only) and the CPU

Post by earlz »

Well, I was thinking about how to make an OS more portable, and well....most parts of an OS just can't be made portable(even with a layer) but the actual OS kernel possibly could..

I really don't have much knowledge with many other Archs, but anyway...
really, I think some assumptions should be made, such as an MMU is present

But basically make something to seperate things like task switching, memory protection, and other things like that on the CPU(or common thing on the mobo)

yea..I kinda lost my train of thought for this, but I'll comeback and post more tommorrow...so tel me what you think so far though...is it possible? or what?
User avatar
Alboin
Member
Member
Posts: 1466
Joined: Thu Jan 04, 2007 3:29 pm
Location: Noricum and Pannonia

Post by Alboin »

You would have to abstract everything that wasn't portable. So hardware, CPU data structures, memory management, etc. would all have to be abstracted to beyond recognition.

That could get interesting. It would be like a source code level virtual machine. Moreover, the actual result of the OS would be strange as it would know very little about the actual hardware it was running on.

Hmm...
C8H10N4O2 | #446691 | Trust the nodes.
User avatar
os64dev
Member
Member
Posts: 553
Joined: Sat Jan 27, 2007 3:21 pm
Location: Best, Netherlands

Post by os64dev »

Well it can be done rather easily if you use the bridge, abstract factory and strategy design pattern. Though most of the work lies in desing it correctly. Implementing problably is not hard.
Author of COBOS
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

Post by earlz »

well, rather than setting up GDTs, you setup something more portable like..AdressSpaces

Rather than setting up an IDT, you'd setup an interrupt list with some attributes....


I just don't know how to make it all work though...
User avatar
Colonel Kernel
Member
Member
Posts: 1437
Joined: Tue Oct 17, 2006 6:06 pm
Location: Vancouver, BC, Canada
Contact:

Post by Colonel Kernel »

hckr83 wrote:Well, I was thinking about how to make an OS more portable, and well....most parts of an OS just can't be made portable(even with a layer) but the actual OS kernel possibly could..
There are some parts of any OS that are impossible to make portable -- you just have to implement them for each architecture. It's all really low-level stuff though (interrupt handling stubs, syscall dispatching, low-level I/O for drivers, managing the MMU structures). Pretty much everything else can be abstracted and made portable.

Have you looked at Linux or any other OS to see how they do it? This is not a new idea...
really, I think some assumptions should be made, such as an MMU is present
For OSes that use hardware memory protection, this is definitely true. For example, Linux makes certain assumptions about an MMU being present, and supporting certain address space sizes, etc.
But basically make something to seperate things like task switching, memory protection, and other things like that on the CPU(or common thing on the mobo)
What do you mean by "separate things" exactly? Keep these things separate from each other, or for each thing, to separate its architecture-specific and architecture-independent parts?

Pretty much every OS I know of has a hardware abstraction layer "HAL" that does more or less what you're proposing.
os64dev wrote:Well it can be done rather easily if you use the bridge, abstract factory and strategy design pattern.
In theory, yes. :) In practice, these patterns often rely on OO language features like polymorphism to work, which in C++ is inconvenient unless you allocate objects on the heap, which is not something you want to be doing in the lowest-level parts of the kernel.

Sometimes you can implement these design patterns "statically" in a way that would be safe to use in low-level code. For example, you can use templates to implement a static version of the strategy pattern, where the strategy is a template parameter and each instantiation uses a different concrete strategy.

It's quite misleading to say that using these patterns makes it easy though. It just gives you a mental framework that makes it easy to understand what you have to do. Actually doing it (figuring out how to abstract hardware) is always challenging.


I'm a bit puzzled why this is being discussed as though it is a new and somehow novel idea... Try looking around at some other OSes to see how they are designed for portability. Sometimes you'll find that with microkernels in particular, the whole kernel is architecture-specific so that everything else can be portable. Other times almost the entire OS is portable.
Top three reasons why my OS project died:
  1. Too much overtime at work
  2. Got married
  3. My brain got stuck in an infinite loop while trying to design the memory manager
Don't let this happen to you!
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Post by Brendan »

Hi,
hckr83 wrote:Well, I was thinking about how to make an OS more portable, and well....most parts of an OS just can't be made portable(even with a layer) but the actual OS kernel possibly could..
First, there's 2 ways to write portable code - only use features that are supported on all architectures and have a small amount of architecture specific code, or have more architecture specific code and use features on some architectures that aren't supported on others. The main difference here is where the abstraction layer/s are placed.

Now, imagine you've already written all architecture specific code (task switching code, IRQ handling stubs, exception handling stubs, SMP startup code, inter-processor communication, local APIC timer, kernel API framework, I/O APIC, PIC, MMU, re-entrancy locking, etc). What would you do with it?

Some options are:

A) Statically link it to a large amount of portable code, use conditional code for glue and call it a monolithic kernel. This is sort of how Linux does it.

B) Statically link it to a small amount of portable code, use conditional code for glue and call it a micro-kernel. This is sort of how Minix does it.

C) Do the same as in B, but use a small amount of architecture specific code (instead of a small amount of portable code) to turn it into a microkernel. This is how L3 and L4 do it.

D) Call it a HAL and dynamically link it to the portable code. This is sort of how Windows NT/XP does it.


For my OS I prefer option C. It means that a little more code is architecture specific, but it also means the abstraction layers are at a higher level. This makes it easier to support features on one architecture that aren't supported on others. A good example of this is L4's "small address spaces" - for 32-bit 80x86 they use segmentation to divide the linear address space into several smaller address spaces so that task switches can be done between the small address spaces without TLB flushing. It also reduces the amount of mess you get with options A and B (all the conditional code vanishes), and doesn't have the inefficiencies you get with option D (no function inlining, where you can end up with a full function call just to execute one instruction).

Of course this is a little funny when you think about it - for some people (including myself), a 100% architecture specific micro-kernel may be the best way to write a portable OS... ;)


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
Colonel Kernel
Member
Member
Posts: 1437
Joined: Tue Oct 17, 2006 6:06 pm
Location: Vancouver, BC, Canada
Contact:

Post by Colonel Kernel »

Brendan wrote:A) Statically link it to a large amount of portable code, use conditional code for glue and call it a monolithic kernel. This is sort of how Linux does it.

B) Statically link it to a small amount of portable code, use conditional code for glue and call it a micro-kernel. This is sort of how Minix does it.

C) Do the same as in B, but use a small amount of architecture specific code (instead of a small amount of portable code) to turn it into a microkernel. This is how L3 and L4 do it.

D) Call it a HAL and dynamically link it to the portable code. This is sort of how Windows NT/XP does it.
Actually, Windows is more of a hybrid between A and D. The HAL contains only machine-specific code (i.e. -- specific to the particular chipset and CPU model/stepping/whatever), not all the architecture-specific code. For example, the ISR stubs (which are very architecture-specific) are not in the HAL, but in the "Kernel" (which is, confusingly, the name of a sub-system in ntoskrnl that acts a lot like a microkernel).

BTW, for my own fledgling kernel, so far I have no conditional code for portability, but I do have somewhat conditional makefiles. :)
Top three reasons why my OS project died:
  1. Too much overtime at work
  2. Got married
  3. My brain got stuck in an infinite loop while trying to design the memory manager
Don't let this happen to you!
axilmar
Member
Member
Posts: 28
Joined: Sat Jun 02, 2007 10:35 am

Post by axilmar »

It would be interesting to see a sort of virtual machine as the kernel: instead of running native code, the kernel would allow byte code to run, translating it on the spot to native code. Then the only need to port the O/S to another architecture would be to write a new virtual machine.
Crazed123
Member
Member
Posts: 248
Joined: Thu Oct 21, 2004 11:00 pm

Post by Crazed123 »

I don't think that's worth the trouble unless:

1) Your virtual machine can provide performance (ie: speed, throughput, responsiveness) beyond native code running on a kernel. OR
2) Your virtual "architecture" has extremely useful features implemented by compiling them to native code. For example, adding a Process Register or an I/O MMU.
User avatar
B.E
Member
Member
Posts: 275
Joined: Sat Oct 21, 2006 5:29 pm
Location: Brisbane Australia
Contact:

Re: A layer between the OS(kernel only) and the CPU

Post by B.E »

hckr83 wrote:Well, I was thinking about how to make an OS more portable, and well....most parts of an OS just can't be made portable(even with a layer) but the actual OS kernel possibly could..

I really don't have much knowledge with many other Archs, but anyway...
really, I think some assumptions should be made, such as an MMU is present

But basically make something to seperate things like task switching, memory protection, and other things like that on the CPU(or common thing on the mobo)

yea..I kinda lost my train of thought for this, but I'll comeback and post more tommorrow...so tel me what you think so far though...is it possible? or what?
This is already done by most operating systems, Linux is portable to most platforms. The whole point of an operating system is provide an api that's independant of the hardware beneith,
Image
Microsoft: "let everyone run after us. We'll just INNOV~1"
btbx
Posts: 8
Joined: Tue Aug 14, 2007 8:57 am

Post by btbx »

What about LLVM and LLVA?

In this project, we have taken our next logical steps in this effort by (1) porting the entire Linux kernel to LLVA, and (2) engineering an environment in which a kernel can be run directly from its LLVM bytecode representation -- essentially, a minimal, but complete, emulated computer system with LLVA as its native instruction set. The emulator we have invented, llva-emu, executes kernel code by translating programs "just-in-time" from the LLVM bytecode format to the processor's native instruction set.
Crazed123
Member
Member
Posts: 248
Joined: Thu Oct 21, 2004 11:00 pm

Post by Crazed123 »

That's actually damn cool, and I can't wait until someone (maybe me many years from now?) creates a LLVA -> native "bare metal" compiler that allows operating systems compiled to LLVA to run on real machines.
btbx
Posts: 8
Joined: Tue Aug 14, 2007 8:57 am

Post by btbx »

> LLVA

Please contact Mr John Criswell:

"The code for the LLVA-OS extensions (and the LLVA-OS Linux port) are not publicly available at this time. Some of the LLVA-OS extensions may find their way into LLVM in the future. As for the LLVA-OS Linux port, we may release that at some point, but I can't make any promises about
it at the moment. The LLVA work doesn't have its own web page, currently. However, if you're interested, there is a paper on LLVA on the LLVM publication page"

http://llvm.cs.uiuc.edu/pubs/2003-10-01-LLVA.html
Avarok
Member
Member
Posts: 102
Joined: Thu Aug 30, 2007 9:09 pm

Post by Avarok »

I kind of thought that the purpose of an OS was to provide a useful framework for person(s) and program(s) to run program(s) and get file(s); ideally, quickly and effectively.

It doesn't necessarily have to do it all itself, exokernel theory suggests that it's perhaps even better to export the workload, but the final result ought to be just that?
There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies.
- C. A. R. Hoare
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

I don't quite understand how that reply relates to the thread...?
Post Reply