- Fixed comments in various system call handlers. Work in progress on new

sys_privctl() call to dynamically start servers and drivers.

- Shutdown sequence slightly adjusted: called as watchdog timer to let the
  busy sys_abort() call from the PM return first.

- Changed umap_bios() to have more restrictive check: BIOS memory is now
  allowed in BIOS_MEM_BEGIN to END (interrupt vectors) and BASE_MEM_TOP
  to UPPER_MEM_END. Hopefully this keeps QEMU and Bochs happy.
This commit is contained in:
Jorrit Herder 2005-07-21 18:36:40 +00:00
parent 8d3e390bda
commit f0594a9e6d
22 changed files with 157 additions and 161 deletions

View file

@ -33,7 +33,7 @@
#define USE_SDEVIO 1 /* perform I/O request on a buffer */
#define USE_IRQCTL 1 /* set an interrupt policy */
#define USE_SEGCTL 1 /* set up a remote segment */
#define USE_SVRCTL 1 /* system server control */
#define USE_PRIVCTL 1 /* system privileges control */
#define USE_NICE 1 /* change scheduling priority */
#define USE_UMAP 1 /* map virtual to physical address */
#define USE_VIRCOPY 1 /* copy using virtual addressing */

View file

@ -76,18 +76,14 @@ PUBLIC void main()
for (i=0; i < NR_BOOT_PROCS; ++i) {
ip = &image[i]; /* process' attributes */
rp = proc_addr(ip->proc_nr); /* get process pointer */
(void) init_proc(rp, NIL_SYS_PROC);
#if DEAD_CODE
(ip->flags & SYS_PROC) ?
NIL_SYS_PROC : NIL_PROC); /* initialize new process */
#endif
strncpy(rp->p_name, ip->proc_name, P_NAME_LEN); /* set name */
rp->p_name[P_NAME_LEN-1] = '\0'; /* just for safety */
rp->p_max_priority = ip->priority; /* max scheduling priority */
rp->p_priority = ip->priority; /* current priority */
rp->p_quantum_size = ip->quantum; /* quantum size in ticks */
rp->p_sched_ticks = ip->quantum; /* current credit */
rp->p_full_quantums = QUANTUMS(ip->priority); /* quantums left */
rp->p_full_quantums = QUANTUMS(ip->priority); /* nr quantums left */
strncpy(rp->p_name, ip->proc_name, P_NAME_LEN); /* set process name */
(void) set_priv(rp, (ip->flags & SYS_PROC)); /* assign structure */
rp->p_priv->s_flags = ip->flags; /* process flags */
rp->p_priv->s_call_mask = ip->call_mask;/* allowed system calls */
if (i-NR_TASKS < 0) { /* part of the kernel? */
@ -188,14 +184,16 @@ PRIVATE void announce(void)
/*==========================================================================*
* prepare_shutdown *
*==========================================================================*/
PUBLIC void prepare_shutdown(how)
int how; /* reason to shut down */
PUBLIC void prepare_shutdown(tp)
timer_t *tp;
{
/* This function prepares to shutdown MINIX. It uses a global flag to make
* sure it is only executed once. Unless a CPU exception occurred, the
/* This function prepares to shutdown MINIX. It is called by a watchdog
* timer if this is a normal abort so that the sys_abort() call can return
* first. The timer structure passes the shutdown status as an argument.
*/
static timer_t shutdown_timer; /* timer for watchdog function */
register struct proc *rp;
static timer_t shutdown_timer;
int how = tmr_arg(tp)->ta_int;
message m;
/* Show debugging dumps on panics. Make sure that the TTY task is still
@ -215,8 +213,9 @@ int how; /* reason to shut down */
* run their shutdown code, e.g, to synchronize the FS or to let the TTY
* switch to the first console.
*/
kprintf("Sending SIGKSTOP to system processes ...\n");
for (rp=BEG_PROC_ADDR; rp<END_PROC_ADDR; rp++) {
if (! isemptyp(rp) && (priv(rp)->s_flags & SYS_PROC) && ! iskernelp(rp))
if (!isemptyp(rp) && (priv(rp)->s_flags & SYS_PROC) && !iskernelp(rp))
send_sig(proc_nr(rp), SIGKSTOP);
}
@ -224,9 +223,8 @@ int how; /* reason to shut down */
* scheduled by setting a watchog timer that calls shutdown(). The timer
* argument passes the shutdown status.
*/
kprintf("Informed system about upcoming shutdown with SIGKSTOP signal.\n");
kprintf("Time for cleanup is allowed. MINIX will now be brought down.\n");
tmr_arg(&shutdown_timer)->ta_int = how; /* pass how in timer */
kprintf("MINIX will now be shut down ...\n");
tmr_arg(&shutdown_timer)->ta_int = how;
set_timer(&shutdown_timer, get_uptime() + SHUTDOWN_TICKS, shutdown);
}

View file

@ -308,6 +308,7 @@ unsigned flags; /* system call flags */
return(OK); /* report success */
}
#if TEMP_CODE
ntf_q_pp = &caller_ptr->p_ntf_q; /* get pointer pointer */
while (*ntf_q_pp != NULL) {
if (src == ANY || src == (*ntf_q_pp)->n_source) {
@ -328,6 +329,7 @@ unsigned flags; /* system call flags */
ntf_q_pp = &(*ntf_q_pp)->n_next; /* proceed to next */
}
}
#endif
/* Check caller queue. Use pointer pointers to keep code simple. */
xpp = &caller_ptr->p_caller_q;

View file

@ -66,7 +66,6 @@ struct proc {
#define SIGNALED 0x10 /* set when new kernel signal arrives */
#define SIG_PENDING 0x20 /* unready while signal being processed */
#define P_STOP 0x40 /* set when process is being traced */
#define NO_PRIV 0x80 /* privilege structure not yet initialized */
/* Scheduling priorities for p_priority. Values must start at zero (highest
* priority) and increment. Priorities of the processes in the boot image can

View file

@ -17,8 +17,7 @@ _PROTOTYPE( void reset_timer, (struct timer *tp) );
/* main.c */
_PROTOTYPE( void main, (void) );
_PROTOTYPE( void prepare_shutdown, (int how) );
_PROTOTYPE( void stop_sequence, (struct timer *tp) );
_PROTOTYPE( void prepare_shutdown, (struct timer *tp) );
/* utility.c */
_PROTOTYPE( void kprintf, (const char *fmt, ...) );
@ -41,8 +40,7 @@ _PROTOTYPE( void cstart, (U16_t cs, U16_t ds, U16_t mds,
/* system.c */
_PROTOTYPE( void send_sig, (int proc_nr, int sig_nr) );
_PROTOTYPE( void cause_sig, (int proc_nr, int sig_nr) );
_PROTOTYPE( int init_proc, (register struct proc *rc, struct proc *rp) );
_PROTOTYPE( void clear_proc, (register struct proc *rc) );
_PROTOTYPE( int set_priv, (register struct proc *rc,int sys_proc_flag) );
_PROTOTYPE( phys_bytes numap_local, (int proc_nr, vir_bytes vir_addr,
vir_bytes bytes) );
_PROTOTYPE( void sys_task, (void) );

View file

@ -11,10 +11,9 @@
*
* In addition to the main sys_task() entry point, which starts the main loop,
* there are several other minor entry points:
* send_sig: send signal directly to a system process
* set_priv: assign privilege structure to user or system process
* send_sig: send a signal directly to a system process
* cause_sig: take action to cause a signal to occur via PM
* init_proc: initialize a process, during start up or fork
* clear_proc: clean up a process in the process table, e.g. on exit
* umap_local: map virtual address in LOCAL_SEG to physical
* umap_remote: map virtual address in REMOTE_SEG to physical
* umap_bios: map virtual address in BIOS_SEG to physical
@ -24,9 +23,7 @@
* generic_handler: interrupt handler for user-level device drivers
*
* Changes:
* Apr 25, 2005 new init_proc() function (Jorrit N. Herder)
* Apr 25, 2005 made mapping of call vector explicit (Jorrit N. Herder)
* Oct 29, 2004 new clear_proc() function (Jorrit N. Herder)
* Oct 17, 2004 generic handler and IRQ policies (Jorrit N. Herder)
* Oct 10, 2004 dispatch system calls from call vector (Jorrit N. Herder)
* Sep 30, 2004 source code documentation updated (Jorrit N. Herder)
@ -40,7 +37,6 @@
#include <signal.h>
#include <unistd.h>
#include <sys/sigcontext.h>
#include <sys/svrctl.h>
#if (CHIP == INTEL)
#include <ibm/memory.h>
#include "protect.h"
@ -127,7 +123,6 @@ PRIVATE void initialize(void)
call_vec[i] = do_unused;
}
/* Process management. */
map(SYS_FORK, do_fork); /* a process forked a new process */
map(SYS_NEWMAP, do_newmap); /* set up a process memory map */
map(SYS_EXEC, do_exec); /* update process after execute */
@ -155,8 +150,8 @@ PRIVATE void initialize(void)
/* System control. */
map(SYS_ABORT, do_abort); /* abort MINIX */
map(SYS_GETINFO, do_getinfo); /* request system information */
map(SYS_PRIVCTL, do_privctl); /* system privileges control */
map(SYS_SEGCTL, do_segctl); /* add segment and get selector */
map(SYS_SVRCTL, do_svrctl); /* kernel control functions */
/* Copying. */
map(SYS_UMAP, do_umap); /* map virtual to physical address */
@ -169,93 +164,28 @@ PRIVATE void initialize(void)
/*===========================================================================*
* init_proc *
* set_priv *
*===========================================================================*/
PUBLIC int init_proc(rc, rp)
PUBLIC int set_priv(rc, proc_type)
register struct proc *rc; /* new (child) process pointer */
struct proc *rp; /* prototype (parent) process */
int proc_type; /* system or user process flag */
{
register struct priv *sp; /* process' privilege structure */
int i;
/* Get a privilege structure. All user processes share the same privilege
* structure. System processes get their own privilege structure.
*/
register struct priv *sp; /* privilege structure */
/* If there is a prototype process to initialize from, use it. Otherwise,
* assume the caller will take care of initialization, but make sure that
* the new process gets a pointer to a system properties structure.
*/
if (rp == NIL_PROC) { /* new user process */
kprintf("init_proc() for new user proc %d\n", proc_nr(rc));
sp = &priv[USER_PRIV_ID];
sp->s_proc_nr = ANY; /* misuse for users */
rc->p_priv = sp; /* assign to process */
return(OK);
} else if (rp == NIL_SYS_PROC) { /* new system process */
for (sp = BEG_PRIV_ADDR, i = 0; sp < END_PRIV_ADDR; ++sp, ++i) {
if (sp->s_proc_nr == NONE) { /* found free slot */
sp->s_proc_nr = proc_nr(rc); /* set association */
rc->p_priv = sp; /* assign to process */
return(OK);
}
}
kprintf("No free PRIV structure!\n", NO_NUM);
return(ENOSPC); /* out of resources */
} else { /* forked process */
kprintf("init_proc() from prototype %d\n", proc_nr(rp));
if (proc_type == SYS_PROC) { /* find a new slot */
for (sp = BEG_PRIV_ADDR; sp < END_PRIV_ADDR; ++sp)
if (sp->s_proc_nr == NONE && sp->s_id != USER_PRIV_ID) break;
if (sp->s_proc_nr != NONE) return(ENOSPC);
rc->p_priv = sp; /* assign new slot */
rc->p_priv->s_proc_nr = proc_nr(rc); /* set association */
} else {
rc->p_priv = &priv[USER_PRIV_ID]; /* use shared slot */
rc->p_priv->s_proc_nr = INIT_PROC_NR; /* set association */
}
}
/*===========================================================================*
* clear_proc *
*===========================================================================*/
PUBLIC void clear_proc(rc)
register struct proc *rc; /* slot of process to clean up */
{
register struct proc *rp; /* iterate over process table */
register struct proc **xpp; /* iterate over caller queue */
int i;
/* Turn off any alarm timers at the clock. */
reset_timer(&priv(rc)->s_alarm_timer);
/* Make sure that the exiting process is no longer scheduled. */
if (rc->p_rts_flags == 0) lock_unready(rc);
/* If the process being terminated happens to be queued trying to send a
* message (e.g., the process was killed by a signal, rather than it doing
* a normal exit), then it must be removed from the message queues.
*/
if (rc->p_rts_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_caller_q == NIL_PROC) continue;
/* Make sure that the exiting process is not on the queue. */
xpp = &rp->p_caller_q;
while (*xpp != NIL_PROC) { /* check entire queue */
if (*xpp == rc) { /* process is on the queue */
*xpp = (*xpp)->p_q_link; /* replace by next process */
break;
}
xpp = &(*xpp)->p_q_link; /* proceed to next queued */
}
}
}
/* Check the table with IRQ hooks to see if hooks should be released. */
for (i=0; i < NR_IRQ_HOOKS; i++) {
if (irq_hooks[i].proc_nr == proc_nr(rc)) {
rm_irq_handler(&irq_hooks[i]); /* remove interrupt handler */
irq_hooks[i].proc_nr = NONE; /* mark hook as free */
}
}
/* Now it is safe to release the process table slot. If this is a system
* process, also release its privilege structure. Further cleanup is not
* needed at this point. All important fields are reinitialized when the
* slots are assigned to another, new process.
*/
rc->p_rts_flags = SLOT_FREE;
if (priv(rc)->s_flags & SYS_PROC) priv(rc)->s_proc_nr = NONE;
return(OK);
}
@ -390,12 +320,12 @@ vir_bytes bytes; /* # of bytes to be copied */
*/
/* Check all acceptable ranges. */
#if DEAD_CODE /* to be replaced by proper ranges, e.g. 640 - 1 KB */
if (vir_addr >= BIOS_MEM_BEGIN && vir_addr + bytes <= BIOS_MEM_END)
return (phys_bytes) vir_addr;
else if (vir_addr >= UPPER_MEM_BEGIN && vir_addr + bytes <= UPPER_MEM_END)
else if (vir_addr >= BASE_MEM_TOP && vir_addr + bytes <= UPPER_MEM_END)
return (phys_bytes) vir_addr;
#else
#if DEAD_CODE /* brutal fix for QEMU and Bochs, if above doesn't work */
if (vir_addr >= BIOS_MEM_BEGIN && vir_addr + bytes <= UPPER_MEM_END)
return (phys_bytes) vir_addr;
#endif

View file

@ -82,9 +82,9 @@ _PROTOTYPE( int do_getinfo, (message *m_ptr) );
#define do_getinfo do_unused
#endif
_PROTOTYPE( int do_svrctl, (message *m_ptr) );
#if ! USE_SVRCTL
#define do_svrctl do_unused
_PROTOTYPE( int do_privctl, (message *m_ptr) );
#if ! USE_PRIVCTL
#define do_privctl do_unused
#endif
_PROTOTYPE( int do_segctl, (message *m_ptr) );

View file

@ -34,7 +34,7 @@ OBJECTS = \
$(SYSTEM)(do_vcopy.o) \
$(SYSTEM)(do_umap.o) \
$(SYSTEM)(do_memset.o) \
$(SYSTEM)(do_svrctl.o) \
$(SYSTEM)(do_privctl.o) \
$(SYSTEM)(do_segctl.o) \
$(SYSTEM)(do_getksig.o) \
$(SYSTEM)(do_endksig.o) \
@ -129,8 +129,8 @@ $(SYSTEM)(do_getinfo.o): do_getinfo.c
$(SYSTEM)(do_abort.o): do_abort.c
$(CC) do_abort.c
$(SYSTEM)(do_svrctl.o): do_svrctl.c
$(CC) do_svrctl.c
$(SYSTEM)(do_privctl.o): do_privctl.c
$(CC) do_privctl.c
$(SYSTEM)(do_segctl.o): do_segctl.c
$(CC) do_segctl.c

View file

@ -24,9 +24,10 @@ message *m_ptr; /* pointer to request message */
* or ESC after debugging dumps).
*/
int how = m_ptr->ABRT_HOW;
timer_t *tp;
/* See if the monitor is to run the specified instructions. */
if (how == RBT_MONITOR) {
/* The monitor is to run the specified instructions. */
int proc_nr = m_ptr->ABRT_MON_PROC;
int length = m_ptr->ABRT_MON_LEN + 1;
vir_bytes src_vir = (vir_bytes) m_ptr->ABRT_MON_ADDR;
@ -38,7 +39,14 @@ message *m_ptr; /* pointer to request message */
else
phys_copy(src_phys, kinfo.params_base, (phys_bytes) length);
}
prepare_shutdown(how);
/* Set a watchdog timer to shut down, so that this call returns first.
* The timer will expire at the next clock tick, which can be any moment.
* The CLOCK task is only scheduled when the SYSTEM task is done, though.
*/
tp = &priv(proc_addr(KERNEL))->s_alarm_timer;
tmr_arg(tp)->ta_int = how; /* pass status as timer argument */
set_timer(tp, get_uptime(), prepare_shutdown);
return(OK); /* pro-forma (really EDISASTER) */
}

View file

@ -2,7 +2,6 @@
* m_type: SYS_SETALARM
*
* The parameters for this system call are:
* m2_i1: ALRM_PROC_NR (set alarm for this process)
* m2_l1: ALRM_EXP_TIME (alarm's expiration time)
* m2_i2: ALRM_ABS_TIME (expiration time is absolute?)
* m2_l1: ALRM_TIME_LEFT (return seconds left of previous)
@ -31,9 +30,7 @@ message *m_ptr; /* pointer to request message */
clock_t uptime; /* placeholder for current uptime */
/* Extract shared parameters from the request message. */
proc_nr = m_ptr->ALRM_PROC_NR; /* process to interrupt later */
if (SELF == proc_nr) proc_nr = m_ptr->m_source;
if (! isokprocn(proc_nr)) return(EINVAL);
proc_nr = m_ptr->m_source; /* process to interrupt later */
exp_time = m_ptr->ALRM_EXP_TIME; /* alarm's expiration time */
use_abs_time = m_ptr->ALRM_ABS_TIME; /* flag for absolute time */
@ -50,7 +47,7 @@ message *m_ptr; /* pointer to request message */
m_ptr->ALRM_TIME_LEFT = (tp->tmr_exp_time - uptime);
}
/* Finally, (re)set the timer depending on 'exp_time'. */
/* Finally, (re)set the timer depending on the expiration time. */
if (exp_time == 0) {
reset_timer(tp);
} else {

View file

@ -23,7 +23,8 @@ PUBLIC int do_copy(m_ptr)
register message *m_ptr; /* pointer to request message */
{
/* Handle sys_vircopy() and sys_physcopy(). Copy data using virtual or
* physical addressing.
* physical addressing. Although a single handler function is used, there
* are two different system calls so that permissions can be checked.
*/
struct vir_addr vir_addr[2]; /* virtual source and destination address */
vir_bytes bytes; /* number of bytes to copy */

View file

@ -22,7 +22,7 @@
PUBLIC int do_devio(m_ptr)
register message *m_ptr; /* pointer to request message */
{
/* Perform actual device I/O for byte, word, and long values. */
/* Process a single I/O request for byte, word, and long values. */
if (m_ptr->DIO_REQUEST == DIO_INPUT) {
switch (m_ptr->DIO_TYPE) {
case DIO_BYTE: m_ptr->DIO_VALUE = inb(m_ptr->DIO_PORT); break;

View file

@ -9,6 +9,8 @@
#if USE_EXIT
FORWARD _PROTOTYPE( void clear_proc, (register struct proc *rc));
/*===========================================================================*
* do_exit *
*===========================================================================*/
@ -37,6 +39,61 @@ message *m_ptr; /* pointer to request message */
clear_proc(proc_addr(m_ptr->m_source));
return(EDONTREPLY);
}
/*===========================================================================*
* clear_proc *
*===========================================================================*/
PRIVATE void clear_proc(rc)
register struct proc *rc; /* slot of process to clean up */
{
register struct proc *rp; /* iterate over process table */
register struct proc **xpp; /* iterate over caller queue */
int i;
/* Turn off any alarm timers at the clock. */
reset_timer(&priv(rc)->s_alarm_timer);
/* Make sure that the exiting process is no longer scheduled. */
if (rc->p_rts_flags == 0) lock_unready(rc);
/* If the process being terminated happens to be queued trying to send a
* message (e.g., the process was killed by a signal, rather than it doing
* a normal exit), then it must be removed from the message queues.
*/
if (rc->p_rts_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_caller_q == NIL_PROC) continue;
/* Make sure that the exiting process is not on the queue. */
xpp = &rp->p_caller_q;
while (*xpp != NIL_PROC) { /* check entire queue */
if (*xpp == rc) { /* process is on the queue */
*xpp = (*xpp)->p_q_link; /* replace by next process */
break;
}
xpp = &(*xpp)->p_q_link; /* proceed to next queued */
}
}
}
/* Check the table with IRQ hooks to see if hooks should be released. */
for (i=0; i < NR_IRQ_HOOKS; i++) {
if (irq_hooks[i].proc_nr == proc_nr(rc)) {
rm_irq_handler(&irq_hooks[i]); /* remove interrupt handler */
irq_hooks[i].proc_nr = NONE; /* mark hook as free */
}
}
/* Now it is safe to release the process table slot. If this is a system
* process, also release its privilege structure. Further cleanup is not
* needed at this point. All important fields are reinitialized when the
* slots are assigned to another, new process.
*/
rc->p_rts_flags = SLOT_FREE;
if (priv(rc)->s_flags & SYS_PROC) priv(rc)->s_proc_nr = NONE;
}
#endif /* USE_EXIT */

View file

@ -22,7 +22,6 @@ PUBLIC int do_fork(m_ptr)
register message *m_ptr; /* pointer to request message */
{
/* Handle sys_fork(). PR_PPROC_NR has forked. The child is PR_PROC_NR. */
#if (CHIP == INTEL)
reg_t old_ldt_sel;
#endif
@ -43,10 +42,6 @@ register message *m_ptr; /* pointer to request message */
#endif
rpc->p_nr = m_ptr->PR_PROC_NR; /* this was obliterated by copy */
#if TEMP_CODE
rpc->p_ntf_q = NULL; /* remove pending notifications */
#endif
/* Only one in group should have SIGNALED, child doesn't inherit tracing. */
rpc->p_rts_flags |= NO_MAP; /* inhibit process from running */
rpc->p_rts_flags &= ~(SIGNALED | SIG_PENDING | P_STOP);

View file

@ -23,7 +23,9 @@
PUBLIC int do_getinfo(m_ptr)
register message *m_ptr; /* pointer to request message */
{
/* Request system information to be copied to caller's address space. */
/* Request system information to be copied to caller's address space. This
* call simply copies entire data structures to the caller.
*/
size_t length;
phys_bytes src_phys;
phys_bytes dst_phys;
@ -117,7 +119,7 @@ register message *m_ptr; /* pointer to request message */
/* Try to make the actual copy for the requested data. */
if (m_ptr->I_VAL_LEN > 0 && length > m_ptr->I_VAL_LEN) return (E2BIG);
proc_nr = m_ptr->m_source; /* only caller can request copy */
proc_nr = m_ptr->m_source; /* only caller can request copy */
dst_phys = numap_local(proc_nr, (vir_bytes) m_ptr->I_VAL_PTR, length);
if (src_phys == 0 || dst_phys == 0) return(EFAULT);
phys_copy(src_phys, dst_phys, length);

View file

@ -2,9 +2,9 @@
* m_type: SYS_MEMSET
*
* The parameters for this system call are:
* m5_l1: CP_SRC_ADDR (virtual address)
* m5_l2: CP_DST_ADDR (returns physical address)
* m5_l3: CP_NR_BYTES (size of datastructure)
* m1_p1: MEM_PTR (virtual address)
* m1_i1: MEM_COUNT (returns physical address)
* m1_i2: MEM_PATTERN (size of datastructure)
*/
#include "../system.h"
@ -17,9 +17,9 @@
PUBLIC int do_memset(m_ptr)
register message *m_ptr;
{
/* Handle sys_memset(). */
/* Handle sys_memset(). This writes a pattern into the specified memory. */
unsigned long p;
unsigned char c = m_ptr->MEM_CHAR;
unsigned char c = m_ptr->MEM_PATTERN;
p = c | (c << 8) | (c << 16) | (c << 24);
phys_memset((phys_bytes) m_ptr->MEM_PTR, p, (phys_bytes) m_ptr->MEM_COUNT);
return(OK);

View file

@ -62,7 +62,7 @@ message *m_ptr; /* pointer to request message */
#endif
/* Restore the registers. */
memcpy(&rp->p_reg, (char *)&sc.sc_regs, sizeof(struct sigregs));
memcpy(&rp->p_reg, &sc.sc_regs, sizeof(struct sigregs));
return(OK);
}
#endif /* USE_SIGRETURN */

View file

@ -41,7 +41,7 @@ message *m_ptr; /* pointer to request message */
scp = (struct sigcontext *) smsg.sm_stkptr - 1;
/* Copy the registers to the sigcontext structure. */
memcpy(&sc.sc_regs, &rp->p_reg, sizeof(struct sigregs));
memcpy(&sc.sc_regs, (char *) &rp->p_reg, sizeof(struct sigregs));
/* Finish the sigcontext initialization. */
sc.sc_flags = SC_SIGCONTEXT;

View file

@ -25,7 +25,10 @@ PRIVATE struct vir_cp_req vir_cp_req[VCOPY_VEC_SIZE];
PUBLIC int do_vcopy(m_ptr)
register message *m_ptr; /* pointer to request message */
{
/* Handle sys_virvcopy(). Handle virtual copy requests from vector. */
/* Handle sys_virvcopy() and sys_physvcopy() that pass a vector with copy
* requests. Although a single handler function is used, there are two
* different system calls so that permissions can be checked.
*/
int nr_req;
int caller_pid;
vir_bytes caller_vir;

View file

@ -13,7 +13,6 @@
#if USE_VDEVIO
/* Buffer for SYS_VDEVIO to copy (port,value)-pairs from/ to user. */
PRIVATE char vdevio_pv_buf[VDEVIO_BUF_SIZE];
@ -42,7 +41,7 @@ register message *m_ptr; /* pointer to request message */
pvw_pair_t *pvw_pairs; /* needed for word values */
pvl_pair_t *pvl_pairs; /* needed for long values */
int i;
pid_t caller_pid; /* process id of caller */
int caller_proc; /* process number of caller */
size_t bytes; /* # bytes to be copied */
vir_bytes caller_vir; /* virtual address at caller */
phys_bytes caller_phys; /* physical address at caller */
@ -69,9 +68,9 @@ register message *m_ptr; /* pointer to request message */
}
/* Calculate physical addresses and copy (port,value)-pairs from user. */
caller_pid = (pid_t) m_ptr->m_source;
caller_proc = m_ptr->m_source;
caller_vir = (vir_bytes) m_ptr->DIO_VEC_ADDR;
caller_phys = umap_local(proc_addr(caller_pid), D, caller_vir, bytes);
caller_phys = umap_local(proc_addr(caller_proc), D, caller_vir, bytes);
if (0 == caller_phys) return EFAULT;
kernel_phys = vir2phys(vdevio_pv_buf);
phys_copy(caller_phys, kernel_phys, (phys_bytes) bytes);

View file

@ -19,12 +19,12 @@
* or PRIVATE. The reason for this is that extern variables cannot have a
* default initialization. If such variables are shared, they must also be
* declared in one of the *.h files without the initialization. Examples
* include 'tasktab' (this file) and 'idt'/'gdt' (protect.c).
* include 'system_image' (this file) and 'idt' and 'gdt' (protect.c).
*
* Changes:
* Nov 10, 2004 removed controller->driver mappings (Jorrit N. Herder)
* Oct 17, 2004 updated above and tasktab comments (Jorrit N. Herder)
* May 01, 2004 included p_sendmask in tasktab (Jorrit N. Herder)
* May 01, 2004 changed struct for system image (Jorrit N. Herder)
*/
#define _TABLE
@ -59,22 +59,21 @@ PUBLIC char *t_stack[TOT_STACK_SPACE / sizeof(char *)];
* mask, and a name for the process table. For kernel processes, the startup
* routine and stack size is also provided.
*/
#define IDLE_F (PREEMPTIBLE | BILLABLE)
#define USER_F (PREEMPTIBLE | RDY_Q_HEAD)
#define USER_F (PREEMPTIBLE | BILLABLE | RDY_Q_HEAD)
#define SYS_F (PREEMPTIBLE | SYS_PROC)
#define TCB_F (SYS_PROC) /* trusted computing base */
#define TASK_F (SYS_PROC)
#define IDLE_T 32 /* ticks */
#define USER_T 8 /* ticks */
#define SYS_T 16 /* ticks */
PUBLIC struct system_image image[] = {
{ IDLE, idle_task, IDLE_F, IDLE_T, IDLE_Q, IDLE_S, EMPTY_CALL_MASK, 0, "IDLE" },
{ CLOCK, clock_task, TCB_F, SYS_T, TASK_Q, CLOCK_S, SYSTEM_CALL_MASK, 0, "CLOCK" },
{ SYSTEM, sys_task, TCB_F, SYS_T, TASK_Q, SYSTEM_S, SYSTEM_CALL_MASK, 0, "SYS" },
{ HARDWARE, 0, 0, SYS_T, TASK_Q, HARDWARE_S, EMPTY_CALL_MASK, 0,"KERNEL" },
{ PM_PROC_NR, 0, TCB_F, SYS_T, 3, 0, SYSTEM_CALL_MASK, 0, "PM" },
{ FS_PROC_NR, 0, TCB_F, SYS_T, 3, 0, SYSTEM_CALL_MASK, 0, "FS" },
{ IDLE, idle_task, USER_F, IDLE_T, IDLE_Q, IDLE_S, EMPTY_CALL_MASK, 0, "IDLE" },
{ CLOCK, clock_task, TASK_F, SYS_T, TASK_Q, CLOCK_S, SYSTEM_CALL_MASK, 0, "CLOCK" },
{ SYSTEM, sys_task, TASK_F, SYS_T, TASK_Q, SYSTEM_S, SYSTEM_CALL_MASK, 0, "SYS" },
{ HARDWARE, 0, TASK_F, SYS_T, TASK_Q, HARDWARE_S, EMPTY_CALL_MASK, 0,"KERNEL" },
{ PM_PROC_NR, 0, SYS_F, SYS_T, 3, 0, SYSTEM_CALL_MASK, 0, "PM" },
{ FS_PROC_NR, 0, SYS_F, SYS_T, 3, 0, SYSTEM_CALL_MASK, 0, "FS" },
{ IS_PROC_NR, 0, SYS_F, SYS_T, 2, 0, SYSTEM_CALL_MASK, 0, "IS" },
{ TTY, 0, SYS_F, SYS_T, 1, 0, SYSTEM_CALL_MASK, 0, "TTY" },
{ MEMORY, 0, SYS_F, SYS_T, 2, 0, SYSTEM_CALL_MASK, 0, "MEMORY" },

View file

@ -19,6 +19,7 @@
#include <stdlib.h>
#include <signal.h>
#include <minix/com.h>
#include "proc.h"
#define END_OF_KMESS -1
FORWARD _PROTOTYPE(void kputc, (int c));
@ -33,6 +34,7 @@ int nr;
{
/* The system has run aground of a fatal kernel error. Terminate execution. */
static int panicking = 0;
timer_t *tp;
if (panicking ++) return; /* prevent recursive panics */
if (mess != NULL) {
@ -40,7 +42,13 @@ int nr;
if (nr != NO_NUM) kprintf(" %d", nr);
kprintf("\n",NO_NUM);
}
prepare_shutdown(RBT_PANIC);
/* Make a direct call to shutdown. Interface requires to pass the shutdown
* status by means of a timer.
*/
tp = &priv(proc_addr(KERNEL))->s_alarm_timer;
tmr_arg(tp)->ta_int = RBT_PANIC;
prepare_shutdown(tp);
}