Page 1 of 2

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

Posted: Fri Jul 06, 2007 10:18 pm
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?

Posted: Fri Jul 06, 2007 10:51 pm
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...

Posted: Sat Jul 07, 2007 5:51 am
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.

Posted: Sat Jul 07, 2007 9:40 am
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...

Posted: Sat Jul 07, 2007 10:00 am
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.

Posted: Sun Jul 08, 2007 1:41 am
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

Posted: Sun Jul 08, 2007 2:01 am
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. :)

Posted: Fri Jul 13, 2007 8:16 am
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.

Posted: Fri Jul 27, 2007 8:11 am
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.

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

Posted: Wed Aug 01, 2007 10:57 pm
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,

Posted: Tue Aug 14, 2007 9:11 am
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.

Posted: Tue Aug 14, 2007 9:54 pm
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.

Posted: Tue Aug 14, 2007 11:55 pm
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

Posted: Sun Sep 02, 2007 7:52 pm
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?

Posted: Mon Sep 03, 2007 3:11 am
by JamesM
I don't quite understand how that reply relates to the thread...?