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
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.