~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Minix Cross Reference
Minix/mm/main.c


  1 /* This file contains the main program of the memory manager and some related
  2  * procedures.  When MINIX starts up, the kernel runs for a little while,
  3  * initializing itself and its tasks, and then it runs MM and FS.  Both MM
  4  * and FS initialize themselves as far as they can.  FS then makes a call to
  5  * MM, because MM has to wait for FS to acquire a RAM disk.  MM asks the
  6  * kernel for all free memory and starts serving requests.
  7  *
  8  * The entry points into this file are:
  9  *   main:      starts MM running
 10  *   reply:     reply to a process making an MM system call
 11  */
 12 
 13 #include "mm.h"
 14 #include <minix/callnr.h>
 15 #include <minix/com.h>
 16 #include <signal.h>
 17 #include <fcntl.h>
 18 #include <sys/ioctl.h>
 19 #include "mproc.h"
 20 #include "param.h"
 21 
 22 FORWARD _PROTOTYPE( void get_work, (void)                               );
 23 FORWARD _PROTOTYPE( void mm_init, (void)                                );
 24 
 25 /*===========================================================================*
 26  *                              main                                         *
 27  *===========================================================================*/
 28 PUBLIC void main()
 29 {
 30 /* Main routine of the memory manager. */
 31 
 32   int error;
 33 
 34   mm_init();                    /* initialize memory manager tables */
 35 
 36   /* This is MM's main loop-  get work and do it, forever and forever. */
 37   while (TRUE) {
 38         /* Wait for message. */
 39         get_work();             /* wait for an MM system call */
 40         mp = &mproc[who];
 41 
 42         /* Set some flags. */
 43         error = OK;
 44         dont_reply = FALSE;
 45         err_code = -999;
 46 
 47         /* If the call number is valid, perform the call. */
 48         if (mm_call < 0 || mm_call >= NCALLS)
 49                 error = EBADCALL;
 50         else
 51                 error = (*call_vec[mm_call])();
 52 
 53         /* Send the results back to the user to indicate completion. */
 54         if (dont_reply) continue;       /* no reply for EXIT and WAIT */
 55         if (mm_call == EXEC && error == OK) continue;
 56         reply(who, error, result2, res_ptr);
 57   }
 58 }
 59 
 60 
 61 /*===========================================================================*
 62  *                              get_work                                     *
 63  *===========================================================================*/
 64 PRIVATE void get_work()
 65 {
 66 /* Wait for the next message and extract useful information from it. */
 67   int error;
 68 
 69   if ((error = receive(ANY, &mm_in)) != OK) panic("MM receive error", error);
 70   who = mm_in.m_source;         /* who sent the message */
 71   mm_call = mm_in.m_type;       /* system call number */
 72 }
 73 
 74 
 75 /*===========================================================================*
 76  *                              reply                                        *
 77  *===========================================================================*/
 78 PUBLIC void reply(proc_nr, result, res2, respt)
 79 int proc_nr;                    /* process to reply to */
 80 int result;                     /* result of the call (usually OK or error #)*/
 81 int res2;                       /* secondary result */
 82 char *respt;                    /* result if pointer */
 83 {
 84 /* Send a reply to a user process. */
 85 
 86   register struct mproc *proc_ptr;
 87 
 88   proc_ptr = &mproc[proc_nr];
 89   /* 
 90    * To make MM robust, check to see if destination is still alive.  This
 91    * validy check must be skipped if the caller is a task.
 92    */
 93   if ((who >=0) && ((proc_ptr->mp_flags&IN_USE) == 0 || 
 94         (proc_ptr->mp_flags&HANGING))) return;
 95 
 96   reply_type = result;
 97   reply_i1 = res2;
 98   reply_p1 = respt;
 99   if (send(proc_nr, &mm_out) != OK) panic("MM can't reply", NO_NUM);
100 }
101 
102 
103 /*===========================================================================*
104  *                              mm_init                                      *
105  *===========================================================================*/
106 PRIVATE void mm_init()
107 {
108 /* Initialize the memory manager. */
109 
110   static char core_sigs[] = {
111         SIGQUIT, SIGILL, SIGTRAP, SIGABRT,
112         SIGEMT, SIGFPE, SIGUSR1, SIGSEGV,
113         SIGUSR2, 0 };
114   register int proc_nr;
115   register struct mproc *rmp;
116   register char *sig_ptr;
117   phys_clicks ram_clicks, total_clicks, minix_clicks, free_clicks;
118   message mess;
119   struct mem_map kernel_map[NR_SEGS];
120   int mem;
121 
122   /* Build the set of signals which cause core dumps. Do it the Posix
123    * way, so no knowledge of bit positions is needed.
124    */
125   sigemptyset(&core_sset);
126   for (sig_ptr = core_sigs; *sig_ptr != 0; sig_ptr++)
127         sigaddset(&core_sset, *sig_ptr);
128 
129   /* Get the memory map of the kernel to see how much memory it uses,
130    * including the gap between address 0 and the start of the kernel.
131    */
132   sys_getmap(SYSTASK, kernel_map);
133   minix_clicks = kernel_map[S].mem_phys + kernel_map[S].mem_len;
134 #if MACHINE == SUN
135   /*
136    * Don't include the area from addr 0 to the start of the kernel text
137    * segment in the minix memory total, as it is not used for smx
138    * "physical" memory!
139    */
140   minix_clicks -= kernel_map[T].mem_phys;
141   set_stack_high(kernel_map[T].mem_phys);
142 #endif
143 
144   /* Initialize MM's tables. */
145   for (proc_nr = 0; proc_nr <= INIT_PROC_NR; proc_nr++) {
146         rmp = &mproc[proc_nr];
147         rmp->mp_flags |= IN_USE;
148         sys_getmap(proc_nr, rmp->mp_seg);
149         if (rmp->mp_seg[T].mem_len != 0) rmp->mp_flags |= SEPARATE;
150         minix_clicks += (rmp->mp_seg[S].mem_phys + rmp->mp_seg[S].mem_len)
151                                 - rmp->mp_seg[T].mem_phys;
152   }
153   mproc[INIT_PROC_NR].mp_pid = INIT_PID;
154   sigemptyset(&mproc[INIT_PROC_NR].mp_ignore);
155   sigemptyset(&mproc[INIT_PROC_NR].mp_catch);
156   sigemptyset(&mproc[INIT_PROC_NR].mp_sigmask);
157   sigemptyset(&mproc[INIT_PROC_NR].mp_sigmask2);
158   sigemptyset(&mproc[INIT_PROC_NR].mp_sigpending);
159   procs_in_use = LOW_USER + 1;
160 
161   /* Wait for FS to send a message telling the RAM disk size then go "on-line".
162    */
163   if (receive(FS_PROC_NR, &mess) != OK)
164         panic("MM can't obtain RAM disk size from FS", NO_NUM);
165 
166   ram_clicks = mess.m1_i1;
167 
168   /* Initialize tables to all physical mem. */
169   mem_init(&total_clicks, &free_clicks);
170 
171   /* Print memory information. */
172   printf("\nMemory size =%5dK   ", click_to_round_k(total_clicks));
173   printf("MINIX =%4dK   ", click_to_round_k(minix_clicks));
174   printf("RAM disk =%5dK   ", click_to_round_k(ram_clicks));
175   printf("Available =%5dK\n\n", click_to_round_k(free_clicks));
176 
177   /* Tell FS to continue. */
178   if (send(FS_PROC_NR, &mess) != OK)
179         panic("MM can't sync up with FS", NO_NUM);
180 
181   /* Tell the memory task where my process table is for the sake of ps(1). */
182   if ((mem = open("/dev/mem", O_RDWR)) != -1) {
183         ioctl(mem, MIOCSPSINFO, (void *) mproc);
184         close(mem);
185   }
186 }
187 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.