Kernel 0.1, Win
Michael David WINIKOFF
winikoff@mulga.cs.mu.OZ.AU
Sun, 21 Mar 93 15:27:18 EST
Kernel -- The Second Attempt
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[NOTE: I'm starting from a conventional OS and moving away rather then starting
from objects and moving towards OS -- I feel that this is more likely to
yield a running system in a short amount of time. As Dennis has pointed out
we don't have the resources to re-invent the wheel]
Rather then just present details here I'd like to throw some ideas and
justifications.
Idea 1
~~~~~~
We base the kernel on persistent processes.
[Terminology: In a moment I'll modify this to persistent objects and explain
the differences. By persistent I mean that it can be swapped out to storage,
the machine turned off and on and then continued. In practice we would like
to be able to have a large number of suspended processes on disk]
This subsumes directories and files -- a directory is just a process that
accepts queries and returns some identifier for the processes representing files
Consider now the form of such a server (which incidently bears a striking
resemblence to the nameservers (or dictionaries)):
while (accept(request))
case request of
type1 : ... handle 1 ...
type2 : ... handle 2 ...
This type of code will be very common in the system.
It allready is in event based systems.
Why then not have a process declare to the kernel that
"I handle the following request:
req1 taking 4 parameters
req2 taking 3 parameters
etc."
This is just an object.
It has the concept of methods.
[Note: It is open to discussion how much the kernel should know about the form
of the parameters (Eg. number, type ...)]
[note 2: Inheritance has been left out for the moment.
as have overloading and polymorphism]
Definition 1
~~~~~~~~~~~~
An object is a process with method declerations.
Definition 2
~~~~~~~~~~~~~
A Device or "LOw Level Object" (lolo) is an object which
either i
(1) has been granted the privilege of being able to refer to certain hardware
resources. (Eg. disk control registers, ethernet card)
AND/OR
(2) Has methods which are invoked upon the reciept of a particular interrupt.
(Eg. data ready)
[Note: Most lolo's will have (1) -- I think that few will have ONLY (2)]
Definition 3
~~~~~~~~~~~~~
An OID (Object IDentifier) is an atomic data item that is valid across processes
(Note: In a distributed system it would be valid across machines too) and
can be used to address an object.
Definition 4
~~~~~~~~~~~~~
A Dictionary (Or Name Server) is an object which supports certain lookup
operations and returns an OID.
[Note: We see the concept of object classes by the type of the supported methods
falling out. Whether this should be enforced by the kernel or elsewhere
or not at all is open to debate]
Discussion: As can be seen, so far we need system calls to
* Create new objects
This must take in parameters describing
(1) The code
(2) The method declerations
These two could (should?) be together in an executable
(3) OIDs for the objects which the new object has
access to
This is important -- it replaces the concept of a default
name server. The only object that is not given an object by
it's spawner is the initial object. Giving it a nameserver
is part of the bootstrap process.
* Destroy objects -- clearly this takes an OID as a parameter
* Invoking a method
This takes
(1) An OID
(2) The method "name"
(3) The arguments
Issues:
What is the type of the name?
An integer is the obvious.
When would the allocation of these be done?
The permissible type of the arguments?
in a purely OO system we could just have OIDs and be
done. In our system it is doubtful that representing
(eg.) an array by an object would be practicle so we
need to be able to pass large granularity data between
objects.
This is where IPC comes in.
(I'm using the definition that IPC involves data
copying between address space]
A comment on (very) small objects
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In a pure OO environment one could use an object to represent say an array
(not to mention an integer)
This is impracticle if we treat objects as processes since then a method
invocation involves a context switch.
This does not prohibit using small objects WITHIN a single larger object it's
just that these small objects can't be exported to the rest of the system.
I don't think that we can develop a system supporting small objects with
reasonable efficiency in reasonable time. It involves too much research.
Some Other Issues
~~~~~~~~~~~~~~~~~~~~
These are areas which bear further thought.
I'll indicate my initial reactions to these issues.
Rather then spend time filling out the details now (and spark a debate on them)
I'd like to come to agreement on the basics first.
(1) Memory Allocation
(2) lolos -- how are they created, managed etc.
(3) Virtual Memory and Address Spaces
(4) What are the semantics of persistance -- eg. what efficiency do we guarantee
[Note: Efficiency is important in design in that a gross efficiency difference
will influence the way a feature will be used.]
(5) Semantics of invocation (Eg. do we have a single threaded or multi threaded
semantics)
(6) Inheritance
(7) Polymorphism and Overloading
---------
(1) Memory allocation:
What kernel calls, how and should we support higher level functionality.
(Eg. GC etc.)
(2) lolos:
How do we set an object up as a lolo, how do we give it access to a
certain region of memory.
(Implementation: we might need to have the access traped and then redone
by the kernel after checking -- MMUs don't neccessarily support fine
grain protection.
(Eg. this object can read bytes 100-102 and write bytes 103-110 but
can't touch bytes 0-99 and 111-500)
)
(3) Virtual Memory and Address Space
I think we can more or less agree that seperate objects should not
be able to read/write each others address space for robustness
reasons.
Should we have an address space that is global or local to each object.
(Note: This IS an independant issue)
How should VM be done? I think paging is the simplest way.
DEtails:
User input to the process if any
Existance of PHYS_MEM and it's management
(4) Semantics of persistance:
One way to do persistance is to simply rely on paging -- assume all
objects are in a very large memory and let paging load them in as
needed.
As Dennis has pointed out this is inefficient.
Another way is swapping -- a process can only be either completely
swapped out or completely in memory.
Disadvantage: Lose the ability to save memory by having part of a
process in memory
Advantages: (1) Can be done without an MMU
(2) By letting the user do this manually we allow coarse grain
manual resource allocation.
(Sort of like doing a "copy foo TO ramdisk" b4 starting
and having an automatic save files to hard disk from ramdisk
when about to shutdown)
(5) Semantics of invocation
MOOSE is multitasking.
What happens in the following situation:
Object X Object Y Object Z
Invoke(Z,1)
Starts executing method 1
Invoke(Z,2)
The three obvious possibilities are
(a) Z starts another method in parallel
(b) Y is blocked until Z finishes
(c) Y continues and the invocation is queued.
(a) Gives us multithreading and requires us to have semaphores to co-ordinate
access to shared data.
(b) Is the simplest to implement but is less versatile
(c) Makes invocation asynchronous -- this adds paralellism to the system.
Notice that under (b) one could have the invoke call return a result.
Under (c) though the invoke would not return anything (other then
"this was succesfuly queued" OR "this failed") and the reciever would use
it's own invoke to return an answer.
Of course we could (and probly will end up doing) provide more then one.
(6) Inheritance
I've left this out for now.
One question I would like to raise is WHICH INHERITANCE?
There are multiple models -- C++, Smalltalk.
Oh, and this is without considering multiple inheritance.
(7) Polymorphism and Overloading
So far I've only come across these as language design issues.
You have a "natural" polymorphism in some commands
(Eg. mv,rm,cp) when the contents of a file don't matter.
Could someone expound on their ideas -- how do YOU view the role
and function of polymorphism in an OS.
--------------------------
And of course, feel free to comment, correct, suggest, debate and/or flame.
Michael
Aka. Merlin son of Corwin and Dara, sorcerer and creator of Ghostwheel. :-)