A layer between the OS(kernel only) and the CPU
A layer between the OS(kernel only) and the CPU
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?
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?
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...
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.
- Colonel Kernel
- Member
- Posts: 1437
- Joined: Tue Oct 17, 2006 6:06 pm
- Location: Vancouver, BC, Canada
- Contact:
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.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..
Have you looked at Linux or any other OS to see how they do it? This is not a new idea...
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.really, I think some assumptions should be made, such as an MMU is present
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?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)
Pretty much every OS I know of has a hardware abstraction layer "HAL" that does more or less what you're proposing.
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.os64dev wrote:Well it can be done rather easily if you use the bridge, abstract factory and strategy design pattern.
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:
- Too much overtime at work
- Got married
- My brain got stuck in an infinite loop while trying to design the memory manager
Hi,
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
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.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..
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.
- Colonel Kernel
- Member
- Posts: 1437
- Joined: Tue Oct 17, 2006 6:06 pm
- Location: Vancouver, BC, Canada
- Contact:
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).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.
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:
- Too much overtime at work
- Got married
- My brain got stuck in an infinite loop while trying to design the memory manager
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.
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
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,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?
Microsoft: "let everyone run after us. We'll just INNOV~1"
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.
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.
> 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
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
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?
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
- C. A. R. Hoare