Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: utzoo!mnetor!seismo!lll-lcc!mordor!styx!lognet2!ames!rutgers!clyde!cbatt!ihnp4!inuxc!iuvax!jec
From: jec@iuvax.indiana.EDU
Newsgroups: comp.sys.atari.st
Subject: Re: Forwarded message (MINIX)
Message-ID: <117900011@iuvax>
Date: Mon, 5-Jan-87 20:05:00 EST
Article-I.D.: iuvax.117900011
Posted: Mon Jan  5 20:05:00 1987
Date-Received: Wed, 7-Jan-87 00:50:09 EST
References: <2771@mit-hermes.AI.MIT.EDU>
Lines: 98
Nf-ID: #R:mit-hermes.AI.MIT.EDU:2771:iuvax:117900011:000:4447
Nf-From: iuvax.indiana.EDU!jec    Jan  5 20:05:00 1987


	Okay, I give up.  How in the world do you do a fork() without some
sort of MMU.  Let me review how I think fork() works just in case I'm wrong.

	Fork() takes a process image-- text, bss, data, and stack and makes
a new process image.

	Two alternatives:

	(1) Allowing the process to be moved after loading:

	Okay, now, you can share the text, that is no problem.  This is
even a good idea since programs may have absolute addresses in them.  The
bss, well, no you can't share that.  So you have to make a separate copy
of it.  Ditto for data and stack.  But wait!  What do you do about all of
those nasty absolute addresses on the stack!?!

	Well, obviously you have to make those addresses relative.

	Okay, what do you make them relative too:  simple, the start of the
text segment.  We can just decide that all of our addresses are going to be
relative to the start of the text segment and we'll just load that in one
of the A registers and address off that.  Uh, wait a minute, that gives us
a 32K address space!  A slight deficiency of the 68000. Okay, we'll bite 
the bullet and do the arithmetic of adding it.  That won't be too bad, 
only >TWO< instructions per memory address:

	MOVEA.L	,A5	; the OS could do this, but then again, we 
				; don't have a three pronged ADD anyway so
				; we might as well load it.
	ADDA.L	,A5	; plus the relative address
	MOVEA.L	(A5),D0		; the thing we want

	Now we have another problem:  what happens when we get swapped out!
This needs to be an atomic operation!  Well, another few instructions:

			CLR.B	SWAPPABLE	; don't swap
				.
				.
			ADDQ.B	#1,SWAPPABLE	; okay, it's cool

	And we just don't swap when it says we can't.  If we were really
ingenious we could steal the single step interrupt vector and walk through
instructions until we can swap.

	But the obvious response to this is...YYUUUCCCCCK!  >FIVE< 
instructions per memory access, not to mention the C compiler would need to
be drastically changed to support this.  

(2)	STATIC LOADING

	Okay, now for the alternative:  the running process gets put in a
FIXED memory location.  We can swap to memory most of the time if we have
enough of it and we don't have to screw around with weird addresses.  This
is the only solution that I can think of and it makes context switches VERY
expensive.  

	Okay, now for an 'optimization':  we dynamically allocate the process'
load address when it is exec()'ed.  This wins in that we don't have to move
a process on EVERY context switch.  The problem is, of course, fragmentation
and an extremely complex process scheduler/exec().  Also, a forked() process
will have to share the same load address.  This is bad, but unavoidable--
especially when you consider /etc/init which forks for every tty that has a
getty on it.

	An MMU is a >BIG HUGH ENORMOUS< win when it comes to multi-tasking,
by the way, because it allows you to do offset addressing in hardware.  You
don't have to worry about moving processes in memory, you diddle the pointers
to make it look right to the program-- the OS does with with probably about
30 machine language instructions.

	The Amiga manages to multi-task by using the static loading method.
From experience let me tell you that fragmentation is a real problem with
this method.  You can have 300K free and not be able to load a 50K program.
The Amiga also does not do swapping and so fork() is probably impossible.
I don't know how the Atari does it with MT Shell, but I imagine it isn't
much better.

	Okay, there you have it.  How I think MINIX would have to work on a
68000 w/o an MMU.  I've actually given this some serious thought having tried
to port a V7 kernel to the 68000.  Our solution was to modify the hardware and
put in an MMU (the sleazy 68451 at that-- better than nothing).  Another time
I was looking into a kernel for the 68000 that would allow relocation of the
executable objects.  It is possible, but is very expensive and puts serious
limits on the programmer (especially the assembly language program that has
to deal with all the weirdness of SWAP/CANTSWAP).


    III          Usenet:     iuvax!jec
UUU  I  UUU		     jec@indiana.csnet
 U   I   U
 U   I   U       Phone:      (812) 335-5561
 U   I   U       U.S. Mail:  Indiana University                   
  UUUIUUU                    Dept. of Computer Science
     I           	     021-C Lindley Hall
    III                      Bloomington, IN. 47405