system.c
来自「MINIX2.0操作系统源码 MINIX2.0操作系统源码」· C语言 代码 · 共 1,159 行 · 第 1/3 页
C
1,159 行
m_ptr->m1_i2 = (int)size;
#endif
strcpy(rc->p_name, "<noname>"); /* process no longer has a name */
/* If the process being terminated happens to be queued trying to send a
* message (i.e., the process was killed by a signal, rather than it doing an
* EXIT), then it must be removed from the message queues.
*/
if (rc->p_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_callerq == NIL_PROC) continue;
if (rp->p_callerq == rc) {
/* Exiting process is on front of this queue. */
rp->p_callerq = rc->p_sendlink;
break;
} else {
/* See if exiting process is in middle of queue. */
np = rp->p_callerq;
while ( ( xp = np->p_sendlink) != NIL_PROC)
if (xp == rc) {
np->p_sendlink = xp->p_sendlink;
break;
} else {
np = xp;
}
}
}
}
#if (CHIP == M68000) && (SHADOWING == 0)
pmmu_delete(rc); /* we're done remove tables */
#endif
if (rc->p_flags & PENDING) --sig_procs;
sigemptyset(&rc->p_pending);
rc->p_pendcount = 0;
rc->p_flags = P_SLOT_FREE;
return(OK);
}
/*===========================================================================*
* do_getsp *
*===========================================================================*/
PRIVATE int do_getsp(m_ptr)
register message *m_ptr; /* pointer to request message */
{
/* Handle sys_getsp(). MM wants to know what sp is. */
register struct proc *rp;
if (!isoksusern(m_ptr->PROC1)) return(E_BAD_PROC);
rp = proc_addr(m_ptr->PROC1);
m_ptr->STACK_PTR = (char *) rp->p_reg.sp; /* return sp here (bad type) */
return(OK);
}
/*===========================================================================*
* do_times *
*===========================================================================*/
PRIVATE int do_times(m_ptr)
register message *m_ptr; /* pointer to request message */
{
/* Handle sys_times(). Retrieve the accounting information. */
register struct proc *rp;
if (!isoksusern(m_ptr->PROC1)) return E_BAD_PROC;
rp = proc_addr(m_ptr->PROC1);
/* Insert the times needed by the TIMES system call in the message. */
lock(); /* halt the volatile time counters in rp */
m_ptr->USER_TIME = rp->user_time;
m_ptr->SYSTEM_TIME = rp->sys_time;
unlock();
m_ptr->CHILD_UTIME = rp->child_utime;
m_ptr->CHILD_STIME = rp->child_stime;
m_ptr->BOOT_TICKS = get_uptime();
return(OK);
}
/*===========================================================================*
* do_abort *
*===========================================================================*/
PRIVATE int do_abort(m_ptr)
message *m_ptr; /* pointer to request message */
{
/* Handle sys_abort. MINIX is unable to continue. Terminate operation. */
char monitor_code[64];
phys_bytes src_phys;
if (m_ptr->m1_i1 == RBT_MONITOR) {
/* The monitor is to run user specified instructions. */
src_phys = numap(m_ptr->m_source, (vir_bytes) m_ptr->m1_p1,
(vir_bytes) sizeof(monitor_code));
if (src_phys == 0) panic("bad monitor code from", m_ptr->m_source);
phys_copy(src_phys, vir2phys(monitor_code),
(phys_bytes) sizeof(monitor_code));
reboot_code = vir2phys(monitor_code);
}
wreboot(m_ptr->m1_i1);
return(OK); /* pro-forma (really EDISASTER) */
}
#if (SHADOWING == 1)
/*===========================================================================*
* do_fresh *
*===========================================================================*/
PRIVATE int do_fresh(m_ptr) /* for 68000 only */
message *m_ptr; /* pointer to request message */
{
/* Handle sys_fresh. Start with fresh process image during EXEC. */
register struct proc *p;
int proc_nr; /* number of process doing the exec */
phys_clicks base, size;
phys_clicks c1, nc;
proc_nr = m_ptr->PROC1; /* slot number of exec-ing process */
if (!isokprocn(proc_nr)) return(E_BAD_PROC);
p = proc_addr(proc_nr);
rmshadow(p, &base, &size);
do_newmap(m_ptr);
c1 = p->p_map[D].mem_phys;
nc = p->p_map[S].mem_phys - p->p_map[D].mem_phys + p->p_map[S].mem_len;
c1 += m_ptr->m1_i2;
nc -= m_ptr->m1_i2;
zeroclicks(c1, nc);
m_ptr->m1_i1 = (int)base;
m_ptr->m1_i2 = (int)size;
return(OK);
}
#endif /* (SHADOWING == 1) */
/*===========================================================================*
* do_sendsig *
*===========================================================================*/
PRIVATE int do_sendsig(m_ptr)
message *m_ptr; /* pointer to request message */
{
/* Handle sys_sendsig, POSIX-style signal */
struct sigmsg smsg;
register struct proc *rp;
phys_bytes src_phys, dst_phys;
struct sigcontext sc, *scp;
struct sigframe fr, *frp;
if (!isokusern(m_ptr->PROC1)) return(E_BAD_PROC);
rp = proc_addr(m_ptr->PROC1);
/* Get the sigmsg structure into our address space. */
src_phys = umap(proc_addr(MM_PROC_NR), D, (vir_bytes) m_ptr->SIG_CTXT_PTR,
(vir_bytes) sizeof(struct sigmsg));
if (src_phys == 0)
panic("do_sendsig can't signal: bad sigmsg address from MM", NO_NUM);
phys_copy(src_phys, vir2phys(&smsg), (phys_bytes) sizeof(struct sigmsg));
/* Compute the usr stack pointer value where sigcontext will be stored. */
scp = (struct sigcontext *) smsg.sm_stkptr - 1;
/* Copy the registers to the sigcontext structure. */
memcpy(&sc.sc_regs, &rp->p_reg, sizeof(struct sigregs));
/* Finish the sigcontext initialization. */
sc.sc_flags = SC_SIGCONTEXT;
sc.sc_mask = smsg.sm_mask;
/* Copy the sigcontext structure to the user's stack. */
dst_phys = umap(rp, D, (vir_bytes) scp,
(vir_bytes) sizeof(struct sigcontext));
if (dst_phys == 0) return(EFAULT);
phys_copy(vir2phys(&sc), dst_phys, (phys_bytes) sizeof(struct sigcontext));
/* Initialize the sigframe structure. */
frp = (struct sigframe *) scp - 1;
fr.sf_scpcopy = scp;
fr.sf_retadr2= (void (*)()) rp->p_reg.pc;
fr.sf_fp = rp->p_reg.fp;
rp->p_reg.fp = (reg_t) &frp->sf_fp;
fr.sf_scp = scp;
fr.sf_code = 0; /* XXX - should be used for type of FP exception */
fr.sf_signo = smsg.sm_signo;
fr.sf_retadr = (void (*)()) smsg.sm_sigreturn;
/* Copy the sigframe structure to the user's stack. */
dst_phys = umap(rp, D, (vir_bytes) frp, (vir_bytes) sizeof(struct sigframe));
if (dst_phys == 0) return(EFAULT);
phys_copy(vir2phys(&fr), dst_phys, (phys_bytes) sizeof(struct sigframe));
/* Reset user registers to execute the signal handler. */
rp->p_reg.sp = (reg_t) frp;
rp->p_reg.pc = (reg_t) smsg.sm_sighandler;
return(OK);
}
/*===========================================================================*
* do_sigreturn *
*===========================================================================*/
PRIVATE int do_sigreturn(m_ptr)
register message *m_ptr;
{
/* POSIX style signals require sys_sigreturn to put things in order before the
* signalled process can resume execution
*/
struct sigcontext sc;
register struct proc *rp;
phys_bytes src_phys;
if (!isokusern(m_ptr->PROC1)) return(E_BAD_PROC);
rp = proc_addr(m_ptr->PROC1);
/* Copy in the sigcontext structure. */
src_phys = umap(rp, D, (vir_bytes) m_ptr->SIG_CTXT_PTR,
(vir_bytes) sizeof(struct sigcontext));
if (src_phys == 0) return(EFAULT);
phys_copy(src_phys, vir2phys(&sc), (phys_bytes) sizeof(struct sigcontext));
/* Make sure that this is not just a jmp_buf. */
if ((sc.sc_flags & SC_SIGCONTEXT) == 0) return(EINVAL);
/* Fix up only certain key registers if the compiler doesn't use
* register variables within functions containing setjmp.
*/
if (sc.sc_flags & SC_NOREGLOCALS) {
rp->p_reg.retreg = sc.sc_retreg;
rp->p_reg.fp = sc.sc_fp;
rp->p_reg.pc = sc.sc_pc;
rp->p_reg.sp = sc.sc_sp;
return (OK);
}
sc.sc_psw = rp->p_reg.psw;
#if (CHIP == INTEL)
/* Don't panic kernel if user gave bad selectors. */
sc.sc_cs = rp->p_reg.cs;
sc.sc_ds = rp->p_reg.ds;
sc.sc_es = rp->p_reg.es;
#if _WORD_SIZE == 4
sc.sc_fs = rp->p_reg.fs;
sc.sc_gs = rp->p_reg.gs;
#endif
#endif
/* Restore the registers. */
memcpy(&rp->p_reg, (char *)&sc.sc_regs, sizeof(struct sigregs));
return(OK);
}
/*===========================================================================*
* do_kill *
*===========================================================================*/
PRIVATE int do_kill(m_ptr)
register message *m_ptr; /* pointer to request message */
{
/* Handle sys_kill(). Cause a signal to be sent to a process via MM.
* Note that this has nothing to do with the kill (2) system call, this
* is how the FS (and possibly other servers) get access to cause_sig to
* send a KSIG message to MM
*/
if (!isokusern(m_ptr->PR)) return(E_BAD_PROC);
cause_sig(m_ptr->PR, m_ptr->SIGNUM);
return(OK);
}
/*===========================================================================*
* do_endsig *
*===========================================================================*/
PRIVATE int do_endsig(m_ptr)
register message *m_ptr; /* pointer to request message */
{
/* Finish up after a KSIG-type signal, caused by a SYS_KILL message or a call
* to cause_sig by a task
*/
register struct proc *rp;
if (!isokusern(m_ptr->PROC1)) return(E_BAD_PROC);
rp = proc_addr(m_ptr->PROC1);
/* MM has finished one KSIG. */
if (rp->p_pendcount != 0 && --rp->p_pendcount == 0
&& (rp->p_flags &= ~SIG_PENDING) == 0)
lock_ready(rp);
return(OK);
}
/*===========================================================================*
* do_copy *
*===========================================================================*/
PRIVATE int do_copy(m_ptr)
register message *m_ptr; /* pointer to request message */
{
/* Handle sys_copy(). Copy data for MM or FS. */
int src_proc, dst_proc, src_space, dst_space;
vir_bytes src_vir, dst_vir;
phys_bytes src_phys, dst_phys, bytes;
/* Dismember the command message. */
src_proc = m_ptr->SRC_PROC_NR;
dst_proc = m_ptr->DST_PROC_NR;
src_space = m_ptr->SRC_SPACE;
dst_space = m_ptr->DST_SPACE;
src_vir = (vir_bytes) m_ptr->SRC_BUFFER;
dst_vir = (vir_bytes) m_ptr->DST_BUFFER;
bytes = (phys_bytes) m_ptr->COPY_BYTES;
/* Compute the source and destination addresses and do the copy. */
#if (SHADOWING == 0)
if (src_proc == ABS)
src_phys = (phys_bytes) m_ptr->SRC_BUFFER;
else {
if (bytes != (vir_bytes) bytes)
/* This would happen for 64K segments and 16-bit vir_bytes.
* It would happen a lot for do_fork except MM uses ABS
* copies for that case.
*/
panic("overflow in count in do_copy", NO_NUM);
#endif
src_phys = umap(proc_addr(src_proc), src_space, src_vir,
(vir_bytes) bytes);
#if (SHADOWING == 0)
}
#endif
#if (SHADOWING == 0)
if (dst_proc == ABS)
dst_phys = (phys_bytes) m_ptr->DST_BUFFER;
else
#endif
dst_phys = umap(proc_addr(dst_proc), dst_space, dst_vir,
(vir_bytes) bytes);
if (src_phys == 0 || dst_phys == 0) return(EFAULT);
phys_copy(src_phys, dst_phys, bytes);
return(OK);
}
/*===========================================================================*
* do_vcopy *
*===========================================================================*/
PRIVATE int do_vcopy(m_ptr)
register message *m_ptr; /* pointer to request message */
{
/* Handle sys_vcopy(). Copy multiple blocks of memory */
int src_proc, dst_proc, vect_s, i;
vir_bytes src_vir, dst_vir, vect_addr;
phys_bytes src_phys, dst_phys, bytes;
cpvec_t cpvec_table[CPVEC_NR];
/* Dismember the command message. */
src_proc = m_ptr->m1_i1;
dst_proc = m_ptr->m1_i2;
vect_s = m_ptr->m1_i3;
vect_addr = (vir_bytes)m_ptr->m1_p1;
if (vect_s > CPVEC_NR) return EDOM;
src_phys= numap (m_ptr->m_source, vect_addr, vect_s * sizeof(cpvec_t));
if (!src_phys) return EFAULT;
phys_copy(src_phys, vir2phys(cpvec_table),
(phys_bytes) (vect_s * sizeof(cpvec_t)));
for (i = 0; i < vect_s; i++) {
src_vir= cpvec_table[i].cpv_src;
dst_vir= cpvec_table[i].cpv_dst;
bytes= cpvec_table[i].cpv_size;
src_phys = numap(src_proc,src_vir,(vir_bytes)bytes);
dst_phys = numap(dst_proc,dst_vir,(vir_bytes)bytes);
if (src_phys == 0 || dst_phys == 0) return(EFAULT);
phys_copy(src_phys, dst_phys, bytes);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?