?? main.c
字號:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/mm/main.c
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
16600 /* This file contains the main program of the memory manager and some related
16601 * procedures. When MINIX starts up, the kernel runs for a little while,
16602 * initializing itself and its tasks, and then it runs MM and FS. Both MM
16603 * and FS initialize themselves as far as they can. FS then makes a call to
16604 * MM, because MM has to wait for FS to acquire a RAM disk. MM asks the
16605 * kernel for all free memory and starts serving requests.
16606 *
16607 * The entry points into this file are:
16608 * main: starts MM running
16609 * reply: reply to a process making an MM system call
16610 */
16611
16612 #include "mm.h"
16613 #include <minix/callnr.h>
16614 #include <minix/com.h>
16615 #include <signal.h>
16616 #include <fcntl.h>
16617 #include <sys/ioctl.h>
16618 #include "mproc.h"
16619 #include "param.h"
16620
16621 FORWARD _PROTOTYPE( void get_work, (void) );
16622 FORWARD _PROTOTYPE( void mm_init, (void) );
16623
16624 /*===========================================================================*
16625 * main *
16626 *===========================================================================*/
16627 PUBLIC void main()
16628 {
16629 /* Main routine of the memory manager. */
16630
16631 int error;
16632
16633 mm_init(); /* initialize memory manager tables */
16634
16635 /* This is MM's main loop- get work and do it, forever and forever. */
16636 while (TRUE) {
16637 /* Wait for message. */
16638 get_work(); /* wait for an MM system call */
16639 mp = &mproc[who];
16640
16641 /* Set some flags. */
16642 error = OK;
16643 dont_reply = FALSE;
16644 err_code = -999;
16645
16646 /* If the call number is valid, perform the call. */
16647 if (mm_call < 0 || mm_call >= NCALLS)
16648 error = EBADCALL;
16649 else
16650 error = (*call_vec[mm_call])();
16651
16652 /* Send the results back to the user to indicate completion. */
16653 if (dont_reply) continue; /* no reply for EXIT and WAIT */
16654 if (mm_call == EXEC && error == OK) continue;
16655 reply(who, error, result2, res_ptr);
16656 }
16657 }
16660 /*===========================================================================*
16661 * get_work *
16662 *===========================================================================*/
16663 PRIVATE void get_work()
16664 {
16665 /* Wait for the next message and extract useful information from it. */
16666
16667 if (receive(ANY, &mm_in) != OK) panic("MM receive error", NO_NUM);
16668 who = mm_in.m_source; /* who sent the message */
16669 mm_call = mm_in.m_type; /* system call number */
16670 }
16673 /*===========================================================================*
16674 * reply *
16675 *===========================================================================*/
16676 PUBLIC void reply(proc_nr, result, res2, respt)
16677 int proc_nr; /* process to reply to */
16678 int result; /* result of the call (usually OK or error #)*/
16679 int res2; /* secondary result */
16680 char *respt; /* result if pointer */
16681 {
16682 /* Send a reply to a user process. */
16683
16684 register struct mproc *proc_ptr;
16685
16686 proc_ptr = &mproc[proc_nr];
16687 /*
16688 * To make MM robust, check to see if destination is still alive. This
16689 * validy check must be skipped if the caller is a task.
16690 */
16691 if ((who >=0) && ((proc_ptr->mp_flags&IN_USE) == 0 ||
16692 (proc_ptr->mp_flags&HANGING))) return;
16693
16694 reply_type = result;
16695 reply_i1 = res2;
16696 reply_p1 = respt;
16697 if (send(proc_nr, &mm_out) != OK) panic("MM can't reply", NO_NUM);
16698 }
16701 /*===========================================================================*
16702 * mm_init *
16703 *===========================================================================*/
16704 PRIVATE void mm_init()
16705 {
16706 /* Initialize the memory manager. */
16707
16708 static char core_sigs[] = {
16709 SIGQUIT, SIGILL, SIGTRAP, SIGABRT,
16710 SIGEMT, SIGFPE, SIGUSR1, SIGSEGV,
16711 SIGUSR2, 0 };
16712 register int proc_nr;
16713 register struct mproc *rmp;
16714 register char *sig_ptr;
16715 phys_clicks ram_clicks, total_clicks, minix_clicks, free_clicks, dummy;
16716 message mess;
16717 struct mem_map kernel_map[NR_SEGS];
16718 int mem;
16719
16720 /* Build the set of signals which cause core dumps. Do it the Posix
16721 * way, so no knowledge of bit positions is needed.
16722 */
16723 sigemptyset(&core_sset);
16724 for (sig_ptr = core_sigs; *sig_ptr != 0; sig_ptr++)
16725 sigaddset(&core_sset, *sig_ptr);
16726
16727 /* Get the memory map of the kernel to see how much memory it uses,
16728 * including the gap between address 0 and the start of the kernel.
16729 */
16730 sys_getmap(SYSTASK, kernel_map);
16731 minix_clicks = kernel_map[S].mem_phys + kernel_map[S].mem_len;
16732
16733 /* Initialize MM's tables. */
16734 for (proc_nr = 0; proc_nr <= INIT_PROC_NR; proc_nr++) {
16735 rmp = &mproc[proc_nr];
16736 rmp->mp_flags |= IN_USE;
16737 sys_getmap(proc_nr, rmp->mp_seg);
16738 if (rmp->mp_seg[T].mem_len != 0) rmp->mp_flags |= SEPARATE;
16739 minix_clicks += (rmp->mp_seg[S].mem_phys + rmp->mp_seg[S].mem_len)
16740 - rmp->mp_seg[T].mem_phys;
16741 }
16742 mproc[INIT_PROC_NR].mp_pid = INIT_PID;
16743 sigemptyset(&mproc[INIT_PROC_NR].mp_ignore);
16744 sigemptyset(&mproc[INIT_PROC_NR].mp_catch);
16745 procs_in_use = LOW_USER + 1;
16746
16747 /* Wait for FS to send a message telling the RAM disk size then go "on-line".
16748 */
16749 if (receive(FS_PROC_NR, &mess) != OK)
16750 panic("MM can't obtain RAM disk size from FS", NO_NUM);
16751
16752 ram_clicks = mess.m1_i1;
16753
16754 /* Initialize tables to all physical mem. */
16755 mem_init(&total_clicks, &free_clicks);
16756
16757 /* Print memory information. */
16758 printf("\nMemory size =%5dK ", click_to_round_k(total_clicks));
16759 printf("MINIX =%4dK ", click_to_round_k(minix_clicks));
16760 printf("RAM disk =%5dK ", click_to_round_k(ram_clicks));
16761 printf("Available =%5dK\n\n", click_to_round_k(free_clicks));
16762
16763 /* Tell FS to continue. */
16764 if (send(FS_PROC_NR, &mess) != OK)
16765 panic("MM can't sync up with FS", NO_NUM);
16766
16767 /* Tell the memory task where my process table is for the sake of ps(1). */
16768 if ((mem = open("/dev/mem", O_RDWR)) != -1) {
16769 ioctl(mem, MIOCSPSINFO, (void *) mproc);
16770 close(mem);
16771 }
16772 }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -