]> Zhao Yanbai Git Server - minix.git/commitdiff
- Fixed comments in various system call handlers. Work in progress on new
authorJorrit Herder <jnherder@minix3.org>
Thu, 21 Jul 2005 18:36:40 +0000 (18:36 +0000)
committerJorrit Herder <jnherder@minix3.org>
Thu, 21 Jul 2005 18:36:40 +0000 (18:36 +0000)
  sys_privctl() call to dynamically start servers and drivers.

- Shutdown sequence slightly adjusted: called as watchdog timer to let the
  busy sys_abort() call from the PM return first.

- Changed umap_bios() to have more restrictive check: BIOS memory is now
  allowed in BIOS_MEM_BEGIN to END (interrupt vectors) and BASE_MEM_TOP
  to UPPER_MEM_END. Hopefully this keeps QEMU and Bochs happy.

22 files changed:
kernel/config.h
kernel/main.c
kernel/proc.c
kernel/proc.h
kernel/proto.h
kernel/system.c
kernel/system.h
kernel/system/Makefile
kernel/system/do_abort.c
kernel/system/do_alarm.c
kernel/system/do_copy.c
kernel/system/do_devio.c
kernel/system/do_exit.c
kernel/system/do_fork.c
kernel/system/do_getinfo.c
kernel/system/do_memset.c
kernel/system/do_sigreturn.c
kernel/system/do_sigsend.c
kernel/system/do_vcopy.c
kernel/system/do_vdevio.c
kernel/table.c
kernel/utility.c

index eb5676b8e2ecaca218985fff5437b1c3ca29e10d..82d27f936e79cb5ffff369088023f3b9c1f3f89d 100644 (file)
@@ -33,7 +33,7 @@
 #define USE_SDEVIO             1       /* perform I/O request on a buffer */
 #define USE_IRQCTL             1       /* set an interrupt policy */
 #define USE_SEGCTL             1       /* set up a remote segment */
-#define USE_SVRCTL             1       /* system server control */
+#define USE_PRIVCTL            1       /* system privileges control */
 #define USE_NICE       1       /* change scheduling priority */
 #define USE_UMAP               1       /* map virtual to physical address */
 #define USE_VIRCOPY    1       /* copy using virtual addressing */ 
index 7f13a77c14116b6146f7cf3a30804d00faa228cb..fe35ad6b08bda940e57c4629b255e9eb11d04dfe 100755 (executable)
@@ -76,18 +76,14 @@ PUBLIC void main()
   for (i=0; i < NR_BOOT_PROCS; ++i) {
        ip = &image[i];                         /* process' attributes */
        rp = proc_addr(ip->proc_nr);            /* get process pointer */
-       (void) init_proc(rp, NIL_SYS_PROC);
-#if DEAD_CODE
-               (ip->flags & SYS_PROC) ?
-               NIL_SYS_PROC : NIL_PROC);       /* initialize new process */
-#endif
-       strncpy(rp->p_name, ip->proc_name, P_NAME_LEN);  /* set name */
        rp->p_name[P_NAME_LEN-1] = '\0';        /* just for safety */
        rp->p_max_priority = ip->priority;      /* max scheduling priority */
        rp->p_priority = ip->priority;          /* current priority */
        rp->p_quantum_size = ip->quantum;       /* quantum size in ticks */
        rp->p_sched_ticks = ip->quantum;        /* current credit */
-       rp->p_full_quantums = QUANTUMS(ip->priority);  /* quantums left */
+       rp->p_full_quantums = QUANTUMS(ip->priority);   /* nr quantums left */
+       strncpy(rp->p_name, ip->proc_name, P_NAME_LEN); /* set process name */
+       (void) set_priv(rp, (ip->flags & SYS_PROC));    /* assign structure */
        rp->p_priv->s_flags = ip->flags;        /* process flags */
        rp->p_priv->s_call_mask = ip->call_mask;/* allowed system calls */
        if (i-NR_TASKS < 0) {                   /* part of the kernel? */ 
@@ -188,14 +184,16 @@ PRIVATE void announce(void)
 /*==========================================================================*
  *                            prepare_shutdown                             *
  *==========================================================================*/
-PUBLIC void prepare_shutdown(how)
-int how;                               /* reason to shut down */
+PUBLIC void prepare_shutdown(tp)
+timer_t *tp;
 {
-/* This function prepares to shutdown MINIX. It uses a global flag to make 
- * sure it is only executed once. Unless a CPU exception occurred, the 
+/* This function prepares to shutdown MINIX. It is called by a watchdog 
+ * timer if this is a normal abort so that the sys_abort() call can return
+ * first. The timer structure passes the shutdown status as an argument.
  */
-  static timer_t shutdown_timer;       /* timer for watchdog function */ 
   register struct proc *rp; 
+  static timer_t shutdown_timer;
+  int how = tmr_arg(tp)->ta_int;
   message m;
 
   /* Show debugging dumps on panics. Make sure that the TTY task is still 
@@ -215,8 +213,9 @@ int how;                            /* reason to shut down */
    * run their shutdown code, e.g, to synchronize the FS or to let the TTY
    * switch to the first console. 
    */
+  kprintf("Sending SIGKSTOP to system processes ...\n"); 
   for (rp=BEG_PROC_ADDR; rp<END_PROC_ADDR; rp++) {
-      if (! isemptyp(rp) && (priv(rp)->s_flags & SYS_PROC) && ! iskernelp(rp))
+      if (!isemptyp(rp) && (priv(rp)->s_flags & SYS_PROC) && !iskernelp(rp))
           send_sig(proc_nr(rp), SIGKSTOP);
   }
 
@@ -224,9 +223,8 @@ int how;                            /* reason to shut down */
    * scheduled by setting a watchog timer that calls shutdown(). The timer 
    * argument passes the shutdown status. 
    */
-  kprintf("Informed system about upcoming shutdown with SIGKSTOP signal.\n"); 
-  kprintf("Time for cleanup is allowed.  MINIX will now be brought down.\n");
-  tmr_arg(&shutdown_timer)->ta_int = how;      /* pass how in timer */
+  kprintf("MINIX will now be shut down ...\n");
+  tmr_arg(&shutdown_timer)->ta_int = how;
   set_timer(&shutdown_timer, get_uptime() + SHUTDOWN_TICKS, shutdown);
 }
 
index ca235b4ec1541847ae8b242263a03abb08d9db44..98db457eb3e14e64e468ec5e32a6ae79c6a7451c 100755 (executable)
@@ -308,6 +308,7 @@ unsigned flags;                             /* system call flags */
             return(OK);                                        /* report success */
         }
 
+#if TEMP_CODE
         ntf_q_pp = &caller_ptr->p_ntf_q;       /* get pointer pointer */
         while (*ntf_q_pp != NULL) {
             if (src == ANY || src == (*ntf_q_pp)->n_source) {
@@ -328,6 +329,7 @@ unsigned flags;                             /* system call flags */
            ntf_q_pp = &(*ntf_q_pp)->n_next;    /* proceed to next */
         }
     }
+#endif
 
     /* Check caller queue. Use pointer pointers to keep code simple. */
     xpp = &caller_ptr->p_caller_q;
index 2501572057d0bcfae785c8818b9d6e434ccb65d1..eb30a06ea454511c4988c876976873942d798213 100755 (executable)
@@ -66,7 +66,6 @@ struct proc {
 #define SIGNALED       0x10    /* set when new kernel signal arrives */
 #define SIG_PENDING    0x20    /* unready while signal being processed */
 #define P_STOP         0x40    /* set when process is being traced */
-#define NO_PRIV                0x80    /* privilege structure not yet initialized */
 
 /* Scheduling priorities for p_priority. Values must start at zero (highest
  * priority) and increment. Priorities of the processes in the boot image can 
index 74fd1250990b11fb68a388e41f468bea2a144e71..6ead2fdd74e1cb4fa1a603fa318af26b2784d80c 100755 (executable)
@@ -17,8 +17,7 @@ _PROTOTYPE( void reset_timer, (struct timer *tp)                      );
 
 /* main.c */
 _PROTOTYPE( void main, (void)                                          );
-_PROTOTYPE( void prepare_shutdown, (int how)                           );
-_PROTOTYPE( void stop_sequence, (struct timer *tp)                     );
+_PROTOTYPE( void prepare_shutdown, (struct timer *tp)                  );
 
 /* utility.c */
 _PROTOTYPE( void kprintf, (const char *fmt, ...)                       );
@@ -41,8 +40,7 @@ _PROTOTYPE( void cstart, (U16_t cs, U16_t ds, U16_t mds,
 /* system.c */
 _PROTOTYPE( void send_sig, (int proc_nr, int sig_nr)                   );
 _PROTOTYPE( void cause_sig, (int proc_nr, int sig_nr)                  );
-_PROTOTYPE( int init_proc, (register struct proc *rc, struct proc *rp) );
-_PROTOTYPE( void clear_proc, (register struct proc *rc)                                );
+_PROTOTYPE( int set_priv, (register struct proc *rc,int sys_proc_flag) );
 _PROTOTYPE( phys_bytes numap_local, (int proc_nr, vir_bytes vir_addr, 
                vir_bytes bytes)                                        );
 _PROTOTYPE( void sys_task, (void)                                      );
index ebd463a4436f51c5052ada0e21c6458d762affab..64237c301bda77b5c13973008d39873f0a05c741 100755 (executable)
  *
  * In addition to the main sys_task() entry point, which starts the main loop,
  * there are several other minor entry points:
- *   send_sig:         send signal directly to a system process
+ *   set_priv:         assign privilege structure to user or system process
+ *   send_sig:         send a signal directly to a system process
  *   cause_sig:                take action to cause a signal to occur via PM
- *   init_proc:                initialize a process, during start up or fork
- *   clear_proc:       clean up a process in the process table, e.g. on exit
  *   umap_local:       map virtual address in LOCAL_SEG to physical 
  *   umap_remote:      map virtual address in REMOTE_SEG to physical 
  *   umap_bios:                map virtual address in BIOS_SEG to physical 
@@ -24,9 +23,7 @@
  *   generic_handler:  interrupt handler for user-level device drivers
  *
  * Changes:
- *   Apr 25, 2005   new init_proc() function  (Jorrit N. Herder)
  *   Apr 25, 2005   made mapping of call vector explicit  (Jorrit N. Herder)
- *   Oct 29, 2004   new clear_proc() function  (Jorrit N. Herder)
  *   Oct 17, 2004   generic handler and IRQ policies  (Jorrit N. Herder)
  *   Oct 10, 2004   dispatch system calls from call vector  (Jorrit N. Herder)
  *   Sep 30, 2004   source code documentation updated  (Jorrit N. Herder)
@@ -40,7 +37,6 @@
 #include <signal.h>
 #include <unistd.h>
 #include <sys/sigcontext.h>
-#include <sys/svrctl.h>
 #if (CHIP == INTEL)
 #include <ibm/memory.h>
 #include "protect.h"
@@ -127,7 +123,6 @@ PRIVATE void initialize(void)
       call_vec[i] = do_unused;
   }
 
-  /* Process management. */
   map(SYS_FORK, do_fork);              /* a process forked a new process */
   map(SYS_NEWMAP, do_newmap);          /* set up a process memory map */
   map(SYS_EXEC, do_exec);              /* update process after execute */
@@ -155,8 +150,8 @@ PRIVATE void initialize(void)
   /* System control. */
   map(SYS_ABORT, do_abort);            /* abort MINIX */
   map(SYS_GETINFO, do_getinfo);        /* request system information */ 
+  map(SYS_PRIVCTL, do_privctl);                /* system privileges control */
   map(SYS_SEGCTL, do_segctl);          /* add segment and get selector */
-  map(SYS_SVRCTL, do_svrctl);          /* kernel control functions */
 
   /* Copying. */
   map(SYS_UMAP, do_umap);              /* map virtual to physical address */
@@ -169,93 +164,28 @@ PRIVATE void initialize(void)
 
 
 /*===========================================================================*
- *                              init_proc                                   *
+ *                              set_priv                                    *
  *===========================================================================*/
-PUBLIC int init_proc(rc, rp)
+PUBLIC int set_priv(rc, proc_type)
 register struct proc *rc;              /* new (child) process pointer */
-struct proc *rp;                       /* prototype (parent) process */
+int proc_type;                         /* system or user process flag */
 {
-  register struct priv *sp;            /* process' privilege structure */
-  int i;
-
-  /* If there is a prototype process to initialize from, use it. Otherwise,
-   * assume the caller will take care of initialization, but make sure that 
-   * the new process gets a pointer to a system properties structure.
-   */
-  if (rp == NIL_PROC) {                                /* new user process */
-      kprintf("init_proc() for new user proc %d\n", proc_nr(rc));
-      sp = &priv[USER_PRIV_ID];
-      sp->s_proc_nr = ANY;                     /* misuse for users */
-      rc->p_priv = sp;                         /* assign to process */
-      return(OK);
-  } else if (rp == NIL_SYS_PROC) {             /* new system process */
-      for (sp = BEG_PRIV_ADDR, i = 0; sp < END_PRIV_ADDR; ++sp, ++i) {
-          if (sp->s_proc_nr == NONE) {         /* found free slot */
-              sp->s_proc_nr = proc_nr(rc);     /* set association */
-              rc->p_priv = sp;                 /* assign to process */
-              return(OK);
-          }
-      }
-      kprintf("No free PRIV structure!\n", NO_NUM);
-      return(ENOSPC);                          /* out of resources */
-  } else {                                     /* forked process */
-
-      kprintf("init_proc() from prototype %d\n", proc_nr(rp));
-  }
-}
-
-
-/*===========================================================================*
- *                              clear_proc                                  *
- *===========================================================================*/
-PUBLIC void clear_proc(rc)
-register struct proc *rc;              /* slot of process to clean up */
-{
-  register struct proc *rp;            /* iterate over process table */
-  register struct proc **xpp;          /* iterate over caller queue */
-  int i;
-
-  /* Turn off any alarm timers at the clock. */   
-  reset_timer(&priv(rc)->s_alarm_timer);
-
-  /* Make sure that the exiting process is no longer scheduled. */
-  if (rc->p_rts_flags == 0) lock_unready(rc);
-
-  /* If the process being terminated happens to be queued trying to send a
-   * message (e.g., the process was killed by a signal, rather than it doing 
-   * a normal exit), then it must be removed from the message queues.
-   */
-  if (rc->p_rts_flags & SENDING) {
-      /* Check all proc slots to see if the exiting process is queued. */
-      for (rp = BEG_PROC_ADDR; rp < END_PROC_ADDR; rp++) {
-          if (rp->p_caller_q == NIL_PROC) continue;
-          /* Make sure that the exiting process is not on the queue. */
-          xpp = &rp->p_caller_q;
-          while (*xpp != NIL_PROC) {           /* check entire queue */
-              if (*xpp == rc) {                        /* process is on the queue */
-                  *xpp = (*xpp)->p_q_link;     /* replace by next process */
-                  break;
-              }
-              xpp = &(*xpp)->p_q_link;         /* proceed to next queued */
-          }
-      }
-  }
-
-  /* Check the table with IRQ hooks to see if hooks should be released. */
-  for (i=0; i < NR_IRQ_HOOKS; i++) {
-      if (irq_hooks[i].proc_nr == proc_nr(rc)) {
-          rm_irq_handler(&irq_hooks[i]);       /* remove interrupt handler */
-          irq_hooks[i].proc_nr = NONE;                 /* mark hook as free */
-      }
+/* Get a privilege structure. All user processes share the same privilege 
+ * structure. System processes get their own privilege structure. 
+ */
+  register struct priv *sp;                    /* privilege structure */
+
+  if (proc_type == SYS_PROC) {                 /* find a new slot */
+      for (sp = BEG_PRIV_ADDR; sp < END_PRIV_ADDR; ++sp) 
+          if (sp->s_proc_nr == NONE && sp->s_id != USER_PRIV_ID) break;        
+      if (sp->s_proc_nr != NONE) return(ENOSPC);
+      rc->p_priv = sp;                         /* assign new slot */
+      rc->p_priv->s_proc_nr = proc_nr(rc);     /* set association */
+  } else {
+      rc->p_priv = &priv[USER_PRIV_ID];                /* use shared slot */
+      rc->p_priv->s_proc_nr = INIT_PROC_NR;    /* set association */
   }
-
-  /* Now it is safe to release the process table slot. If this is a system 
-   * process, also release its privilege structure.  Further cleanup is not
-   * needed at this point. All important fields are reinitialized when the 
-   * slots are assigned to another, new process. 
-   */
-  rc->p_rts_flags = SLOT_FREE;         
-  if (priv(rc)->s_flags & SYS_PROC) priv(rc)->s_proc_nr = NONE;
+  return(OK);
 }
 
 
@@ -390,12 +320,12 @@ vir_bytes bytes;          /* # of bytes to be copied */
  */
 
   /* Check all acceptable ranges. */
-#if DEAD_CODE  /* to be replaced by proper ranges, e.g. 640 - 1 KB */
   if (vir_addr >= BIOS_MEM_BEGIN && vir_addr + bytes <= BIOS_MEM_END)
        return (phys_bytes) vir_addr;
-  else if (vir_addr >= UPPER_MEM_BEGIN && vir_addr + bytes <= UPPER_MEM_END)
+  else if (vir_addr >= BASE_MEM_TOP && vir_addr + bytes <= UPPER_MEM_END)
        return (phys_bytes) vir_addr;
-#else
+
+#if DEAD_CODE  /* brutal fix for QEMU and Bochs, if above doesn't work */
   if (vir_addr >= BIOS_MEM_BEGIN && vir_addr + bytes <= UPPER_MEM_END)
        return (phys_bytes) vir_addr;
 #endif
index 099e81dfd006e13fae458e8ccbf2386ad0a364c5..116f13e5b301ef75b170fe9d1f84ac50f3d94272 100644 (file)
@@ -82,9 +82,9 @@ _PROTOTYPE( int do_getinfo, (message *m_ptr) );
 #define do_getinfo do_unused
 #endif
 
-_PROTOTYPE( int do_svrctl, (message *m_ptr) ); 
-#if ! USE_SVRCTL
-#define do_svrctl do_unused
+_PROTOTYPE( int do_privctl, (message *m_ptr) );        
+#if ! USE_PRIVCTL
+#define do_privctl do_unused
 #endif
 
 _PROTOTYPE( int do_segctl, (message *m_ptr) );
index ac5d04984ba017589dbbee2747806c757f6b8feb..4ad4619218c5b3835a218e1fe6281822169793f5 100644 (file)
@@ -34,7 +34,7 @@ OBJECTS       = \
        $(SYSTEM)(do_vcopy.o) \
        $(SYSTEM)(do_umap.o) \
        $(SYSTEM)(do_memset.o) \
-       $(SYSTEM)(do_svrctl.o) \
+       $(SYSTEM)(do_privctl.o) \
        $(SYSTEM)(do_segctl.o) \
        $(SYSTEM)(do_getksig.o) \
        $(SYSTEM)(do_endksig.o) \
@@ -129,8 +129,8 @@ $(SYSTEM)(do_getinfo.o):    do_getinfo.c
 $(SYSTEM)(do_abort.o): do_abort.c
        $(CC) do_abort.c
 
-$(SYSTEM)(do_svrctl.o):        do_svrctl.c
-       $(CC) do_svrctl.c
+$(SYSTEM)(do_privctl.o):       do_privctl.c
+       $(CC) do_privctl.c
 
 $(SYSTEM)(do_segctl.o):        do_segctl.c
        $(CC) do_segctl.c
index e34c2efca3e60769b9e1304abf46fa22299b09ea..0676a0ae5eb6f9016747abe5bdbc974e0a33ad06 100644 (file)
@@ -24,9 +24,10 @@ message *m_ptr;                      /* pointer to request message */
  * or ESC after debugging dumps).
  */
   int how = m_ptr->ABRT_HOW;
+  timer_t *tp;
 
+  /* See if the monitor is to run the specified instructions. */
   if (how == RBT_MONITOR) {
-      /* The monitor is to run the specified instructions. */
       int proc_nr = m_ptr->ABRT_MON_PROC;
       int length = m_ptr->ABRT_MON_LEN + 1;
       vir_bytes src_vir = (vir_bytes) m_ptr->ABRT_MON_ADDR;
@@ -38,7 +39,14 @@ message *m_ptr;                      /* pointer to request message */
       else
           phys_copy(src_phys, kinfo.params_base, (phys_bytes) length);
   }
-  prepare_shutdown(how);
+
+  /* Set a watchdog timer to shut down, so that this call returns first.
+   * The timer will expire at the next clock tick, which can be any moment.
+   * The CLOCK task is only scheduled when the SYSTEM task is done, though.
+   */
+  tp = &priv(proc_addr(KERNEL))->s_alarm_timer;
+  tmr_arg(tp)->ta_int = how;           /* pass status as timer argument */
+  set_timer(tp, get_uptime(), prepare_shutdown);
   return(OK);                          /* pro-forma (really EDISASTER) */
 }
 
index 3f52e2e97b66f7151ff9944ace9f923004f0dff8..ee2de2d22aab80a92dbd80b9fa50f95edd59749e 100644 (file)
@@ -2,7 +2,6 @@
  *   m_type:   SYS_SETALARM 
  *
  * The parameters for this system call are:
- *    m2_i1:   ALRM_PROC_NR            (set alarm for this process)    
  *    m2_l1:   ALRM_EXP_TIME           (alarm's expiration time)
  *    m2_i2:   ALRM_ABS_TIME           (expiration time is absolute?)
  *    m2_l1:   ALRM_TIME_LEFT          (return seconds left of previous)
@@ -31,9 +30,7 @@ message *m_ptr;                       /* pointer to request message */
   clock_t uptime;              /* placeholder for current uptime */
 
   /* Extract shared parameters from the request message. */
-  proc_nr = m_ptr->ALRM_PROC_NR;       /* process to interrupt later */
-  if (SELF == proc_nr) proc_nr = m_ptr->m_source;
-  if (! isokprocn(proc_nr)) return(EINVAL);
+  proc_nr = m_ptr->m_source;           /* process to interrupt later */
   exp_time = m_ptr->ALRM_EXP_TIME;     /* alarm's expiration time */
   use_abs_time = m_ptr->ALRM_ABS_TIME; /* flag for absolute time */
 
@@ -50,7 +47,7 @@ message *m_ptr;                       /* pointer to request message */
       m_ptr->ALRM_TIME_LEFT = (tp->tmr_exp_time - uptime);
   }
 
-  /* Finally, (re)set the timer depending on 'exp_time'. */
+  /* Finally, (re)set the timer depending on the expiration time. */
   if (exp_time == 0) {
       reset_timer(tp);
   } else {
index b2bce2c686a0801244c6f3a3ae7e0d590c52c06f..9212329cbe90b0b2e22f741b510338f864906144 100644 (file)
@@ -23,7 +23,8 @@ PUBLIC int do_copy(m_ptr)
 register message *m_ptr;       /* pointer to request message */
 {
 /* Handle sys_vircopy() and sys_physcopy().  Copy data using virtual or
- * physical addressing. 
+ * physical addressing. Although a single handler function is used, there 
+ * are two different system calls so that permissions can be checked. 
  */
   struct vir_addr vir_addr[2]; /* virtual source and destination address */
   vir_bytes bytes;             /* number of bytes to copy */
index 26bf87a7f64d47359726afe7ad73a0e479928106..03e6103c4ad07ad4f0a1b977bc94420b5fd29cb1 100644 (file)
@@ -22,7 +22,7 @@
 PUBLIC int do_devio(m_ptr)
 register message *m_ptr;       /* pointer to request message */
 {
-    /* Perform actual device I/O for byte, word, and long values. */
+/* Process a single I/O request for byte, word, and long values. */
     if (m_ptr->DIO_REQUEST == DIO_INPUT) { 
       switch (m_ptr->DIO_TYPE) {
         case DIO_BYTE: m_ptr->DIO_VALUE = inb(m_ptr->DIO_PORT); break; 
index b17091639e163721219787b38f1fc1d2a900bc85..3eac7891b23fe90466297412b162c09d837a7020 100644 (file)
@@ -9,6 +9,8 @@
 
 #if USE_EXIT
 
+FORWARD _PROTOTYPE( void clear_proc, (register struct proc *rc));
+
 /*===========================================================================*
  *                             do_exit                                      *
  *===========================================================================*/
@@ -37,6 +39,61 @@ message *m_ptr;                      /* pointer to request message */
   clear_proc(proc_addr(m_ptr->m_source));
   return(EDONTREPLY);
 }
+
+
+/*===========================================================================*
+ *                              clear_proc                                  *
+ *===========================================================================*/
+PRIVATE void clear_proc(rc)
+register struct proc *rc;              /* slot of process to clean up */
+{
+  register struct proc *rp;            /* iterate over process table */
+  register struct proc **xpp;          /* iterate over caller queue */
+  int i;
+
+  /* Turn off any alarm timers at the clock. */   
+  reset_timer(&priv(rc)->s_alarm_timer);
+
+  /* Make sure that the exiting process is no longer scheduled. */
+  if (rc->p_rts_flags == 0) lock_unready(rc);
+
+  /* If the process being terminated happens to be queued trying to send a
+   * message (e.g., the process was killed by a signal, rather than it doing 
+   * a normal exit), then it must be removed from the message queues.
+   */
+  if (rc->p_rts_flags & SENDING) {
+      /* Check all proc slots to see if the exiting process is queued. */
+      for (rp = BEG_PROC_ADDR; rp < END_PROC_ADDR; rp++) {
+          if (rp->p_caller_q == NIL_PROC) continue;
+          /* Make sure that the exiting process is not on the queue. */
+          xpp = &rp->p_caller_q;
+          while (*xpp != NIL_PROC) {           /* check entire queue */
+              if (*xpp == rc) {                        /* process is on the queue */
+                  *xpp = (*xpp)->p_q_link;     /* replace by next process */
+                  break;
+              }
+              xpp = &(*xpp)->p_q_link;         /* proceed to next queued */
+          }
+      }
+  }
+
+  /* Check the table with IRQ hooks to see if hooks should be released. */
+  for (i=0; i < NR_IRQ_HOOKS; i++) {
+      if (irq_hooks[i].proc_nr == proc_nr(rc)) {
+          rm_irq_handler(&irq_hooks[i]);       /* remove interrupt handler */
+          irq_hooks[i].proc_nr = NONE;                 /* mark hook as free */
+      }
+  }
+
+  /* Now it is safe to release the process table slot. If this is a system 
+   * process, also release its privilege structure.  Further cleanup is not
+   * needed at this point. All important fields are reinitialized when the 
+   * slots are assigned to another, new process. 
+   */
+  rc->p_rts_flags = SLOT_FREE;         
+  if (priv(rc)->s_flags & SYS_PROC) priv(rc)->s_proc_nr = NONE;
+}
+
 #endif /* USE_EXIT */
 
 
index baf722ba119f05b1691faad0f5a0d3a1e97348cd..0c77771dc2e483e1132d69082ca87d3c6c4f4bc4 100644 (file)
@@ -22,7 +22,6 @@ PUBLIC int do_fork(m_ptr)
 register message *m_ptr;       /* pointer to request message */
 {
 /* Handle sys_fork().  PR_PPROC_NR has forked.  The child is PR_PROC_NR. */
-
 #if (CHIP == INTEL)
   reg_t old_ldt_sel;
 #endif
@@ -43,10 +42,6 @@ register message *m_ptr;     /* pointer to request message */
 #endif
   rpc->p_nr = m_ptr->PR_PROC_NR;       /* this was obliterated by copy */
 
-#if TEMP_CODE
-  rpc->p_ntf_q = NULL;                 /* remove pending notifications */
-#endif
-
   /* Only one in group should have SIGNALED, child doesn't inherit tracing. */
   rpc->p_rts_flags |= NO_MAP;          /* inhibit process from running */
   rpc->p_rts_flags &= ~(SIGNALED | SIG_PENDING | P_STOP);
index 936ec2f0685d0774ce07a9488d8a35b6557fde83..90492f39cc68a0569ba727e632072332534e2d22 100644 (file)
@@ -23,7 +23,9 @@
 PUBLIC int do_getinfo(m_ptr)
 register message *m_ptr;       /* pointer to request message */
 {
-/* Request system information to be copied to caller's address space. */
+/* Request system information to be copied to caller's address space. This
+ * call simply copies entire data structures to the caller.
+ */
   size_t length;
   phys_bytes src_phys; 
   phys_bytes dst_phys; 
@@ -117,7 +119,7 @@ register message *m_ptr;    /* pointer to request message */
 
   /* Try to make the actual copy for the requested data. */
   if (m_ptr->I_VAL_LEN > 0 && length > m_ptr->I_VAL_LEN) return (E2BIG);
-  proc_nr = m_ptr->m_source;   /* only caller can request copy */
+  proc_nr = m_ptr->m_source;           /* only caller can request copy */
   dst_phys = numap_local(proc_nr, (vir_bytes) m_ptr->I_VAL_PTR, length); 
   if (src_phys == 0 || dst_phys == 0) return(EFAULT);
   phys_copy(src_phys, dst_phys, length);
index 65e825dc56c9605583f5859c374a9d3520b6a73a..360fdc4102d16871befb62163eb0371f2983625a 100644 (file)
@@ -2,9 +2,9 @@
  *   m_type:   SYS_MEMSET
  *
  * The parameters for this system call are:
- *    m5_l1:   CP_SRC_ADDR     (virtual address)       
- *    m5_l2:   CP_DST_ADDR     (returns physical address)      
- *    m5_l3:   CP_NR_BYTES     (size of datastructure)         
+ *    m1_p1:   MEM_PTR         (virtual address)       
+ *    m1_i1:   MEM_COUNT       (returns physical address)      
+ *    m1_i2:   MEM_PATTERN     (size of datastructure)         
  */
 
 #include "../system.h"
@@ -17,9 +17,9 @@
 PUBLIC int do_memset(m_ptr)
 register message *m_ptr;
 {
-/* Handle sys_memset(). */
+/* Handle sys_memset(). This writes a pattern into the specified memory. */
   unsigned long p;
-  unsigned char c = m_ptr->MEM_CHAR;
+  unsigned char c = m_ptr->MEM_PATTERN;
   p = c | (c << 8) | (c << 16) | (c << 24);
   phys_memset((phys_bytes) m_ptr->MEM_PTR, p, (phys_bytes) m_ptr->MEM_COUNT);
   return(OK);
index 052b450df137533e6f683dfdb22d2465da982ae9..576240ccec9b49d818dfb5daef1920d020f99ab0 100644 (file)
@@ -62,7 +62,7 @@ message *m_ptr;                       /* pointer to request message */
 #endif
 
   /* Restore the registers. */
-  memcpy(&rp->p_reg, (char *)&sc.sc_regs, sizeof(struct sigregs));
+  memcpy(&rp->p_reg, &sc.sc_regs, sizeof(struct sigregs));
   return(OK);
 }
 #endif /* USE_SIGRETURN */
index f298b948d7ec26a581b243862dba09fa0c8dd228..33bd85bad8253c8805625d501a16033146e3424a 100644 (file)
@@ -41,7 +41,7 @@ message *m_ptr;                       /* pointer to request message */
   scp = (struct sigcontext *) smsg.sm_stkptr - 1;
 
   /* Copy the registers to the sigcontext structure. */
-  memcpy(&sc.sc_regs, &rp->p_reg, sizeof(struct sigregs));
+  memcpy(&sc.sc_regs, (char *) &rp->p_reg, sizeof(struct sigregs));
 
   /* Finish the sigcontext initialization. */
   sc.sc_flags = SC_SIGCONTEXT;
index 42cef8620ffd9fc85e3ff93155388bdc1d4f5f68..26323afd6398c283a7b9ffd8ae874e43ab53a97e 100644 (file)
@@ -25,7 +25,10 @@ PRIVATE struct vir_cp_req vir_cp_req[VCOPY_VEC_SIZE];
 PUBLIC int do_vcopy(m_ptr)
 register message *m_ptr;       /* pointer to request message */
 {
-/* Handle sys_virvcopy(). Handle virtual copy requests from vector. */
+/* Handle sys_virvcopy() and sys_physvcopy() that pass a vector with copy
+ * requests. Although a single handler function is used, there are two
+ * different system calls so that permissions can be checked.
+ */
   int nr_req;
   int caller_pid;
   vir_bytes caller_vir;
index e7ecb2549ea082cd8671e8d367dfa180d38f0ff0..9c455fcb69a421288ecd4e0575578582c242739c 100644 (file)
@@ -13,7 +13,6 @@
 
 #if USE_VDEVIO
 
-
 /* Buffer for SYS_VDEVIO to copy (port,value)-pairs from/ to user. */
 PRIVATE char vdevio_pv_buf[VDEVIO_BUF_SIZE];      
 
@@ -42,7 +41,7 @@ register message *m_ptr;      /* pointer to request message */
     pvw_pair_t *pvw_pairs;      /* needed for word values */
     pvl_pair_t *pvl_pairs;      /* needed for long values */
     int i;
-    pid_t caller_pid;           /* process id of caller */
+    int caller_proc;            /* process number of caller */
     size_t bytes;               /* # bytes to be copied */
     vir_bytes caller_vir;       /* virtual address at caller */
     phys_bytes caller_phys;     /* physical address at caller */
@@ -69,9 +68,9 @@ register message *m_ptr;      /* pointer to request message */
     }
 
     /* Calculate physical addresses and copy (port,value)-pairs from user. */
-    caller_pid = (pid_t) m_ptr->m_source; 
+    caller_proc = m_ptr->m_source; 
     caller_vir = (vir_bytes) m_ptr->DIO_VEC_ADDR;
-    caller_phys = umap_local(proc_addr(caller_pid), D, caller_vir, bytes);
+    caller_phys = umap_local(proc_addr(caller_proc), D, caller_vir, bytes);
     if (0 == caller_phys) return EFAULT;
     kernel_phys = vir2phys(vdevio_pv_buf);
     phys_copy(caller_phys, kernel_phys, (phys_bytes) bytes);
index cbd5ed6b4312e03191857facf3849536eecf32ca..03b700f08f679c396d057b85dfee64a878cab893 100755 (executable)
  * or PRIVATE. The reason for this is that extern variables cannot have a  
  * default initialization. If such variables are shared, they must also be
  * declared in one of the *.h files without the initialization.  Examples 
- * include 'tasktab' (this file) and 'idt'/'gdt' (protect.c). 
+ * include 'system_image' (this file) and 'idt' and 'gdt' (protect.c). 
  *
  * Changes:
  *    Nov 10, 2004   removed controller->driver mappings  (Jorrit N. Herder)
  *    Oct 17, 2004   updated above and tasktab comments  (Jorrit N. Herder)
- *    May 01, 2004   included p_sendmask in tasktab  (Jorrit N. Herder)
+ *    May 01, 2004   changed struct for system image  (Jorrit N. Herder)
  */
 
 #define _TABLE
@@ -59,22 +59,21 @@ PUBLIC char *t_stack[TOT_STACK_SPACE / sizeof(char *)];
  * mask, and a name for the process table. For kernel processes, the startup 
  * routine and stack size is also provided.
  */
-#define IDLE_F         (PREEMPTIBLE | BILLABLE)
-#define USER_F         (PREEMPTIBLE | RDY_Q_HEAD)
+#define USER_F         (PREEMPTIBLE | BILLABLE | RDY_Q_HEAD)
 #define SYS_F                  (PREEMPTIBLE | SYS_PROC)
-#define TCB_F                  (SYS_PROC)      /* trusted computing base */
+#define TASK_F                 (SYS_PROC)      
 
 #define IDLE_T         32              /* ticks */
 #define USER_T          8              /* ticks */
 #define SYS_T          16              /* ticks */
 
 PUBLIC struct system_image image[] = {
- { IDLE,    idle_task,  IDLE_F, IDLE_T,   IDLE_Q,  IDLE_S,    EMPTY_CALL_MASK, 0,    "IDLE"    },
- { CLOCK,   clock_task, TCB_F, SYS_T,   TASK_Q, CLOCK_S,   SYSTEM_CALL_MASK, 0,   "CLOCK"   },
- { SYSTEM,  sys_task,   TCB_F, SYS_T,   TASK_Q, SYSTEM_S,     SYSTEM_CALL_MASK, 0,  "SYS"     },
- { HARDWARE,   0,       0, SYS_T,   TASK_Q, HARDWARE_S, EMPTY_CALL_MASK, 0,"KERNEL" },
- { PM_PROC_NR, 0,       TCB_F, SYS_T, 3, 0,          SYSTEM_CALL_MASK,   0,      "PM"      },
- { FS_PROC_NR, 0,       TCB_F, SYS_T, 3, 0,          SYSTEM_CALL_MASK,   0,      "FS"      },
+ { IDLE,    idle_task,  USER_F, IDLE_T,   IDLE_Q,  IDLE_S,    EMPTY_CALL_MASK, 0,    "IDLE"    },
+ { CLOCK,   clock_task, TASK_F, SYS_T,   TASK_Q, CLOCK_S,   SYSTEM_CALL_MASK, 0,   "CLOCK"   },
+ { SYSTEM,  sys_task,   TASK_F, SYS_T,   TASK_Q, SYSTEM_S,     SYSTEM_CALL_MASK, 0,  "SYS"     },
+ { HARDWARE,   0,       TASK_F, SYS_T,   TASK_Q, HARDWARE_S, EMPTY_CALL_MASK, 0,"KERNEL" },
+ { PM_PROC_NR, 0,       SYS_F, SYS_T, 3, 0,          SYSTEM_CALL_MASK,   0,      "PM"      },
+ { FS_PROC_NR, 0,       SYS_F, SYS_T, 3, 0,          SYSTEM_CALL_MASK,   0,      "FS"      },
  { IS_PROC_NR, 0,       SYS_F, SYS_T, 2, 0,           SYSTEM_CALL_MASK,  0,      "IS"      },
  { TTY, 0,              SYS_F, SYS_T, 1, 0,           SYSTEM_CALL_MASK, 0,      "TTY"      },
  { MEMORY, 0,           SYS_F, SYS_T, 2, 0,           SYSTEM_CALL_MASK,  0,     "MEMORY" },
index f8b827941af57811547cbf5c8835df0813a9334c..ae772784f04a3a56297ef594b45c2f7146d8b753 100755 (executable)
@@ -19,6 +19,7 @@
 #include <stdlib.h>
 #include <signal.h>
 #include <minix/com.h>
+#include "proc.h"
 
 #define END_OF_KMESS   -1
 FORWARD _PROTOTYPE(void kputc, (int c));
@@ -33,6 +34,7 @@ int nr;
 {
 /* The system has run aground of a fatal kernel error. Terminate execution. */
   static int panicking = 0;
+  timer_t *tp;
   if (panicking ++) return;            /* prevent recursive panics */
 
   if (mess != NULL) {
@@ -40,7 +42,13 @@ int nr;
        if (nr != NO_NUM) kprintf(" %d", nr);
        kprintf("\n",NO_NUM);
   }
-  prepare_shutdown(RBT_PANIC);
+
+  /* Make a direct call to shutdown. Interface requires to pass the shutdown
+   * status by means of a timer. 
+   */
+  tp = &priv(proc_addr(KERNEL))->s_alarm_timer;
+  tmr_arg(tp)->ta_int = RBT_PANIC;
+  prepare_shutdown(tp);
 }