📄 system.c
字号:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/kernel/system.c
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
14700 /* This task handles the interface between file system and kernel as well as
14701 * between memory manager and kernel. System services are obtained by sending
14702 * sys_task() a message specifying what is needed. To make life easier for
14703 * MM and FS, a library is provided with routines whose names are of the
14704 * form sys_xxx, e.g. sys_xit sends the SYS_XIT message to sys_task. The
14705 * message types and parameters are:
14706 *
14707 * SYS_FORK informs kernel that a process has forked
14708 * SYS_NEWMAP allows MM to set up a process memory map
14709 * SYS_GETMAP allows MM to get a process' memory map
14710 * SYS_EXEC sets program counter and stack pointer after EXEC
14711 * SYS_XIT informs kernel that a process has exited
14712 * SYS_GETSP caller wants to read out some process' stack pointer
14713 * SYS_TIMES caller wants to get accounting times for a process
14714 * SYS_ABORT MM or FS cannot go on; abort MINIX
14715 * SYS_FRESH start with a fresh process image during EXEC (68000 only)
14716 * SYS_SENDSIG send a signal to a process (POSIX style)
14717 * SYS_SIGRETURN complete POSIX-style signalling
14718 * SYS_KILL cause a signal to be sent via MM
14719 * SYS_ENDSIG finish up after SYS_KILL-type signal
14720 * SYS_COPY request a block of data to be copied between processes
14721 * SYS_VCOPY request a series of data blocks to be copied between procs
14722 * SYS_GBOOT copies the boot parameters to a process
14723 * SYS_MEM returns the next free chunk of physical memory
14724 * SYS_UMAP compute the physical address for a given virtual address
14725 * SYS_TRACE request a trace operation
14726 *
14727 * Message types and parameters:
14728 *
14729 * m_type PROC1 PROC2 PID MEM_PTR
14730 * ------------------------------------------------------
14731 * | SYS_FORK | parent | child | pid | |
14732 * |------------+---------+---------+---------+---------|
14733 * | SYS_NEWMAP | proc nr | | | map ptr |
14734 * |------------+---------+---------+---------+---------|
14735 * | SYS_EXEC | proc nr | traced | new sp | |
14736 * |------------+---------+---------+---------+---------|
14737 * | SYS_XIT | parent | exitee | | |
14738 * |------------+---------+---------+---------+---------|
14739 * | SYS_GETSP | proc nr | | | |
14740 * |------------+---------+---------+---------+---------|
14741 * | SYS_TIMES | proc nr | | buf ptr | |
14742 * |------------+---------+---------+---------+---------|
14743 * | SYS_ABORT | | | | |
14744 * |------------+---------+---------+---------+---------|
14745 * | SYS_FRESH | proc nr | data_cl | | |
14746 * |------------+---------+---------+---------+---------|
14747 * | SYS_GBOOT | proc nr | | | bootptr |
14748 * |------------+---------+---------+---------+---------|
14749 * | SYS_GETMAP | proc nr | | | map ptr |
14750 * ------------------------------------------------------
14751 *
14752 * m_type m1_i1 m1_i2 m1_i3 m1_p1
14753 * ----------------+---------+---------+---------+--------------
14754 * | SYS_VCOPY | src p | dst p | vec siz | vc addr |
14755 * |---------------+---------+---------+---------+-------------|
14756 * | SYS_SENDSIG | proc nr | | | smp |
14757 * |---------------+---------+---------+---------+-------------|
14758 * | SYS_SIGRETURN | proc nr | | | scp |
14759 * |---------------+---------+---------+---------+-------------|
14760 * | SYS_ENDSIG | proc nr | | | |
14761 * -------------------------------------------------------------
14762 *
14763 * m_type m2_i1 m2_i2 m2_l1 m2_l2
14764 * ------------------------------------------------------
14765 * | SYS_TRACE | proc_nr | request | addr | data |
14766 * ------------------------------------------------------
14767 *
14768 *
14769 * m_type m6_i1 m6_i2 m6_i3 m6_f1
14770 * ------------------------------------------------------
14771 * | SYS_KILL | proc_nr | sig | | |
14772 * ------------------------------------------------------
14773 *
14774 *
14775 * m_type m5_c1 m5_i1 m5_l1 m5_c2 m5_i2 m5_l2 m5_l3
14776 * --------------------------------------------------------------------------
14777 * | SYS_COPY |src seg|src proc|src vir|dst seg|dst proc|dst vir| byte ct |
14778 * --------------------------------------------------------------------------
14779 * | SYS_UMAP | seg |proc nr |vir adr| | | | byte ct |
14780 * --------------------------------------------------------------------------
14781 *
14782 *
14783 * m_type m1_i1 m1_i2 m1_i3
14784 * |------------+----------+----------+----------
14785 * | SYS_MEM | mem base | mem size | tot mem |
14786 * ----------------------------------------------
14787 *
14788 * In addition to the main sys_task() entry point, there are 5 other minor
14789 * entry points:
14790 * cause_sig: take action to cause a signal to occur, sooner or later
14791 * inform: tell MM about pending signals
14792 * numap: umap D segment starting from process number instead of pointer
14793 * umap: compute the physical address for a given virtual address
14794 * alloc_segments: allocate segments for 8088 or higher processor
14795 */
14796
14797 #include "kernel.h"
14798 #include <signal.h>
14799 #include <unistd.h>
14800 #include <sys/sigcontext.h>
14801 #include <sys/ptrace.h>
14802 #include <minix/boot.h>
14803 #include <minix/callnr.h>
14804 #include <minix/com.h>
14805 #include "proc.h"
14806 #include "protect.h"
14807
14808 /* PSW masks. */
14809 #define IF_MASK 0x00000200
14810 #define IOPL_MASK 0x003000
14811
14812 PRIVATE message m;
14813
14814 FORWARD _PROTOTYPE( int do_abort, (message *m_ptr) );
14815 FORWARD _PROTOTYPE( int do_copy, (message *m_ptr) );
14816 FORWARD _PROTOTYPE( int do_exec, (message *m_ptr) );
14817 FORWARD _PROTOTYPE( int do_fork, (message *m_ptr) );
14818 FORWARD _PROTOTYPE( int do_gboot, (message *m_ptr) );
14819 FORWARD _PROTOTYPE( int do_getsp, (message *m_ptr) );
14820 FORWARD _PROTOTYPE( int do_kill, (message *m_ptr) );
14821 FORWARD _PROTOTYPE( int do_mem, (message *m_ptr) );
14822 FORWARD _PROTOTYPE( int do_newmap, (message *m_ptr) );
14823 FORWARD _PROTOTYPE( int do_sendsig, (message *m_ptr) );
14824 FORWARD _PROTOTYPE( int do_sigreturn, (message *m_ptr) );
14825 FORWARD _PROTOTYPE( int do_endsig, (message *m_ptr) );
14826 FORWARD _PROTOTYPE( int do_times, (message *m_ptr) );
14827 FORWARD _PROTOTYPE( int do_trace, (message *m_ptr) );
14828 FORWARD _PROTOTYPE( int do_umap, (message *m_ptr) );
14829 FORWARD _PROTOTYPE( int do_xit, (message *m_ptr) );
14830 FORWARD _PROTOTYPE( int do_vcopy, (message *m_ptr) );
14831 FORWARD _PROTOTYPE( int do_getmap, (message *m_ptr) );
14832
14833
14834 /*===========================================================================*
14835 * sys_task *
14836 *===========================================================================*/
14837 PUBLIC void sys_task()
14838 {
14839 /* Main entry point of sys_task. Get the message and dispatch on type. */
14840
14841 register int r;
14842
14843 while (TRUE) {
14844 receive(ANY, &m);
14845
14846 switch (m.m_type) { /* which system call */
14847 case SYS_FORK: r = do_fork(&m); break;
14848 case SYS_NEWMAP: r = do_newmap(&m); break;
14849 case SYS_GETMAP: r = do_getmap(&m); break;
14850 case SYS_EXEC: r = do_exec(&m); break;
14851 case SYS_XIT: r = do_xit(&m); break;
14852 case SYS_GETSP: r = do_getsp(&m); break;
14853 case SYS_TIMES: r = do_times(&m); break;
14854 case SYS_ABORT: r = do_abort(&m); break;
14855 case SYS_SENDSIG: r = do_sendsig(&m); break;
14856 case SYS_SIGRETURN: r = do_sigreturn(&m); break;
14857 case SYS_KILL: r = do_kill(&m); break;
14858 case SYS_ENDSIG: r = do_endsig(&m); break;
14859 case SYS_COPY: r = do_copy(&m); break;
14860 case SYS_VCOPY: r = do_vcopy(&m); break;
14861 case SYS_GBOOT: r = do_gboot(&m); break;
14862 case SYS_MEM: r = do_mem(&m); break;
14863 case SYS_UMAP: r = do_umap(&m); break;
14864 case SYS_TRACE: r = do_trace(&m); break;
14865 default: r = E_BAD_FCN;
14866 }
14867
14868 m.m_type = r; /* 'r' reports status of call */
14869 send(m.m_source, &m); /* send reply to caller */
14870 }
14871 }
14874 /*===========================================================================*
14875 * do_fork *
14876 *===========================================================================*/
14877 PRIVATE int do_fork(m_ptr)
14878 register message *m_ptr; /* pointer to request message */
14879 {
14880 /* Handle sys_fork(). m_ptr->PROC1 has forked. The child is m_ptr->PROC2. */
14881
14882 reg_t old_ldt_sel;
14883 register struct proc *rpc;
14884 struct proc *rpp;
14885
14886 if (!isoksusern(m_ptr->PROC1) || !isoksusern(m_ptr->PROC2))
14887 return(E_BAD_PROC);
14888 rpp = proc_addr(m_ptr->PROC1);
14889 rpc = proc_addr(m_ptr->PROC2);
14890
14891 /* Copy parent 'proc' struct to child. */
14892 old_ldt_sel = rpc->p_ldt_sel; /* stop this being obliterated by copy */
14893
14894 *rpc = *rpp; /* copy 'proc' struct */
14895
14896 rpc->p_ldt_sel = old_ldt_sel;
14897 rpc->p_nr = m_ptr->PROC2; /* this was obliterated by copy */
14898
14899 rpc->p_flags |= NO_MAP; /* inhibit the process from running */
14900
14901 rpc->p_flags &= ~(PENDING | SIG_PENDING | P_STOP);
14902
14903 /* Only 1 in group should have PENDING, child does not inherit trace status*/
14904 sigemptyset(&rpc->p_pending);
14905 rpc->p_pendcount = 0;
14906 rpc->p_pid = m_ptr->PID; /* install child's pid */
14907 rpc->p_reg.retreg = 0; /* child sees pid = 0 to know it is child */
14908
14909 rpc->user_time = 0; /* set all the accounting times to 0 */
14910 rpc->sys_time = 0;
14911 rpc->child_utime = 0;
14912 rpc->child_stime = 0;
14913
14914 return(OK);
14915 }
14918 /*===========================================================================*
14919 * do_newmap *
14920 *===========================================================================*/
14921 PRIVATE int do_newmap(m_ptr)
14922 message *m_ptr; /* pointer to request message */
14923 {
14924 /* Handle sys_newmap(). Fetch the memory map from MM. */
14925
14926 register struct proc *rp;
14927 phys_bytes src_phys;
14928 int caller; /* whose space has the new map (usually MM) */
14929 int k; /* process whose map is to be loaded */
14930 int old_flags; /* value of flags before modification */
14931 struct mem_map *map_ptr; /* virtual address of map inside caller (MM) */
14932
14933 /* Extract message parameters and copy new memory map from MM. */
14934 caller = m_ptr->m_source;
14935 k = m_ptr->PROC1;
14936 map_ptr = (struct mem_map *) m_ptr->MEM_PTR;
14937 if (!isokprocn(k)) return(E_BAD_PROC);
14938 rp = proc_addr(k); /* ptr to entry of user getting new map */
14939
14940 /* Copy the map from MM. */
14941 src_phys = umap(proc_addr(caller), D, (vir_bytes) map_ptr, sizeof(rp->p_map));
14942 if (src_phys == 0) panic("bad call to sys_newmap", NO_NUM);
14943 phys_copy(src_phys, vir2phys(rp->p_map), (phys_bytes) sizeof(rp->p_map));
14944
14945 alloc_segments(rp);
14946 old_flags = rp->p_flags; /* save the previous value of the flags */
14947 rp->p_flags &= ~NO_MAP;
14948 if (old_flags != 0 && rp->p_flags == 0) lock_ready(rp);
14949
14950 return(OK);
14951 }
14954 /*===========================================================================*
14955 * do_getmap *
14956 *===========================================================================*/
14957 PRIVATE int do_getmap(m_ptr)
14958 message *m_ptr; /* pointer to request message */
14959 {
14960 /* Handle sys_getmap(). Report the memory map to MM. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -