[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Fenix Was: OS calls.

Well, My intention was to keep Fenix a bit secret until
I had some stable code to show but all this talk about
new calling procedures kind of forced me to speak up...

First off all I think that all OS-call should be handled with traps not
unimplemented instruktions. Using line A/F systems will cause compability
problems since line F are used for coproc. instr. and line A is used by
ROM-VDI in all ROMed TOSes (not to mention a lot of programs).

What is Fenix? and Why?

Fenix is a total remake of GEM,BIOS,XBIOS and MiNT. 
Why should anyone make a new MiNT?
Well one reason is that MiNT is now a very old prog which has been 
patched a lot of times. A remake would be a fresh start.
Another reason is that MiNT is a monolithic kernel and does not
support virtual memory. It thus consumes a lot of memory.
MiNT does not support threads and has no true message passing.

Fenix will support theads,virtual memory at kernel level and a very
fast message passing scheme.

How should we do it?

Fenix is very influenced by mach 3 and thus consist of a very little 
microkernel which only handles context-switching,paging and message-
passing. Everything else is handled by threads external to the microkernel. 
This means that the microkernel lies in resident memory and the rest is in 
virtual-memory. An additional benefit is that this scheme increases the 
portability of the OS. 

Processes and threads

In MiNT and Unix a process consist of a context and a memoryspace. 
This means that it is hard to have several contexts running in a program. 
Nearly all of the new OSes have threads instead of processes. A thread is 
basically a context. A unix process is emulated in Fenix by a single
thread in a memoryspace.


Programs in Fenix originally consists of a memoryspace and a thread. 
Additional threads can be spawn by all threads and don't need to be copies 
of the spawning thread. 


This is a new concept. In MiNT there is no need for this since all memory 
is bound to processes. Memoryspace is only a collection of memoryblocks 
that some threads can run in.


The backbone of Fenix is messages. All thread-synchronization and 
communication are performed by messages. A message in fenix consists 
of a pointer to a memoryblock either in shared or global memory or a 
special message page, a virtual memory page, that is moved into the memory 
space of the recieving thread. An old MiNT/TOS/AES/VDI/BIOS/XBIOS-call is 
converted into a message and sent to the thread that is supposed to handle 
the call. Thus Fenix unaware programs must share their memory with the OS 
to be able to run.


A message is sent to a port that the recieving thread have created and is 
listening to. This is very similar to mach. The ability to bundle ports into 
sets that mach have is not used in Fenix. All ports are referenced by handles, 
which is the same as capabilites in mach, similar to filehandles. The handles 
are stored in the memoryspace and are thus shared by all threads that are 
executing in that memoryspace.

What can the microkernel do?

It is vital that the microkernel is small and has all the necessarily 
mechanisms to handle context switching,paging and message passing. 
I believe that this is sufficient:

Context switching: Switch thread and or memoryspace and handle aging
	of processes, that is lowering the priority of threads that
 	consumes more than the allocated timeslice.

Paging:		Swap pages to and from the backing store, ie hard
 			disk, and updating the MMU page trees.

Messages:         Uppdating port structures and blocking the
 			calling/recieving threads if necessarily.

All other activities are handled by servers which have more or less access
 to the memory of the microkernel. The communication to these servers are 
handled by messages. For instance wait can be implemented as a message to 
a clockserver which replies when the time is up. 

What does the microkernel look like?

The microkernel is very small about 4-8k of code written entirely in assembler
 for size and speed reasons. The amount of resident, ie non virtual, memory 
is also small about 8k. The microkernel consists of four parts.
The message controller which also does contextswitching.
The pager which handles virtual memory.
The swapper which is the controller of the swap hard disk.
And the emulator which converts the original OS-calls into messages. The emulator 
	can be bypassed by programs that is Fenix-aware.

Only the pager and the swapper needs to be threads and even these do not need 
to be true threads and communication can be faster because they all are in 
the microkernel. 

The microkernel must be assembled to the computer that it is running 
upon since contexts are saved differently on different processors. On a 
68000 for instance there is no need for the pager and the swapper.


Here are some internals for spec freaks:

		maximum number of threads in a system: 4G (=2^32)
		number of priorityqueues:32
		number of prioritylevels:4G
		maximum number of ports per memoryspace: 4G
            more than 4000 messages sent and recieved per second
 				including contextswitching on a 8MHZ 68000.
		page size: 4k
		maximum memory allocated to a memoryspace: about the same as
 			maximal virtual memoryspace of the computer.

Message interface

This is how a message is sent or recieved:

on a 680x0 system:

d0.l = porthandle
d1.l = higher word: timeout time in milliseconds
	 lower word : flags (send or recieve,blocking or nonblocking and
 					so on)
a0.l = pointer to message to be sent
a1.l = reserved
the microkernel is called by a trap #0

after the call the registers are as follows
d2-d7/a2-a7 and all FP-regs are saved

d0.l = status (errorcode)
d1.l = reserved
a0.l = pointer to recieved message
a1.l = reserved 

The future

As I said i haven't got any stable code yet since I'm in the middle of exams 
right now. I hope to show some code on the microkernel in about 2 weeks. 
There are however a lot of work to be done. The rest of the OS must be 
partitionated into servers and communication schemes must be established 
between these servers. Here are a naive list of servers:

Thread server:  handles everything about threads that the microkernel
 			doesn't handle.
Memory server:  handles everything about memory that the microkernel
Device server:  handles hardware devices and their allocation to
File server:    handles files.
Network server: handles everything about networks.
VDI server:     handles lowlevel screen usage.
AES server:     handles aes-calls. (Perhaps a version of XaAES?)
Application server: makes an easy OO-interface that an application can


Goodies that can be implemented into Fenix are memorymapped files, OO-calls,
dynamic linking and... If something is needed write a server! 

Notes to Fenix implementors


Fenix should be and must be highly portable. That is however no reason to do
things slow. Things that must be really fast must be coded in assembler. We must 
make the common case fast a?la RISC processors. Fenix is meant to be a fast and 
slick OS that is small, powerful and easy to extend by new servers. I think that 
we must face the fact that we must port fenix to PPC or another processor about 
the same time as it is beginning to work on the 680x0. We must bear this in mind 
but also make good solutions to problems. We cannot rely on more powerful 
processors with every new version like microsoft.

Implementation language

Fenix should be implemented in C/C++ and assembler. There is currently no 
competition to these languages. An OO approach would be very nice! 

all the above info is also at http://www.efd.lth.se/~f92sk

	Sven Karlsson
Student of Engineering Physics at Lund Institute of Technology, Sweden

Soft- and Hardware developer @ Istari Software
Current project: Code ,an interactive development tool for video
	game consoles including Editor,Debugger and Assembler
E-mail: f92sk@efd.lth.se or tomten@df.lth.se
WWW: http://www.efd.lth.se/~f92sk