Portability

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
dc0d32

Portability

Post by dc0d32 »

hi

i am very well accustomed to Intel processors as i am designing an OS for the same. but, the problem is that i have no idea whatsoever about the other architectures (apart from 680x0), and i intend to make my kernel portable.

atleast i dont think that one can try and learn fairly large and countable families of processors. you have to work on and for the machine that you have(unless u have many lying around).

my point is, still, how do i make or maintain my kernel portable?

can we, all of us on this forum, create a subset of the faq2 which will tell all the possible alternatives (to date, and growing) for a specific feature, and their implementation concerns on considerable processor families?

eg. someone wants to implement system calls...
then he visits the syscall page,

now, for intels, he is confronted with the regular interrupt method, stating it's adv& disavd etc, then the sysenter/sysexit (whatever) etc.

for 680x0, the same topic "syscalls" will have how-to-do information with each method possible along with it's design issues.

doing so, i'm not saying that this much information is enough to be able to boot your kernel on a different arch, but, we, novice developers will get a guideline about what to do n what to avoid (unless ur design desparately needs it), and why. Because, AFAIK, middle level kernel design is influenced by hardware, no matter how best you try. it is the mark a few can get to.

"work in groups" i hear you say. what if it can not be done? (project or something like that)

first of all, are my views correct? (spare me for english). or anyone has some better idea to create a portable kernel?
Joe324233

Re:Portability

Post by Joe324233 »

Maybe, you can take a look at NetBSD and learn how they have done with it? NetBSD is happened that I can think of OS to have a great portable.
proxy

Re:Portability

Post by proxy »

really I find that the key to portability in most cases is a matter of abstraction. For example, AFAIK Linux _always_, for all builds uses 3 levels of page tables (PDP -> PD -> PT -> PG).

Clearly, this doesn't represent all architectures. However, as far as all other code in the kernel is concerned, when it talks to the VMM system, this is how it is. Once you have a abstract interface, then it's just a matter of making your code do the right thing when the real interface is slightly different.

continuing with my example, on a non-PAE x86 system, the Linux VMM system "folds" layers together in the internal code to conver abstract to real. I've gotten this from pgtable.h in the linux sources.
/*
* The Linux memory management assumes a three-level page table setup. On
* the i386, we use that, but "fold" the mid level into the top-level page
* table, so that we physically have the same two-level page table as the
* i386 mmu expects.
*
* This file contains the functions and defines necessary to modify and use
* the i386 page table tree.
*/
This is just one example of many. Basically the moral is, for any code which you think may be specific to a CPU, come up with a general interface for it (MMU stuff goes here for sure). Many times it's easiest to make your "abstraction" look like your first target, then have your code for other targets tweaked to work with that. It's up to you.

Good luck,
proxy
dc0d32

Re:Portability

Post by dc0d32 »

very true. abstraction is the first thing that comes to your mind when considering portability. actually, without abstraction, you'll get hell of unmanageable code.

but, still, in order to design the abstraction, for which you want descent and not-so-poor, effective underlying implementations on different archs, u still need to have some basic idea of how it is done in those archs. The folding mensioned here is quite trivial and logical. absolutely. i agree. the point is, how do i design such an abstraction that will not hamper nither design beauty nor efficiency(golden mean); without knowing any basics of those arch?
paulbarker

Re:Portability

Post by paulbarker »

The best place to start is to separate your code into platform-dependent parts and generic parts, with a clean and well-defined interface between the two. The generic code must be independent of such things as pointer and integer size.

2 examples from my kernel designs:

1) The physical memory manager handles any number of 'pools', each made up of any number of contiguous ranges of pages. It is up to the platform-dependent code to create the pools it needs, and provide a 'get_pages' function to take pages from the correct pool. For x86, an extra function 'get_dma_pages' can be defined which is only used by x86-only drivers (and other platforms with DMA). As far as the possible pools go, for x86 I will have a DMA pool (0-16MB), a normal pool (16MB-highest address always mapped) and a high memory pool (all other addresses).

2) For threads, I have a generic thread_t structure. One member of this is a arch_thread_t structure, which the generic code never touches. To switch threads, the generic code simply calls 'switch_thread(thread_t*)', which is provided by the platform-dependent code. Other functions such as arch_init_thread must be provided and called where needed.

I hope this gives you a few ideas. There should be many documents around the web about writing portable C/C++ code, take a look at Mozilla for a start, they have some good docs about how they made their browser and other applications portable: http://www.mozilla.org/hacking/portable-cpp.html.

I think the most important thing is to design a good interface between generic and platform-dependent code. Start by supporting one platform, and when a new platform comes along that conflicts with your generic code, weigh up the options carefully.
JoeKayzA

Re:Portability

Post by JoeKayzA »

It might be helpful to have a short look at several different processor architectures - it'll give you a much better overview for creating a good abstraction layer.


Btw, can someone explain to me what's the use of exposing multiple levels of page tables to the rest of the system? IMO, the VMM should hide away this detail entirely and only expose whole virtual address spaces (+ which page sizes are supported on the system).

cheers Joe
proxy

Re:Portability

Post by proxy »

the point is to make it so you don't need to re-write the _whole_ VMM subsystem for each target architecture. You only need to re-write a few key components that the rest build on.

proxy
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re:Portability

Post by Brendan »

Hi,

The first thing you'd need to do (for portability) is decide where your abstraction layer will be (or where non-portable code will meet portable code).

For example, consider the scheduler. You could have the abstraction layer above the scheduler so that all scheduler code is non-portable, or you could have it below the scheduler so that the scheduler is portable (but then you'd probably need a "system timer" abstraction and a "task switch" abstraction).

In general, if the abstraction layer is at the lowest level possible then you end up doing the least amount of work to port the OS to another architecture and the OS will be less efficient. This is due to programming to the "lowest common denominator" (or not using hardware features on one architecture because there's no equivelent on another architecture), or having dummy code that pretends something exists when it doesn't. Alternatively, if the abstraction layer is at the highest possible level (e.g. in high level language libaries) then you'd need to do a lot more work to port the OS but efficiency problems can be avoided.

For my OS the abstraction layer will be the micro-kernel's API. Porting the OS will mean writing an entirely new micro-kernel and boot code, and then recompiling everything else.
JoeKayzA wrote:Btw, can someone explain to me what's the use of exposing multiple levels of page tables to the rest of the system? IMO, the VMM should hide away this detail entirely and only expose whole virtual address spaces (+ which page sizes are supported on the system).
IMHO the abstraction layer in Linux's VMM is may be too close to the hardware....


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:

Re:Portability

Post by Colonel Kernel »

Brendan wrote:For my OS the abstraction layer will be the micro-kernel's API. Porting the OS will mean writing an entirely new micro-kernel and boot code, and then recompiling everything else.
This is also true of the L4 microkernel. There is a very compelling argument to be made (on the grounds of efficiency) that this is one of the reasons to choose a microkernel architecture in the first place.

Exokernels go even further by having an architecture-dependent kernel API. They rely entirely on user-mode libraries to provide the portable abstractions.
IMHO the abstraction layer in Linux's VMM is may be too close to the hardware....
I totally agree... that sounds like serious hackery to me. :P I wonder how Linux would handle architectures with inverted page tables like the PowerPC...
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!
kalyan

Re:Portability

Post by kalyan »

I am porting the linux 2.4 on powerpc.any Suggestions... :)
Post Reply