[comp.unix.internals] Implementing a multitasking OS on top of UNIX

craig@casbah.acns.nwu.edu (Craig Robinson) (05/09/91)

For my operating systems class we are required to do the following project:

"Groups of three students will design and develop a priority based
multitasking kernel that provides for process control, process
synchronization, and process communication.  The kernel will be developed in
the C programming language and will run on top of the UNIX OS."

This is the exact project specification as stated in our syllabus.  No
more, no less is required.

I have several questions I want to ask the gurus.

1)  In what way would we be able to implement a quantum driven system?   
How can we simulate clock interrupts?

2) In UNIX, what happens *at the CPU level* when a process makes a system
call?  How does the processor know to switch from user to kernel mode?  How
can we simulate this on top of UNIX?

Any other tips anyone can give me would be greatly appreciated, we only have
about 3 more weeks until the due date, and we are all very confused about
exactly how we are going to do this.

Thanks,
Craig
-- 
craig@acns.nwu.edu

phil@ux1.cso.uiuc.edu (Phil Howard KA9WGN) (05/09/91)

craig@casbah.acns.nwu.edu (Craig Robinson) writes:

>For my operating systems class we are required to do the following project:
>"Groups of three students will design and develop a priority based
>multitasking kernel that provides for process control, process
>synchronization, and process communication.  The kernel will be developed in
>the C programming language and will run on top of the UNIX OS."

>This is the exact project specification as stated in our syllabus.  No
>more, no less is required.

>1)  In what way would we be able to implement a quantum driven system?   
>How can we simulate clock interrupts?

Do you actually need clocks?  Was that a part of the assignment spec?

Actually it should not be hard.  I assume you have some sort of way to
identify your tasks and a means to send them a message.  Have a signal
handler (which is the equavalent of an interrupt handler here) send a
message to the designated task when a signal comes in for a clock tick.
The schedule the next one and return.

>2) In UNIX, what happens *at the CPU level* when a process makes a system
>call?  How does the processor know to switch from user to kernel mode?  How
>can we simulate this on top of UNIX?

Again, is this part of your assignment?  You don't need to distinguish
between user and kernel mode.  Everything can be in user mode.  You should
not be trying to build a whole UNIX system.

>Any other tips anyone can give me would be greatly appreciated, we only have
>about 3 more weeks until the due date, and we are all very confused about
>exactly how we are going to do this.

I am working on the design of just such a system myself, and I expect to
someday implement it on top of UNIX, as well as some other places first
where I really NEED it.  It will be more than 3 weeks before it is ready.
-- 
 /***************************************************************************\
/ Phil Howard -- KA9WGN -- phil@ux1.cso.uiuc.edu   |  Guns don't aim guns at  \
\ Lietuva laisva -- Brivu Latviju -- Eesti vabaks  |  people; CRIMINALS do!!  /
 \***************************************************************************/

craig@casbah.acns.nwu.edu (Craig Robinson) (05/09/91)

In article <1991May9.040020.26194@ux1.cso.uiuc.edu> phil@ux1.cso.uiuc.edu (Phil Howard KA9WGN) writes:
>craig@casbah.acns.nwu.edu (Craig Robinson) writes:
>
>>For my operating systems class we are required to do the following project:
>>"Groups of three students will design and develop a priority based
>>multitasking kernel that provides for process control, process
>>synchronization, and process communication.  The kernel will be developed in
>>the C programming language and will run on top of the UNIX OS."
>
>>This is the exact project specification as stated in our syllabus.  No
>>more, no less is required.
>
>>1)  In what way would we be able to implement a quantum driven system?   
>>How can we simulate clock interrupts?
>
>Do you actually need clocks?  Was that a part of the assignment spec?
>

Well, I lied a little bit when I said that the above was the exact project
specification.  Since we were given this assignment the Prof. has asked
that we try to implement a quantum driven system. 

>Actually it should not be hard.  I assume you have some sort of way to
>identify your tasks and a means to send them a message.  Have a signal
>handler (which is the equavalent of an interrupt handler here) send a
>message to the designated task when a signal comes in for a clock tick.
>The schedule the next one and return.

Good idea, I like it.

>>2) In UNIX, what happens *at the CPU level* when a process makes a system
>>call?  How does the processor know to switch from user to kernel mode?  How
>>can we simulate this on top of UNIX?
>
>Again, is this part of your assignment?  You don't need to distinguish
>between user and kernel mode.  Everything can be in user mode.  You should
>not be trying to build a whole UNIX system.

You know, you're right.  I never thought about that.  I have been so caught
up in trying to understand how UNIX internals work, that I have been trying
to build a system like it, and was feeling overwhelmed by the task.  But
that is not at all what I need to do.  Thanks for the insight Phil.

Just for my own edification though, what does happen at the CPU level when
a process makes a system call?


> /***************************************************************************\
>/ Phil Howard -- KA9WGN -- phil@ux1.cso.uiuc.edu   |  Guns don't aim guns at  \
>\ Lietuva laisva -- Brivu Latviju -- Eesti vabaks  |  people; CRIMINALS do!!  /
> \***************************************************************************/


Craig
-- 
craig@acns.nwu.edu

torek@elf.ee.lbl.gov (Chris Torek) (05/09/91)

In article <1991May9.055804.6550@casbah.acns.nwu.edu>
craig@casbah.acns.nwu.edu (Craig Robinson) writes:
>Just for my own edification though, what does happen at the CPU level when
>a process makes a system call?

It depends on the CPU.

The VAX has four `chm' instructions (chm[uesk]).  Unix uses only chmk,
`change mode to kernel'.  This is done as, e.g.:

	pushl	$1		# argument to syscall
	chmk	$1		# exit(1)

The chmk changes to kernel mode, sets the stack pointer to the Kernel
Stack Pointer `ksp' (it was the User Stack Pointer `usp'), and jumps to
the `chmk' vector.  (Actually it reads the chmk vector out of the scb,
and uses the low 2 bits to decide whether to use the kernel stack or the
interrupt stack, or to halt.)  The parameter to chmk is pushed on the
new stack after the previous psl and pc.  That is:

	*--ksp = psl;
	*--ksp = pc;
	*--ksp = <argument to chmk>;

The BSD vax kernel follows this with pushing the T_SYSCALL type (not
actually used, it just makes the trap() and syscall() frames the same)
and the usp, then calls syscall().  To return from a chm? instruction
you pop the chm argument (`tstl (sp)+' or `addl2 $4,sp') and execute an
`rei' (the semantics of rei are horribly complicated; see a VAX
architecture manual).  The BSD kernel takes advantage of the register
save mask to get the user's registers saved at entry to syscall()
itself.  (They are thus on the stack and can be modified and will be
reloaded on return automatically.)

The Tahoe has a `kcall' instruction.  It works a lot like the VAX chmk.

The 680x0 has 16 `trap' instructions.  (Well, actually one, with a
parameter in the range 0..15.)  The OS author decides to use one for
system calls, and chooses how to encode the calls.  SunOS, HPUX, and
Utah's HP-BSD all use trap 0 and put the system call number in d0 (with
the rest of the parameters on the stack).  The trap switches to kernel
mode (thus getting the kernel stack pointer), pushes the pc (4 bytes)
and the sr (2 bytes), and jumps through the trap vector.  The BSD
trap-0 vector clears another 2 bytes to realign the stack (important on
the 680[234]0 for performance), then pushes all the user's registers
with `moveml #0xffff,sp@-'.  The BSD kernel then saves the user SP (the
moveml pushed the kernel stack pointer) and pushes the system call
number again (!) and calls syscall().  It then pops the system call
number, reloads the user stack pointer, does a `moveml sp@+,#0x7fff' to
recover everything except the user stack pointer, adds 6 to sp to pop
the usp and the alignment word, and then jumps to a routine that fakes
a VAX `rei' (checking for pseudo ASTs: rather silly but a bit difficult
to clean up).

The SPARC has the `t' (trap) instruction, which has a 7-bit parameter
for (in effect) 128 trap instructions.  The OS author decides to use
one for system calls, and chooses how to encode the calls.  SunOS and
BSD both use software trap 0 and put the system call number in %g1,
with the rest of the parameters in the trapping routine's %o0..%o5.
(For the indir system call, the 7th parameter is found on the routine's
stack.  The usual case involves no memory traffic, however.)  All SPARC
traps, including interrupts, work the same way:  They decrement the
current window pointer in the psr, write the pc and npc into what are
now %l1 and %l2, copy the psr `S' (supervisor) bit into the `PS'
(previous supervisor) bit, clear the `ET' (enable traps) bit, and set
pc and npc---npc is the `next' pc, exposed due to delayed branches
---to the trap base register plus 16 times the trap vector index.
(Software traps start at 128 and go to 255.  Hardware traps use the
range 0..127.)  That is all that the hardware does: it does not set up
a kernel stack pointer, or save things to a stack.  The rest is up to
software.  My kernel:

      -	branches to syscall and saves %psr in %l0 in the delay slot;

      -	at syscall, invokes a hairy macro called TRAP_SETUP:
		if (trap came from kernel mode) { // i.e., psr<PS> is set
			if (we are in the trap window)
				save the trap window somewhere;
			%sp = %fp - stackspace; // here stackspace=80
		} else {
			compute the number of user windows;
			if (we are in the trap window)
				save the trap window somewhere;
			%sp = (top of kernel stack) - stackspace;
		}
	where the number of user windows is:
		cpcb->pcb_uw = (cpcb->pcb_wim - 1 - CWP) % nwindows
	which is computed via table lookup (the pcb_wim field is
	maintained by software; it is simply log2(%wim));

      -	enables traps, stores the saved psr (%l0), pc (%l1), npc (%l2),
	%y (read into %l3), the values of %g1 through %g7 and the
	caller's %o0 through %o7 (now our %i0..%i7) into the 80 bytes
	reserved above;

      -	calls syscall(), passing the address of the stuff just built
	on the kernel stack.

Note that it is possible, but wrong, to get a kernel mode system call.
Therefore, part of the work in TRAP_SETUP could be dispensed with, but
for the fact that the trap window must be saved anyway, even if we are
just going to panic.  Since the delay slot for that test is filled for
both cases, this is only a single instruction; the loss is minor.
The `save the trap window somewhere' is complicated but is done as a
subroutine (with linkage being stored in %l4, leaving only 3 registers
free in the save code in some cases, but that turns out to be *just*
enough).
-- 
In-Real-Life: Chris Torek, Lawrence Berkeley Lab CSE/EE (+1 415 486 5427)
Berkeley, CA		Domain:	torek@ee.lbl.gov

subbarao@phoenix.Princeton.EDU (Kartik Subbarao) (05/09/91)

In article <1991May9.015124.20638@casbah.acns.nwu.edu> craig@casbah.acns.nwu.edu (Craig Robinson) writes:
>For my operating systems class we are required to do the following project:
>
>"Groups of three students will design and develop a priority based
>multitasking kernel that provides for process control, process
>synchronization, and process communication.  The kernel will be developed in
>the C programming language and will run on top of the UNIX OS."
>
>This is the exact project specification as stated in our syllabus.  No
>more, no less is required.
>
>I have several questions I want to ask the gurus.
>
>1)  In what way would we be able to implement a quantum driven system?   
>How can we simulate clock interrupts?

Well, if you're running on TOP of unix, you may not even have to.

>2) In UNIX, what happens *at the CPU level* when a process makes a system
>call?  How does the processor know to switch from user to kernel mode?  How
>can we simulate this on top of UNIX?

When a process makes a system call, many architecturess support some
special instruction (it's "trap" on suns). This is a software interrupt,
so it indexes into a trap table stored somewhere in memory, and executes
whatever code is there. Normally, the OS sets up trap handlers at that
place in memory, so it can service the interrupt.

>Any other tips anyone can give me would be greatly appreciated, we only have
>about 3 more weeks until the due date, and we are all very confused about
>exactly how we are going to do this.

If you're interested in running on top of UNIX, some versions support
LightWeight processes. Lightweight processes appear as just one "process"
to UNIX, so they share the same address space. You can "fork" off threads
in this process, and they can communicate with each other, etc. SunOS has a
whole library to deal with them. I don't know about BSD.

Another way you could implement lwp's without an actual library is by using
setjmp() and longjump() to implement coroutines. Again, since you're
running on top of UNIX, you could steal some of its useful features (like
signals) for asynchronous communication.

I've just had a blast taking an OS course myself. We built a small OS with
sceduling, communication, pipes, the like on top of a bare SPARCstation
SLC. It was awesome :-)


		-Kartik


--
internet% ypwhich

subbarao@phoenix.Princeton.EDU -| Internet
kartik@silvertone.Princeton.EDU (NeXT mail)  
SUBBARAO@PUCC.BITNET			          - Bitnet

jfh@rpp386.cactus.org (John F Haugh II) (05/11/91)

In article <1991May9.015124.20638@casbah.acns.nwu.edu> craig@casbah.acns.nwu.edu (Craig Robinson) writes:
>For my operating systems class we are required to do the following project:
>
>"Groups of three students will design and develop a priority based
>multitasking kernel that provides for process control, process
>synchronization, and process communication.  The kernel will be developed in
>the C programming language and will run on top of the UNIX OS."
>
>This is the exact project specification as stated in our syllabus.  No
>more, no less is required.

You are taking an overly detailed view of the problem.  You have
exactly three things to do - design and implement some scam for
simulating processes and controlling them, design and implement
some scam for having those simulated processes talk to each other,
and finally, design and implement some scam for having these
simulated processes talk to each other.

I'm torn between saying your should be flunked for asking the
net, which I think is cheating, or given an A for asking the
net, which is what real people do when stumped ...

>Any other tips anyone can give me would be greatly appreciated, we only have
>about 3 more weeks until the due date, and we are all very confused about
>exactly how we are going to do this.

This project should be doable in one day of work by you and
your team mates.  Think =very= simple.
-- 
John F. Haugh II        | Distribution to  | UUCP: ...!cs.utexas.edu!rpp386!jfh
Ma Bell: (512) 255-8251 | GEnie PROHIBITED :-) |  Domain: jfh@rpp386.cactus.org
"If liberals interpreted the 2nd Amendment the same way they interpret the
 rest of the Constitution, gun ownership would be mandatory."

craig@casbah.acns.nwu.edu (Craig Robinson) (05/11/91)

In article <19260@rpp386.cactus.org> jfh@rpp386.cactus.org (John F Haugh II) writes:
>
>I'm torn between saying your should be flunked for asking the
>net, which I think is cheating, or given an A for asking the
>net, which is what real people do when stumped ...
>

I don't think it is cheating at all.  I didn't ask anybody for source code,
I just asked for ideas.  Like you said, I was stumped, so I went to the net
for resources, because I knew I could find them.  

The results I received from my question were not any step by step details
on how to do the project, but mostly like the answer I got from you, saying
that I was making the problem too complex.  As it turns out, you were
right, and it now seems fairly simple to me.  So, the only knowledge I
gained from the net was stuff that I really could not have learned from a
book, after all, my text book was what overwhelmed me in th first place.

I also received some good ideas about using the SunOS LWP library to do the
project.  All in all, I learned more than if I had not asked the question,
and that is the reason I'm going to college in the first place.


>-- 
>John F. Haugh II        | Distribution to  | UUCP: ...!cs.utexas.edu!rpp386!jfh
>Ma Bell: (512) 255-8251 | GEnie PROHIBITED :-) |  Domain: jfh@rpp386.cactus.org
>"If liberals interpreted the 2nd Amendment the same way they interpret the
> rest of the Constitution, gun ownership would be mandatory."

Craig

-- 
craig@acns.nwu.edu

phil@ux1.cso.uiuc.edu (Phil Howard KA9WGN) (05/11/91)

jfh@rpp386.cactus.org (John F Haugh II) writes:

>I'm torn between saying your should be flunked for asking the
>net, which I think is cheating, or given an A for asking the
>net, which is what real people do when stumped ...

Shouldn't all tests be "open book"?  Real life is that way, and in fact
people are encouraged (or should be) in ALL fields to be able to look up
information rather than simply memorize it.  There is way to much to
learn it all, so we all need the skill of knowing how to find what we
need.  The net is quite often a pretty good way, but I would not suggest
depending on it.

I'd flunk him for doing something like asking the net for CODE (or FTPing
it from somewhere).  Asking for help in understanding something is no
different than asking a tutor (we who answer become the tutors).
-- 
 /***************************************************************************\
/ Phil Howard -- KA9WGN -- phil@ux1.cso.uiuc.edu   |  Guns don't aim guns at  \
\ Lietuva laisva -- Brivu Latviju -- Eesti vabaks  |  people; CRIMINALS do!!  /
 \***************************************************************************/