[comp.os.minix] Protected mode MINIX for 80286 Part 9 - By Bruce Evans

worsley@ditmela.oz (Andrew Worsley) (05/18/89)

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 9 (of 10)."
# Contents:  kerneldif/system.c.cdif mmdif/alloc.c.cdif
#   mmdif/main.c.cdif toolsdif/fsck.c.cdif
# Wrapped by sys@besplex on Sun Mar 26 06:34:37 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'kerneldif/system.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kerneldif/system.c.cdif'\"
else
echo shar: Extracting \"'kerneldif/system.c.cdif'\" \(20205 characters\)
sed "s/^X//" >'kerneldif/system.c.cdif' <<'END_OF_FILE'
X*** kernel-1.3/system.c	Fri Oct  7 21:02:52 1988
X--- kernel/system.c	Thu Mar 23 23:13:35 1989
X***************
X*** 17,18 ****
X--- 17,21 ----
X   *   SYS_COPY	 requests a block of data to be copied between processes
X+  *   SYS_GBOOT	 copies the boot parameters to a process
X+  *   SYS_UMAP	 compute the physical address for a given virtual address
X+  *   SYS_MEM	 returns the next free chunk of physical memory 
X   *
X***************
X*** 36,37 ****
X--- 39,42 ----
X   * | SYS_ABORT  |         |         |         |         |
X+  * |------------+---------+---------+---------+---------|
X+  * | SYS_GBOOT  | proc nr |         |         | bootptr |
X   * ------------------------------------------------------
X***************
X*** 51,54 ****
X   * --------------------------------------------------------------------------
X   *
X!  * In addition to the main sys_task() entry point, there are three other minor
X   * entry points:
X--- 56,67 ----
X   * --------------------------------------------------------------------------
X+  * | SYS_UMAP   |  seg  |proc nr |vir adr|       |        |       | byte ct |
X+  * --------------------------------------------------------------------------
X   *
X!  *
X!  *    mem_type    DEVICE    PROC_NR    COUNT   POSITION
X!  * |------------+---------+---------+---------+---------|
X!  * | SYS_MEM    | extflag |         |mem size |mem base |
X!  * ------------------------------------------------------
X!  *
X!  * In addition to the main sys_task() entry point, there are 4 other minor
X   * entry points:
X***************
X*** 57,58 ****
X--- 70,72 ----
X   *   umap:	compute the physical address for a given virtual address
X+  *   alloc_segments: allocate segments for 8088 or higher processor
X   */
X***************
X*** 61,62 ****
X--- 75,77 ----
X  #include "../h/type.h"
X+ #include "../h/boot.h"
X  #include "../h/callnr.h"
X***************
X*** 69,70 ****
X--- 84,86 ----
X  #include "proc.h"
X+ #include "protect.h"
X  
X***************
X*** 72,73 ****
X--- 88,90 ----
X  
X+ extern phys_bytes check_mem();
X  extern phys_bytes umap();
X***************
X*** 100,101 ****
X--- 117,121 ----
X  	    case SYS_COPY:	r = do_copy(&m);	break;
X+ 	    case SYS_GBOOT:	r = do_gboot(&m);	break;
X+ 	    case SYS_UMAP:	r = do_umap(&m);	break;
X+ 	    case SYS_MEM:	r = do_mem(&m);		break;
X  	    default:		r = E_BAD_FCN;
X***************
X*** 113,143 ****
X  PRIVATE int do_fork(m_ptr)
X! message *m_ptr;			/* pointer to request message */
X  {
X! /* Handle sys_fork().  'k1' has forked.  The child is 'k2'. */
X  
X    register struct proc *rpc;
X!   register char *sptr, *dptr;	/* pointers for copying proc struct */
X!   int k1;			/* number of parent process */
X!   int k2;			/* number of child process */
X!   int pid;			/* process id of child */
X!   int bytes;			/* counter for copying proc struct */
X  
X!   k1 = m_ptr->PROC1;		/* extract parent slot number from msg */
X!   k2 = m_ptr->PROC2;		/* extract child slot number */
X!   pid = m_ptr->PID;		/* extract child process id */
X  
X-   if (k1 < 0 || k1 >= NR_PROCS || k2 < 0 || k2 >= NR_PROCS)return(E_BAD_PROC);
X-   rpc = proc_addr(k2);
X- 
X    /* Copy parent 'proc' struct to child. */
X!   sptr = (char *) proc_addr(k1);	/* parent pointer */
X!   dptr = (char *) proc_addr(k2);	/* child pointer */
X!   bytes = sizeof(struct proc);		/* # bytes to copy */
X!   while (bytes--) *dptr++ = *sptr++;	/* copy parent struct to child */
X  
X    rpc->p_flags |= NO_MAP;	/* inhibit the process from running */
X!   rpc->p_flags &= ~PENDING;	/* only one in group should have PENDING */
X    rpc->p_pending = 0;
X!   rpc->p_pid = pid;		/* install child's pid */
X!   rpc->p_reg[RET_REG] = 0;	/* child sees pid = 0 to know it is child */
X  
X--- 133,166 ----
X  PRIVATE int do_fork(m_ptr)
X! register message *m_ptr;	/* pointer to request message */
X  {
X! /* Handle sys_fork().  m_ptr->PROC1 has forked.  The child is m_ptr->PROC2. */
X  
X+ #ifdef i80286
X+   u16_t old_ldt_sel;
X+ #endif
X    register struct proc *rpc;
X!   struct proc *rpp;
X  
X!   if (!isoksusern(m_ptr->PROC1) || !isoksusern(m_ptr->PROC2))
X! 	return(E_BAD_PROC);
X!   rpp = proc_addr(m_ptr->PROC1);
X!   rpc = proc_addr(m_ptr->PROC2);
X  
X    /* Copy parent 'proc' struct to child. */
X! #ifdef i80286
X!   old_ldt_sel = rpc->p_ldt_sel;	/* stop this being obliterated by copy */
X! #endif
X!   *rpc = *rpp;
X!   rpc->p_nr = m_ptr->PROC2;	/* this was obliterated by copy */
X! #ifdef i80286
X!   rpc->p_ldt_sel = old_ldt_sel;
X! #endif
X  
X    rpc->p_flags |= NO_MAP;	/* inhibit the process from running */
X!   rpc->p_flags &= ~(PENDING | SIG_PENDING);
X! 				/* only one in group should have PENDING */
X    rpc->p_pending = 0;
X!   rpc->p_pendcount = 0;
X!   rpc->p_pid = m_ptr->PID;	/* install child's pid */
X!   rpc->p_reg.r16.retreg = 0;	/* child sees pid = 0 to know it is child*/
X  
X***************
X*** 171,173 ****
X    map_ptr = (struct mem_map *) m_ptr->MEM_PTR;
X!   if (k < -NR_TASKS || k >= NR_PROCS) return(E_BAD_PROC);
X    rp = proc_addr(k);		/* ptr to entry of user getting new map */
X--- 194,196 ----
X    map_ptr = (struct mem_map *) m_ptr->MEM_PTR;
X!   if (!isokprocn(k)) return(E_BAD_PROC);
X    rp = proc_addr(k);		/* ptr to entry of user getting new map */
X***************
X*** 180,196 ****
X  	panic("bad call to sys_newmap (src)", NO_NUM);
X!   if ( (dst_phys = umap(proc_addr(SYSTASK), D, vsys, vn)) == 0)
X  	panic("bad call to sys_newmap (dst)", NO_NUM);
X    phys_copy(src_phys, dst_phys, pn);
X! 
X! #ifdef i8088
X!   /* On 8088, set segment registers. */
X!   rp->p_reg[CS_REG] = rp->p_map[T].mem_phys;	/* set cs */
X!   rp->p_reg[DS_REG] = rp->p_map[D].mem_phys;	/* set ds */
X!   rp->p_reg[SS_REG] = rp->p_map[D].mem_phys;	/* set ss */
X!   rp->p_reg[ES_REG] = rp->p_map[D].mem_phys;	/* set es */
X! #endif
X! 
X    old_flags = rp->p_flags;	/* save the previous value of the flags */
X    rp->p_flags &= ~NO_MAP;
X!   if (old_flags != 0 && rp->p_flags == 0) ready(rp);
X    return(OK);
X--- 203,211 ----
X  	panic("bad call to sys_newmap (src)", NO_NUM);
X!   if ( (dst_phys = umap(cproc_addr(SYSTASK), D, vsys, vn)) == 0)
X  	panic("bad call to sys_newmap (dst)", NO_NUM);
X    phys_copy(src_phys, dst_phys, pn);
X!   alloc_segments(rp);
X    old_flags = rp->p_flags;	/* save the previous value of the flags */
X    rp->p_flags &= ~NO_MAP;
X!   if (old_flags != 0 && rp->p_flags == 0) lockready(rp);
X    return(OK);
X***************
X*** 203,205 ****
X  PRIVATE int do_exec(m_ptr)
X! message *m_ptr;			/* pointer to request message */
X  {
X--- 218,220 ----
X  PRIVATE int do_exec(m_ptr)
X! register message *m_ptr;	/* pointer to request message */
X  {
X***************
X*** 208,222 ****
X    register struct proc *rp;
X-   int k;			/* which process */
X    int *sp;			/* new sp */
X  
X!   k = m_ptr->PROC1;		/* 'k' tells which process did EXEC */
X!   sp = (int *) m_ptr->STACK_PTR;
X!   if (k < 0 || k >= NR_PROCS) return(E_BAD_PROC);
X!   rp = proc_addr(k);
X!   rp->p_sp = sp;		/* set the stack pointer */
X!   rp->p_pcpsw.pc = (int (*)()) 0;	/* reset pc */
X    rp->p_alarm = 0;		/* reset alarm timer */
X    rp->p_flags &= ~RECEIVING;	/* MM does not reply to EXEC call */
X!   if (rp->p_flags == 0) ready(rp);
X!   set_name(k, (char *)sp);	/* save command string for F1 display */
X    return(OK);
X--- 223,235 ----
X    register struct proc *rp;
X    int *sp;			/* new sp */
X  
X!   sp = (int *) m_ptr->STACK_PTR;	/* bad ptr type */
X!   if (!isoksusern(m_ptr->PROC1)) return E_BAD_PROC;
X!   rp = proc_addr(m_ptr->PROC1);
X!   rp->p_reg.r16.sp = (u16_t) sp;	/* set the stack pointer (bad type) */
X!   rp->p_reg.r16.pc = 0;		/* reset pc */
X    rp->p_alarm = 0;		/* reset alarm timer */
X    rp->p_flags &= ~RECEIVING;	/* MM does not reply to EXEC call */
X!   if (rp->p_flags == 0) lockready(rp);
X!   set_name(m_ptr->PROC1, (char *)sp); /* save command string for F1 display */
X    return(OK);
X***************
X*** 240,242 ****
X    proc_nr = m_ptr->PROC2;	/* slot number of exiting process */
X!   if (parent < 0 || parent >= NR_PROCS || proc_nr < 0 || proc_nr >= NR_PROCS)
X  	return(E_BAD_PROC);
X--- 253,255 ----
X    proc_nr = m_ptr->PROC2;	/* slot number of exiting process */
X!   if (!isoksusern(parent) || !isoksusern(proc_nr))
X  	return(E_BAD_PROC);
X***************
X*** 244,249 ****
X    rc = proc_addr(proc_nr);
X    rp->child_utime += rc->user_time + rc->child_utime;	/* accum child times */
X    rp->child_stime += rc->sys_time + rc->child_stime;
X    rc->p_alarm = 0;		/* turn off alarm timer */
X!   if (rc->p_flags == 0) unready(rc);
X    set_name(proc_nr, (char *) 0);	/* disable command printing for F1 */
X--- 257,264 ----
X    rc = proc_addr(proc_nr);
X+   lock();
X    rp->child_utime += rc->user_time + rc->child_utime;	/* accum child times */
X    rp->child_stime += rc->sys_time + rc->child_stime;
X+   unlock();
X    rc->p_alarm = 0;		/* turn off alarm timer */
X!   if (rc->p_flags == 0) lockunready(rc);
X    set_name(proc_nr, (char *) 0);	/* disable command printing for F1 */
X***************
X*** 256,258 ****
X  	/* Check all proc slots to see if the exiting process is queued. */
X! 	for (rp = &proc[0]; rp < &proc[NR_TASKS + NR_PROCS]; rp++) {
X  		if (rp->p_callerq == NIL_PROC) continue;
X--- 271,273 ----
X  	/* Check all proc slots to see if the exiting process is queued. */
X! 	for (rp = BEG_PROC_ADDR; rp < END_PROC_ADDR; rp++) {
X  		if (rp->p_callerq == NIL_PROC) continue;
X***************
X*** 276,277 ****
X--- 291,294 ----
X    if (rc->p_flags & PENDING) --sig_procs;
X+   rc->p_pending = 0;
X+   rc->p_pendcount = 0;
X    rc->p_flags = P_SLOT_FREE;
X***************
X*** 285,287 ****
X  PRIVATE int do_getsp(m_ptr)
X! message *m_ptr;			/* pointer to request message */
X  {
X--- 302,304 ----
X  PRIVATE int do_getsp(m_ptr)
X! register message *m_ptr;		/* pointer to request message */
X  {
X***************
X*** 290,297 ****
X    register struct proc *rp;
X-   int k;				/* whose stack pointer is wanted? */
X  
X!   k = m_ptr->PROC1;
X!   if (k < 0 || k >= NR_PROCS) return(E_BAD_PROC);
X!   rp = proc_addr(k);
X!   m.STACK_PTR = (char *) rp->p_sp;	/* return sp here */
X    return(OK);
X--- 307,312 ----
X    register struct proc *rp;
X  
X!   if (!isoksusern(m_ptr->PROC1)) return(E_BAD_PROC);
X!   rp = proc_addr(m_ptr->PROC1);
X!   m.STACK_PTR = (char *) rp->p_reg.r16.sp;	/* return sp here (bad t) */
X    return(OK);
X***************
X*** 304,306 ****
X  PRIVATE int do_times(m_ptr)
X! message *m_ptr;			/* pointer to request message */
X  {
X--- 319,321 ----
X  PRIVATE int do_times(m_ptr)
X! register message *m_ptr;	/* pointer to request message */
X  {
X***************
X*** 309,319 ****
X    register struct proc *rp;
X-   int k;
X  
X!   k = m_ptr->PROC1;		/* k tells whose times are wanted */
X!   if (k < 0 || k >= NR_PROCS) return(E_BAD_PROC);
X!   rp = proc_addr(k);
X  
X    /* Insert the four times needed by the TIMES system call in the message. */
X    m_ptr->USER_TIME   = rp->user_time;
X    m_ptr->SYSTEM_TIME = rp->sys_time;
X    m_ptr->CHILD_UTIME = rp->child_utime;
X--- 324,334 ----
X    register struct proc *rp;
X  
X!   if (!isoksusern(m_ptr->PROC1)) return E_BAD_PROC;
X!   rp = proc_addr(m_ptr->PROC1);
X  
X    /* Insert the four times needed by the TIMES system call in the message. */
X+   lock();
X    m_ptr->USER_TIME   = rp->user_time;
X    m_ptr->SYSTEM_TIME = rp->sys_time;
X+   unlock();
X    m_ptr->CHILD_UTIME = rp->child_utime;
X***************
X*** 353,360 ****
X    proc_nr = m_ptr->PR;		/* process being signalled */
X    sig = m_ptr->SIGNUM;		/* signal number, 1 to 16 */
X    sig_handler = m_ptr->FUNC;	/* run time system addr for catching sigs */
X-   if (proc_nr < LOW_USER || proc_nr >= NR_PROCS) return(E_BAD_PROC);
X-   rp = proc_addr(proc_nr);
X    vir_addr = (vir_bytes) sig_stuff;	/* info to be pushed is in 'sig_stuff' */
X!   new_sp = (vir_bytes) rp->p_sp;
X  
X--- 368,383 ----
X    proc_nr = m_ptr->PR;		/* process being signalled */
X+   if (!isokusern(proc_nr)) return(E_BAD_PROC);
X+   rp = proc_addr(proc_nr);
X    sig = m_ptr->SIGNUM;		/* signal number, 1 to 16 */
X+   if (sig == -1) {
X+ 	/* Except -1 is kludged to mean "finished one KSIG". */
X+ 	if (rp->p_pendcount != 0 &&
X+ 	    --rp->p_pendcount == 0 &&
X+ 	    (rp->p_flags &= ~SIG_PENDING) == 0)
X+ 		lockready(rp);
X+ 	return;
X+   }
X    sig_handler = m_ptr->FUNC;	/* run time system addr for catching sigs */
X    vir_addr = (vir_bytes) sig_stuff;	/* info to be pushed is in 'sig_stuff' */
X!   new_sp = (vir_bytes) rp->p_reg.r16.sp;
X  
X***************
X*** 372,375 ****
X    /* Change process' sp and pc to reflect the interrupt. */
X!   rp->p_sp = (int *) new_sp;
X!   rp->p_pcpsw.pc = sig_handler;
X    return(OK);
X--- 395,398 ----
X    /* Change process' sp and pc to reflect the interrupt. */
X!   rp->p_reg.r16.sp = new_sp;
X!   rp->p_reg.r16.pc = (u16_t) sig_handler;	/* bad ptr type */
X    return(OK);
X***************
X*** 378,380 ****
X  
X! /*===========================================================================*
X   *				do_kill					     * 
X--- 401,403 ----
X  
X! /*===========================================================================
X   *				do_kill					     * 
X***************
X*** 391,393 ****
X    sig = m_ptr->SIGNUM;		/* signal number, 1 to 16 */
X!   if (proc_nr < LOW_USER || proc_nr >= NR_PROCS) return(E_BAD_PROC);
X    cause_sig(proc_nr, sig);
X--- 414,416 ----
X    sig = m_ptr->SIGNUM;		/* signal number, 1 to 16 */
X!   if (!isokusern(proc_nr)) return(E_BAD_PROC);
X    cause_sig(proc_nr, sig);
X***************
X*** 449,452 ****
X   * see if MM is free.  If so, a message is sent to it.  If not, when it becomes
X!  * free, a message is sent.  The calling process is blocked as long as
X!  * p_pending is non-zero.
X   */
X--- 472,478 ----
X   * see if MM is free.  If so, a message is sent to it.  If not, when it becomes
X!  * free, a message is sent.  The process being signaled is blocked while MM
X!  * has not seen or finished with all signals for it.  These signals are
X!  * counted in p_pendcount, and the SIG_PENDING flag is kept nonzero while
X!  * there are some.  It is not sufficient to ready the process when MM is
X!  * informed, because MM can block waiting for FS to do a core dump.
X   */
X***************
X*** 456,464 ****
X    rp = proc_addr(proc_nr);
X!   if ((rp->p_flags & PENDING) == 0)
X! 	sig_procs++;		/* incr if a new proc is now pending */
X!   if (rp->p_flags == 0) unready(rp);
X!   rp->p_flags |= PENDING;
X    rp->p_pending |= 1 << (sig_nr - 1);
X  
X!   mmp = proc_addr(MM_PROC_NR);
X    if ( ((mmp->p_flags & RECEIVING) == 0) || mmp->p_getfrom != ANY)
X--- 482,495 ----
X    rp = proc_addr(proc_nr);
X!   if (rp->p_pending & (1 << (sig_nr - 1)))
X! 	return;			/* this signal already pending */
X    rp->p_pending |= 1 << (sig_nr - 1);
X+   ++rp->p_pendcount;		/* count new signal pending */
X+   if (rp->p_flags & PENDING)
X+ 	return;			/* another signal already pending */
X+   if (rp->p_flags == 0)
X+ 	lockunready(rp);
X+   rp->p_flags |= PENDING | SIG_PENDING;
X+   ++sig_procs;			/* count new process pending */
X  
X!   mmp = cproc_addr(MM_PROC_NR);
X    if ( ((mmp->p_flags & RECEIVING) == 0) || mmp->p_getfrom != ANY)
X***************
X*** 484,496 ****
X    /* MM is waiting for new input.  Find a process with pending signals. */
X!   for (rp = proc_addr(0); rp < proc_addr(NR_PROCS); rp++)
X  	if (rp->p_flags & PENDING) {
X  		m.m_type = KSIG;
X! 		m.PROC1 = rp - proc - NR_TASKS;
X  		m.SIG_MAP = rp->p_pending;
X  		sig_procs--;
X! 		if (mini_send(HARDWARE, MM_PROC_NR, &m) != OK) 
X  			panic("can't inform MM", NO_NUM);
X  		rp->p_pending = 0;	/* the ball is now in MM's court */
X! 		rp->p_flags &= ~PENDING;
X! 		if (rp->p_flags == 0) ready(rp);
X  		return;
X--- 515,527 ----
X    /* MM is waiting for new input.  Find a process with pending signals. */
X!   for (rp = BEG_SERV_ADDR; rp < END_PROC_ADDR; rp++)
X  	if (rp->p_flags & PENDING) {
X  		m.m_type = KSIG;
X! 		m.PROC1 = proc_number(rp);
X  		m.SIG_MAP = rp->p_pending;
X  		sig_procs--;
X! 		if (lockmini_send(cproc_addr(HARDWARE), MM_PROC_NR, &m) != OK)
X  			panic("can't inform MM", NO_NUM);
X  		rp->p_pending = 0;	/* the ball is now in MM's court */
X! 		rp->p_flags &= ~PENDING;/* remains inhibited by SIG_PENDING */
X! 		lockpick_proc();	/* avoid delay in scheduling MM */
X  		return;
X***************
X*** 500,501 ****
X--- 531,534 ----
X  
X+ #ifdef i8088
X+ 
X  /*===========================================================================*
X***************
X*** 538 ****
X--- 571,689 ----
X  }
X+ 
X+ 
X+ /*==========================================================================*
X+  *				alloc_segments				    *
X+  *==========================================================================*/
X+ PUBLIC alloc_segments(rp)
X+ register struct proc *rp;
X+ {
X+ #ifdef i80286
X+   offset_t code_bytes;
X+   offset_t data_bytes;
X+   int privilege;
X+ 
X+   if (processor >= 286) {
X+ 	data_bytes = (offset_t)(rp->p_map[S].mem_vir + rp->p_map[S].mem_len)
X+ 	             << CLICK_SHIFT;
X+ 	if (rp->p_map[T].mem_len == 0)
X+ 		code_bytes = data_bytes;	/* common I&D, poor protect */
X+ 	else
X+ 		code_bytes = (offset_t) rp->p_map[T].mem_len << CLICK_SHIFT;
X+ 	privilege = istaskp(rp) ? TASK_PRIVILEGE : USER_PRIVILEGE;
X+ 	init_codeseg(&rp->p_ldt[CS_LDT_INDEX],
X+ 	             (offset_t) rp->p_map[T].mem_phys << CLICK_SHIFT,
X+ 	             code_bytes, privilege);
X+ 	init_dataseg(&rp->p_ldt[DS_LDT_INDEX],
X+ 	             (offset_t) rp->p_map[D].mem_phys << CLICK_SHIFT,
X+ 	             data_bytes, privilege);
X+ 	rp->p_reg.r16.cs = (CS_LDT_INDEX*DESC_SIZE) | TI | privilege;
X+ 	rp->p_reg.r16.ss =
X+ 	rp->p_reg.r16.es =
X+ 	rp->p_reg.r16.ds = (DS_LDT_INDEX*DESC_SIZE) | TI | privilege;
X+   }
X+   else
X+ #endif /* i80286 */
X+   {
X+ 	rp->p_reg.r16.cs = click_to_hclick(rp->p_map[T].mem_phys);
X+ 	rp->p_reg.r16.ss =
X+ 	rp->p_reg.r16.es =
X+ 	rp->p_reg.r16.ds = click_to_hclick(rp->p_map[D].mem_phys);
X+   }
X+ }
X+ #endif /* i8088 */
X+ 
X+ 
X+ /*==========================================================================*
X+  *				do_gboot				    *
X+  *==========================================================================*/
X+ PUBLIC struct bparam_s boot_parameters =  /* overwritten if new boot */
X+ {
X+   DROOTDEV, DRAMIMAGEDEV, DRAMSIZE, DSCANCODE, DPROCESSOR,
X+ };
X+ 
X+ PUBLIC unsigned sizeof_bparam = sizeof boot_parameters;	/* for asm to see */
X+ 
X+ PRIVATE int do_gboot(m_ptr)
X+ message *m_ptr;			/* pointer to request message */
X+ {
X+ /* Copy the boot parameters.  Normally only called during fs init. */
X+ 
X+   phys_bytes src_phys, dst_phys;
X+ 
X+   src_phys = umap(cproc_addr(SYSTASK), D, (vir_bytes) &boot_parameters,
X+                   (vir_bytes) sizeof boot_parameters);
X+   if ( (dst_phys = umap(proc_addr(m_ptr->PROC1), D,
X+                         (vir_bytes) m_ptr->MEM_PTR,
X+ 			(vir_bytes) sizeof boot_parameters)) == 0)
X+ 	panic("bad call to SYS_GBOOT", NO_NUM);
X+   phys_copy(src_phys, dst_phys, (phys_bytes) sizeof boot_parameters);
X+   return(OK);
X+ }
X+ 
X+ 
X+ /*==========================================================================*
X+  *				do_umap					    *
X+  *==========================================================================*/
X+ PRIVATE int do_umap(m_ptr)
X+ register message *m_ptr;		/* pointer to request message */
X+ {
X+ /* Same as umap(), for non-kernel processes. */
X+ 
X+   m_ptr->SRC_BUFFER = umap(proc_addr((int) m_ptr->SRC_PROC_NR),
X+                            (int) m_ptr->SRC_SPACE,
X+                            (vir_bytes) m_ptr->SRC_BUFFER,
X+                            (vir_bytes) m_ptr->COPY_BYTES);
X+   return(OK);
X+ }
X+ 
X+ 
X+ #ifdef i8088
X+ /*===========================================================================*
X+  *				do_mem					     *
X+  *===========================================================================*/
X+ PRIVATE int do_mem(m_ptr)
X+ register message *m_ptr;		/* pointer to request message */
X+ {
X+ /* Return the base and size of the next chunk of memory of a given type. */
X+ 
X+   unsigned mem;
X+ 
X+   for (mem = 0; mem < NR_MEMS; ++mem) {
X+ 	if (memtype[mem] & 0x80) {
X+ 	    memsize[mem] = check_mem((phys_bytes) membase[mem] << CLICK_SHIFT,
X+ 	                             (phys_bytes) memsize[mem] << CLICK_SHIFT)
X+ 	                   >> CLICK_SHIFT;
X+ 	    memtype[mem] &= ~0x80;
X+ 	}
X+ 	if (memsize[mem] != 0 && m_ptr->DEVICE == memtype[mem]) {
X+ 		m_ptr->COUNT = memsize[mem];
X+ 		m_ptr->POSITION = membase[mem];
X+ 		memsize[mem] = 0;	/* now MM has it */
X+ 		return(OK);
X+ 	}
X+   }
X+   m_ptr->COUNT = 0;		/* no more */
X+   m_ptr->POSITION = 0;
X+   return(OK);
X+ }
X+ #endif /* i8088 */
END_OF_FILE
if test 20205 -ne `wc -c <'kerneldif/system.c.cdif'`; then
    echo shar: \"'kerneldif/system.c.cdif'\" unpacked with wrong size!
fi
# end of 'kerneldif/system.c.cdif'
fi
if test -f 'mmdif/alloc.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'mmdif/alloc.c.cdif'\"
else
echo shar: Extracting \"'mmdif/alloc.c.cdif'\" \(3094 characters\)
sed "s/^X//" >'mmdif/alloc.c.cdif' <<'END_OF_FILE'
X*** mm-1.3/alloc.c	Wed Aug  3 21:18:01 1988
X--- mm/alloc.c	Fri Jan 13 08:55:47 1989
X***************
X*** 15,16 ****
X--- 15,17 ----
X   *   max_hole:	returns the largest hole currently available
X+  *   mem_left:	returns the sum of the sizes of all current holes
X   */
X***************
X*** 34,35 ****
X--- 35,38 ----
X  
X+ extern phys_clicks get_mem();
X+ 
X  /*===========================================================================*
X***************
X*** 201,204 ****
X   *===========================================================================*/
X! PUBLIC mem_init(clicks)
X! phys_clicks clicks;		/* amount of memory available */
X  {
X--- 204,206 ----
X   *===========================================================================*/
X! PUBLIC mem_init()
X  {
X***************
X*** 207,213 ****
X   * a linked list of table entries that are not in use.  Initially, the former
X!  * list has one entry, a single hole encompassing all of memory, and the second
X!  * list links together all the remaining table slots.  As memory becomes more
X!  * fragmented in the course of time (i.e., the initial big hole breaks up into
X!  * many small holes), new table slots are needed to represent them.  These
X!  * slots are taken from the list headed by 'free_slots'.
X   */
X--- 209,215 ----
X   * a linked list of table entries that are not in use.  Initially, the former
X!  * list has one entry for each chunk of physical memory, and the second
X!  * list links together the remaining table slots.  As memory becomes more
X!  * fragmented in the course of time (i.e., the initial big holes break up into
X!  * smaller holes), new table slots are needed to represent them.  These slots
X!  * are taken from the list headed by 'free_slots'.
X   */
X***************
X*** 215,224 ****
X    register struct hole *hp;
X  
X    for (hp = &hole[0]; hp < &hole[NR_HOLES]; hp++) hp->h_next = hp + 1;
X-   hole[0].h_next = NIL_HOLE;	/* only 1 big hole initially */
X    hole[NR_HOLES-1].h_next = NIL_HOLE;
X!   hole_head = &hole[0];
X!   free_slots = &hole[1];
X!   hole[0].h_base = 0;
X!   hole[0].h_len = clicks;
X  }
X--- 217,248 ----
X    register struct hole *hp;
X+   phys_clicks base;		/* base address of chunk */
X+   phys_clicks size;		/* size of chunk */
X  
X+   /* Put all holes on the free list. */
X    for (hp = &hole[0]; hp < &hole[NR_HOLES]; hp++) hp->h_next = hp + 1;
X    hole[NR_HOLES-1].h_next = NIL_HOLE;
X!   hole_head = NIL_HOLE;
X!   free_slots = &hole[0];
X! 
X!   /* Allocate a hole for each chunk of physical memory. */
X!   while ( (size = get_mem(&base, FALSE)) != 0)
X! 	free_mem(base, size);
X! }
X! 
X! 
X! /*===========================================================================*
X!  *				mem_left				     *
X!  *===========================================================================*/
X! PUBLIC phys_clicks mem_left()
X! {
X! /* Determine how much memory is left.  This procedure is called just after
X!  * initialization to find the original amount.
X!  */
X! 
X!   register struct hole *hp;
X!   phys_clicks tot;
X! 
X!   for (hp = hole_head, tot = 0; hp != NIL_HOLE; hp = hp->h_next)
X! 	tot += hp->h_len;
X!   return(tot);
X  }
END_OF_FILE
if test 3094 -ne `wc -c <'mmdif/alloc.c.cdif'`; then
    echo shar: \"'mmdif/alloc.c.cdif'\" unpacked with wrong size!
fi
# end of 'mmdif/alloc.c.cdif'
fi
if test -f 'mmdif/main.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'mmdif/main.c.cdif'\"
else
echo shar: Extracting \"'mmdif/main.c.cdif'\" \(5879 characters\)
sed "s/^X//" >'mmdif/main.c.cdif' <<'END_OF_FILE'
X*** mm-1.3/main.c	Wed Aug  3 21:18:03 1988
X--- mm/main.c	Sat Jan 28 10:48:48 1989
X***************
X*** 25,32 ****
X  
X- #define ENOUGH (phys_clicks) 4096	/* any # > max(FS size, INIT size) */
X- #define CLICK_TO_K (1024L/CLICK_SIZE)	/* convert clicks to K */
X- 
X- PRIVATE phys_clicks tot_mem;
X  extern (*call_vec[])();
X  
X  /*===========================================================================*
X--- 25,32 ----
X  
X  extern (*call_vec[])();
X+ extern phys_clicks alloc_mem();
X+ extern phys_clicks mem_left();
X  
X+ FORWARD phys_clicks get_mem();
X+ 
X  /*===========================================================================*
X***************
X*** 110,119 ****
X  
X!   extern phys_clicks get_tot_mem(), alloc_mem();
X  
X-   /* Find out how much memory the machine has and set up core map.  MM and FS
X-    * are part of the map.  Tell the kernel.
X-    */
X-   tot_mem = get_tot_mem();	/* # clicks in mem starting at absolute 0 */
X-   mem_init(tot_mem);		/* initialize tables to all physical mem */
X- 
X    /* Initialize MM's tables. */
X--- 110,113 ----
X  
X!   mem_init();			/* initialize tables to all physical mem */
X  
X    /* Initialize MM's tables. */
X***************
X*** 123,126 ****
X    procs_in_use = 3;
X- 
X-   /* Set stack limit, which is checked on every procedure call. */
X  }
X--- 117,118 ----
X***************
X*** 146,147 ****
X--- 138,140 ----
X    phys_clicks init_text_clicks, init_data_clicks;
X+   phys_clicks minix_clicks;
X  
X***************
X*** 149,164 ****
X  
X!   /* Remove the memory used by MINIX and RAM disk from the memory map. */
X    init_text_clicks = mm_in.m1_i1;	/* size of INIT in clicks */
X    init_data_clicks = mm_in.m1_i2;	/* size of INIT in clicks */
X-   tot_clicks = mm_in.m1_i3;		/* total size of MINIX + RAM disk */
X    init_org = (phys_clicks) mm_in.m1_p1;	/* addr where INIT begins in memory */
X    init_clicks = init_text_clicks + init_data_clicks;
X!   ram_base = init_org + init_clicks;	/* start of RAM disk */
X!   ram_clicks = tot_clicks - ram_base;	/* size of RAM disk */
X!   alloc_mem(tot_clicks);		/* remove RAM disk from map */
X  
X    /* Print memory information. */
X!   mem1 = tot_mem/CLICK_TO_K;
X!   mem2 = (ram_base + 512/CLICK_SIZE)/CLICK_TO_K;	/* MINIX, rounded */
X!   mem3 = ram_clicks/CLICK_TO_K;
X  #ifndef ATARI_ST
X--- 142,171 ----
X  
X!   /* Remove the memory used by MINIX from the memory map. */
X    init_text_clicks = mm_in.m1_i1;	/* size of INIT in clicks */
X    init_data_clicks = mm_in.m1_i2;	/* size of INIT in clicks */
X    init_org = (phys_clicks) mm_in.m1_p1;	/* addr where INIT begins in memory */
X    init_clicks = init_text_clicks + init_data_clicks;
X!   minix_clicks = init_org + init_clicks;	/* size of system in clicks */
X!   ram_base = alloc_mem(minix_clicks);	/* remove MINIX from map */
X!   if (ram_base != 0)
X! 	panic("inconsistent system memory base", ram_base);
X  
X+   /* Remove the memory used by the RAM disk from the memory map. */
X+   tot_clicks = mm_in.m1_i3;		/* total size of MINIX + RAM disk */
X+   ram_clicks = tot_clicks - minix_clicks;	/* size of RAM disk */
X+ #ifdef i8088
X+   /* Put RAM disk in extended memory, if any. */
X+   if (get_mem(&ram_base, TRUE) >= ram_clicks)
X+ 	goto got_base;
X+ #endif
X+   ram_base = alloc_mem(ram_clicks);	/* remove the RAM disk from the map */
X+   if (ram_base == NO_MEM)
X+ 	panic("not enough memory for RAM disk", NO_NUM);
X+ got_base:
X+   mm_out.POSITION = (phys_bytes) ram_base * CLICK_SIZE;	/* tell FS where */
X+ 
X    /* Print memory information. */
X!   mem1 = click_to_round_k(minix_clicks + ram_clicks + mem_left());  
X!   mem2 = click_to_round_k(minix_clicks);
X!   mem3 = click_to_round_k(ram_clicks);
X  #ifndef ATARI_ST
X***************
X*** 195,198 ****
X  #ifdef ATARI_ST
X  /*===========================================================================*
X!  *				get_tot_mem				     *
X   *===========================================================================*/
X--- 202,210 ----
X  #ifdef ATARI_ST
X+ /* This should be moved to the kernel, like the PC version.  It has already
X+  * been modified to match the other changes, but won't compile as is since
X+  * there this file also contains the preferred version of get_mem() (which
X+  * doesn't deserve #ifdef i8088).
X+  */
X  /*===========================================================================*
X!  *				get_mem					     *
X   *===========================================================================*/
X***************
X*** 202,207 ****
X   */
X! PUBLIC phys_clicks get_tot_mem()
X  {
X    long i;
X  
X    if (mem_copy(
X--- 214,225 ----
X   */
X! PRIVATE phys_clicks get_mem(pbase, extflag)
X! phys_clicks *pbase;		/* where to return the base */
X! int extflag;			/* nonzero for extended memory */
X  {
X    long i;
X+   static unsigned already;
X  
X+   *pbase = 0;
X+   if (already) return(0);	/* only one chunk */
X+   already = TRUE;
X    if (mem_copy(
X***************
X*** 215 ****
X--- 233,255 ----
X  #endif
X+ 
X+ 
X+ /*===========================================================================*
X+  *				get_mem					     *
X+  *===========================================================================*/
X+ PUBLIC phys_clicks get_mem(pbase, extflag)
X+ phys_clicks *pbase;		/* where to return the base */
X+ int extflag;			/* nonzero for extended memory */
X+ {
X+ /* Ask kernel for the next chunk of memory.  'extflag' specifies the type of
X+  * memory.  "Extended" memory here means memory above 1MB which is no good
X+  * for putting programs in but usable for the RAM disk.  MM doesn't care
X+  * about the locations of the 2 types of memory, except memory above 1MB is
X+  * unreachable unless CLICK_SIZE > 16, but still usable for the RAM disk.
X+  */
X+   mm_out.m_type = SYS_MEM;
X+   mm_out.DEVICE = extflag;
X+   if (sendrec(SYSTASK, &mm_out) != OK || mm_out.m_type != OK)
X+ 	panic("Kernel didn't respond to get_mem", NO_NUM);
X+   *pbase = (phys_clicks) mm_out.POSITION;
X+   return((phys_clicks) mm_out.COUNT);
X+ }
END_OF_FILE
if test 5879 -ne `wc -c <'mmdif/main.c.cdif'`; then
    echo shar: \"'mmdif/main.c.cdif'\" unpacked with wrong size!
fi
# end of 'mmdif/main.c.cdif'
fi
if test -f 'toolsdif/fsck.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'toolsdif/fsck.c.cdif'\"
else
echo shar: Extracting \"'toolsdif/fsck.c.cdif'\" \(5747 characters\)
sed "s/^X//" >'toolsdif/fsck.c.cdif' <<'END_OF_FILE'
X*** tools-1.3/fsck.c	Thu Oct  6 23:01:16 1988
X--- tools/fsck.c	Fri Mar  3 00:41:29 1989
X***************
X*** 45,46 ****
X--- 45,53 ----
X  
X+ #ifdef STANDALONE
X+ #  include "../h/boot.h"
X+ struct bparam_s boot_parameters =
X+   { DROOTDEV, DRAMIMAGEDEV, DRAMSIZE, DSCANCODE, DPROCESSOR };
X+ char *ramimname = "/dev/fd0";
X+ char *rootname = "/dev/ram";
X+ #endif
X  
X***************
X*** 53,56 ****
X  
X! #define quote(x)	x
X! #define nextarg(t)	(*argp.quote(u_)t++)
X  
X--- 60,62 ----
X  
X! #define nextarg(t)	(*argp.t++)
X  
X***************
X*** 289,303 ****
X  			case 'c':
X! 			case 'C':  prc(nextarg(char));		break;
X! 			case 'b':  prn(unsigned,  2, 0);	break;
X! 			case 'B':  prn(long,      2, 0);	break;
X! 			case 'o':  prn(unsigned,  8, 0);	break;
X! 			case 'O':  prn(long,      8, 0);	break;
X! 			case 'd':  prn(int,      10, 1);	break;
X! 			case 'D':  prn(long,     10, 1);	break;
X! 			case 'u':  prn(unsigned, 10, 0);	break;
X! 			case 'U':  prn(long,     10, 0);	break;
X! 			case 'x':  prn(unsigned, 16, 0);	break;
X! 			case 'X':  prn(long,     16, 0);	break;
X  			case 's':
X! 			case 'S':  s = nextarg(charp);
X  				   while (*s) prc(*s++);	break;
X--- 295,309 ----
X  			case 'c':
X! 			case 'C':  prc(nextarg(u_char));	break;
X! 			case 'b':  prn(u_unsigned,  2, 0);	break;
X! 			case 'B':  prn(u_long,      2, 0);	break;
X! 			case 'o':  prn(u_unsigned,  8, 0);	break;
X! 			case 'O':  prn(u_long,      8, 0);	break;
X! 			case 'd':  prn(u_int,      10, 1);	break;
X! 			case 'D':  prn(u_long,     10, 1);	break;
X! 			case 'u':  prn(u_unsigned, 10, 0);	break;
X! 			case 'U':  prn(u_long,     10, 0);	break;
X! 			case 'x':  prn(u_unsigned, 16, 0);	break;
X! 			case 'X':  prn(u_long,     16, 0);	break;
X  			case 's':
X! 			case 'S':  s = nextarg(u_charp);
X  				   while (*s) prc(*s++);	break;
X***************
X*** 1817,1821 ****
X  		printf("\nHit key as follows:\n\n");
X! 		printf("    =  start MINIX (root file system in drive 0)\n");
X! 		printf("    u  start MINIX on PS/2 Model 30, U.S. keyboard (root file sys in drive 0)\n");
X! 		printf("    d  start MINIX on PS/2 Model 30, Dutch keyboard (root file sys in drive 0)\n");
X  		printf("    f  check the file system (first insert any file system diskette)\n");
X--- 1823,1838 ----
X  		printf("\nHit key as follows:\n\n");
X! 		printf("    =  start MINIX, standard keyboard\n");
X! 		printf("    u  start MINIX, U.S. keyboard\n");
X! 		printf("    d  start MINIX, Dutch keyboard\n\n");
X! 		printf("    r  select root device (now %s)\n", rootname);
X! 		printf("    i  select RAM image device (now %s)%s\n",
X! 		       ramimname,
X! 		       boot_parameters.bp_rootdev == DEV_RAM ?
X! 		       "" : " (not used - root is not RAM disk)");
X! 		printf("    s  set RAM disk size (now %u)%s\n",
X! 		       boot_parameters.bp_ramsize,
X! 		       boot_parameters.bp_rootdev == DEV_RAM ?
X! 		       " (real size is from RAM image)" : "");
X! 		printf("    p  set limit on processor type (now %u)\n\n",
X! 		       boot_parameters.bp_processor);
X  		printf("    f  check the file system (first insert any file system diskette)\n");
X***************
X*** 1868,1872 ****
X  			
X! 		case '=': return((c >> 8) & 0xFF);
X! 		case 'u': return((c >> 8) & 0xFF);
X! 		case 'd': return((c >> 8) & 0xFF);
X  		default:
X--- 1885,1913 ----
X  			
X! 		case '=':
X! 		case 'u':
X! 		case 'd':
X! 			return(boot_parameters.bp_scancode = (c >> 8) & 0xFF);
X! 
X! 		case 'i':
X! 			boot_parameters.bp_ramimagedev =
X! 			get_device(&ramimname, "ram image", 0);
X! 			printf("\n\n");
X! 			continue;
X! 
X! 		case 'p':
X! 			boot_parameters.bp_processor = get_processor();
X! 			printf("\n\n");
X! 			continue;
X! 
X! 		case 'r':
X! 			boot_parameters.bp_rootdev =
X! 			get_device(&rootname, "root", 1);
X! 			printf("\n\n");
X! 			continue;
X! 
X! 		case 's':
X! 			boot_parameters.bp_ramsize = get_ramsize();
X! 			printf("\n\n");
X! 			continue;
X! 
X  		default:
X***************
X*** 1984,1985 ****
X--- 2025,2122 ----
X  }
X+ 
X+ #ifdef STANDALONE
X+ 
X+ int get_device(pname, description, ram_allowed)
X+ char **pname;
X+ char *description;
X+ int ram_allowed;
X+ {
X+   char chr;
X+   static char *devname[] = {
X+ 	"/dev/fd0",
X+ 	"/dev/fd1",
X+ 	"/dev/hd1",
X+ 	"/dev/hd2",
X+ 	"/dev/hd3",
X+ 	"/dev/hd4",
X+ 	"",
X+ 	"/dev/hd6",
X+ 	"/dev/hd7",
X+ 	"/dev/hd8",
X+ 	"/dev/hd9",
X+   };
X+   printf("\nPlease enter (abbreviated) name of %s device.\n", description);
X+   printf("Floppy f0, f1, hard h1 to h4, h6 to h9");
X+   if (ram_allowed)
X+ 	printf (", RAM r");
X+   printf(".\nThen hit RETURN: ");
X+   while (1) {
X+ 	switch(chr = getc()) {
X+ 	case 'f':
X+ 		putc(chr);
X+ 		while ((chr = getc()) < '0' || chr > '1')
X+ 			;
X+ 		putc(chr);
X+ 		getnewline();
X+ 		*pname = devname[chr - '0'];
X+ 		return DEV_FD0 + chr - '0';
X+ 	case 'h':
X+ 		putc(chr);
X+ 		while (((chr = getc()) < '1' || chr > '4') &&
X+ 				  (chr < '6' || chr > '9'))
X+ 			;
X+ 		putc(chr);
X+ 		getnewline();
X+ 		*pname = devname[chr +  1 - '0'];
X+ 		return DEV_HD0 + chr - '0';
X+ 	case 'r':
X+ 		if (ram_allowed) {
X+ 			putc(chr);
X+ 			getnewline();
X+ 			*pname = "/dev/ram";
X+ 			return DEV_RAM;
X+ 		}
X+ 	}
X+   }
X+ }
X+ 
X+ getnewline()
X+ {
X+ 	while ((char) getc() != '\r')
X+ 		;
X+ 	putc('\n');
X+ }
X+ 
X+ int get_processor()
X+ {
X+   printf("\nPlease enter limit on processor type. Then hit RETURN: ");
X+   return get_size();
X+ }
X+ 
X+ int get_ramsize()
X+ {
X+   printf("\nPlease enter size of RAM disk. Then hit RETURN: ");
X+   return get_size();
X+ }
X+ 
X+ int get_size()
X+ {
X+   char chr;
X+   long size;
X+ 
X+   while ((chr = getc()) < '0' || chr > '9')
X+ 	;
X+   size = chr - '0';
X+   putc(chr);
X+   while ((chr = getc()) != '\r') {
X+ 	if (chr >= '0' && chr <= '9' && 10 * size + (chr - '0') < 0x10000) {
X+ 		putc(chr);
X+ 		size = 10 * size + (chr - '0');
X+ 	}
X+   }
X+   putc('\n');
X+   return size;
X+ }
X+ 
X+ #endif /* STANDALONE */
X  
END_OF_FILE
if test 5747 -ne `wc -c <'toolsdif/fsck.c.cdif'`; then
    echo shar: \"'toolsdif/fsck.c.cdif'\" unpacked with wrong size!
fi
# end of 'toolsdif/fsck.c.cdif'
fi
echo shar: End of archive 9 \(of 10\).
cp /dev/null ark9isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 10 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Division of Information Technology (Melbourne), Phone +61 3 347 8644
C.S.I.R.O.                                      Fax  +61 3 347 8987
55 Barry St.                                    Telex AA 152914
Carlton, Vic, 3053, Australia                   E-mail: worsley@ditmela.oz.au