Kernel changes:
- reinstalled priority changing, now in sched() and unready() - reinstalled check on message buffer in sys_call() - reinstalled check in send masks in sys_call() - changed do_fork() to get new privilege structure for SYS_PROCs - removed some processes from boot image---will be dynamically started later
This commit is contained in:
parent
153fdabb26
commit
8866b4d0ef
15 changed files with 160 additions and 124 deletions
|
@ -51,7 +51,7 @@
|
|||
#define INIT_PSW 0x0200 /* initial psw */
|
||||
#define INIT_TASK_PSW 0x1200 /* initial psw for tasks (with IOPL 1) */
|
||||
#define TRACEBIT 0x0100 /* OR this with psw in proc[] for tracing */
|
||||
#define SETPSW(rp, new) /* permits only certain bits to be set */ \
|
||||
#define SETPSW(rp, new) /* permits only certain bits to be set */ \
|
||||
((rp)->p_reg.psw = (rp)->p_reg.psw & ~0xCD5 | (new) & 0xCD5)
|
||||
#define IF_MASK 0x00000200
|
||||
#define IOPL_MASK 0x003000
|
||||
|
|
|
@ -48,7 +48,7 @@ unsigned vec_nr;
|
|||
ep = &ex_data[vec_nr];
|
||||
|
||||
if (vec_nr == 2) { /* spurious NMI on some machines */
|
||||
kprintf("got spurious NMI\n",NO_NUM);
|
||||
kprintf("got spurious NMI\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -67,8 +67,8 @@ unsigned vec_nr;
|
|||
else
|
||||
kprintf("\n%s\n", ep->msg);
|
||||
kprintf("k_reenter = %d ", k_reenter);
|
||||
kprintf("process %d (%s)", proc_nr(saved_proc), saved_proc->p_name);
|
||||
kprintf("pc = %d:0x%x", (unsigned) saved_proc->p_reg.cs,
|
||||
kprintf("process %d (%s), ", proc_nr(saved_proc), saved_proc->p_name);
|
||||
kprintf("pc = %u:0x%x", (unsigned) saved_proc->p_reg.cs,
|
||||
(unsigned) saved_proc->p_reg.pc);
|
||||
|
||||
panic("exception in a kernel task", NO_NUM);
|
||||
|
|
55
kernel/ipc.h
55
kernel/ipc.h
|
@ -1,6 +1,8 @@
|
|||
#ifndef IPC_H
|
||||
#define IPC_H
|
||||
|
||||
#include <minix/com.h>
|
||||
|
||||
/* Masks and flags for system calls. */
|
||||
#define SYSCALL_FUNC 0x0F /* mask for system call function */
|
||||
#define SYSCALL_FLAGS 0xF0 /* mask for system call flags */
|
||||
|
@ -8,18 +10,51 @@
|
|||
#define FRESH_ANSWER 0x20 /* ignore pending notifications as answer */
|
||||
/* (default behaviour for SENDREC calls) */
|
||||
|
||||
/* System calls (numbers passed when trapping to the kernel). */
|
||||
#define ECHO 0 /* function code for echoing messages */
|
||||
#define SEND 1 /* function code for sending messages */
|
||||
#define RECEIVE 2 /* function code for receiving messages */
|
||||
#define SENDREC 3 /* function code for SEND + RECEIVE */
|
||||
#define NOTIFY 4 /* function code for notifications */
|
||||
#define ALERT 5 /* function code for alerting */
|
||||
/* System call numbers that are passed when trapping to the kernel. The
|
||||
* numbers are carefully defined so that it can easily be seen (based on
|
||||
* the bits that are on) which checks should be done in sys_call().
|
||||
*/
|
||||
#define ECHO 0 /* 0 0 0 0 1 (01) : echo a message */
|
||||
#define SEND 1 /* 0 0 0 1 1 (03) : blocking send */
|
||||
#define RECEIVE 2 /* 0 0 1 0 1 (05) : blocking receive */
|
||||
#define SENDREC 3 /* 0 0 1 1 1 (07) : SEND + RECEIVE */
|
||||
#define NOTIFY 4 /* temp */
|
||||
#define ALERT 5 /* 0 1 0 1 0 (10) : nonblocking notify */
|
||||
|
||||
/* Call masks indicating which system calls a process can make. */
|
||||
#define EMPTY_CALL_MASK (0)
|
||||
/* The following definitions determine whether a calls message buffer and/
|
||||
* or destination processes should be validated.
|
||||
*/
|
||||
#define CHECK_PTR 0x01 /* 0 0 0 0 1 : validate message buffer */
|
||||
#define CHECK_DST 0x02 /* 0 0 0 1 0 : validate message destination */
|
||||
#define CHECK_SRC 0x04 /* 0 0 1 0 0 : validate message source */
|
||||
|
||||
/* Call masks indicating which system calls (traps) a process can make.
|
||||
* The values here are used for the processes in the boot image.
|
||||
*/
|
||||
#define EMPTY_MASK (0)
|
||||
#define FILLED_MASK (~0)
|
||||
#define USER_CALL_MASK (1 << SENDREC)
|
||||
#define SYSTEM_CALL_MASK (~0)
|
||||
|
||||
/* Send masks determine to whom processes can send messages or notifications.
|
||||
* The values here are used for the processes in the boot image. We rely on
|
||||
* the initialization code in main() to match the s_nr_to_id() mapping for the
|
||||
* processes in the boot image, so that the send mask that is defined here
|
||||
* can be directly copied onto map[0] of the actual send mask. Privilege
|
||||
* structure 0 is shared by user processes.
|
||||
*
|
||||
* Note that process numbers in the boot image should not be higher than
|
||||
* "BITCHUNK_BITS - NR_TASKS", because a bitchunk_t field is used to store
|
||||
* the send masks in the table that describes that processes in the image.
|
||||
*/
|
||||
#define s_nr_to_id(n) (NR_TASKS + (n) + 1)
|
||||
#define s(n) (1 << s_nr_to_id(n))
|
||||
#define USER_SEND_MASK (s(PM_PROC_NR) | s(FS_PROC_NR))
|
||||
#define DRIVER_SEND_MASK (s(PM_PROC_NR) | s(FS_PROC_NR) | s(SYSTEM) | \
|
||||
s(CLOCK) | s(PRINTF_PROC) | s(TTY))
|
||||
#define SERVER_SEND_MASK (~0)
|
||||
#define SYSTEM_SEND_MASK (~1)
|
||||
|
||||
/* Sanity check to make sure the send masks can be set. */
|
||||
extern int dummy[(BITCHUNK_BITS-NR_TASKS > INIT_PROC_NR) ? 1 : -1];
|
||||
|
||||
#endif /* IPC_H */
|
||||
|
|
|
@ -49,7 +49,7 @@ PUBLIC void main()
|
|||
|
||||
/* Clear the process table. Anounce each slot as empty and set up mappings
|
||||
* for proc_addr() and proc_nr() macros. Do the same for the table with
|
||||
* system properties structures.
|
||||
* privilege structures for the system processes.
|
||||
*/
|
||||
for (rp = BEG_PROC_ADDR, i = -NR_TASKS; rp < END_PROC_ADDR; ++rp, ++i) {
|
||||
rp->p_rts_flags = SLOT_FREE; /* initialize free slot */
|
||||
|
@ -76,17 +76,17 @@ 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 */
|
||||
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); /* 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? */
|
||||
(void) get_priv(rp, (ip->flags & SYS_PROC)); /* assign structure */
|
||||
priv(rp)->s_flags = ip->flags; /* process flags */
|
||||
priv(rp)->s_call_mask = ip->call_mask; /* allowed traps */
|
||||
priv(rp)->s_send_mask.chunk[0] = ip->send_mask; /* restrict targets */
|
||||
if (iskerneln(proc_nr(rp))) { /* part of the kernel? */
|
||||
if (ip->stksize > 0) { /* HARDWARE stack size is 0 */
|
||||
rp->p_priv->s_stack_guard = (reg_t *) ktsb;
|
||||
*rp->p_priv->s_stack_guard = STACK_GUARD;
|
||||
|
@ -97,14 +97,14 @@ PUBLIC void main()
|
|||
/* processes that are in the kernel */
|
||||
hdrindex = 0; /* all use the first a.out header */
|
||||
} else {
|
||||
hdrindex = 1 + i-NR_TASKS; /* drivers, servers, INIT follow */
|
||||
hdrindex = 1 + i-NR_TASKS; /* servers, drivers, INIT */
|
||||
}
|
||||
|
||||
/* The bootstrap loader created an array of the a.out headers at
|
||||
* absolute address 'aout'. Get one element to e_hdr.
|
||||
*/
|
||||
phys_copy(aout + hdrindex * A_MINHDR, vir2phys(&e_hdr),
|
||||
(phys_bytes) A_MINHDR);
|
||||
(phys_bytes) A_MINHDR);
|
||||
/* Convert addresses to clicks and build process memory map */
|
||||
text_base = e_hdr.a_syms >> CLICK_SHIFT;
|
||||
text_clicks = (e_hdr.a_text + CLICK_SIZE-1) >> CLICK_SHIFT;
|
||||
|
@ -127,7 +127,7 @@ PUBLIC void main()
|
|||
/* Initialize the server stack pointer. Take it down one word
|
||||
* to give crtso.s something to use as "argc".
|
||||
*/
|
||||
if (i-NR_TASKS >= 0) {
|
||||
if (isusern(proc_nr(rp))) { /* user-space process? */
|
||||
rp->p_reg.sp = (rp->p_memmap[S].mem_vir +
|
||||
rp->p_memmap[S].mem_len) << CLICK_SHIFT;
|
||||
rp->p_reg.sp -= sizeof(reg_t);
|
||||
|
|
|
@ -50,8 +50,8 @@ struct priv {
|
|||
#define priv_id(rp) ((rp)->p_priv->s_id)
|
||||
#define priv(rp) ((rp)->p_priv)
|
||||
|
||||
#define id_to_nr(id) priv_addr(id)->s_proc_nr;
|
||||
#define nr_to_id(nr) priv(proc_addr(nr))->s_id;
|
||||
#define id_to_nr(id) priv_addr(id)->s_proc_nr
|
||||
#define nr_to_id(nr) priv(proc_addr(nr))->s_id
|
||||
|
||||
/* The system structures table and pointers to individual table slots. The
|
||||
* pointers allow faster access because now a process entry can be found by
|
||||
|
|
110
kernel/proc.c
110
kernel/proc.c
|
@ -130,47 +130,46 @@ message *m_ptr; /* pointer to message in the caller's space */
|
|||
if (! (isokprocn(src_dst) || src_dst == ANY || function == ECHO))
|
||||
return(EBADSRCDST);
|
||||
|
||||
#if DEAD_CODE /* temporarily disabled for testing ALERT */
|
||||
/* This check allows a message to be anywhere in data or stack or gap.
|
||||
* It will have to be made more elaborate later for machines which
|
||||
* don't have the gap mapped.
|
||||
/* If the call involves a message buffer, i.e., for SEND, RECEIVE, SENDREC,
|
||||
* or ECHO, check the message pointer. This check allows a message to be
|
||||
* anywhere in data or stack or gap. It will have to be made more elaborate
|
||||
* for machines which don't have the gap mapped.
|
||||
*/
|
||||
vb = (vir_bytes) m_ptr;
|
||||
vlo = vb >> CLICK_SHIFT; /* vir click for bottom of message */
|
||||
vhi = (vb + MESS_SIZE - 1) >> CLICK_SHIFT; /* vir click for top of msg */
|
||||
if (vlo < caller_ptr->p_memmap[D].mem_vir || vlo > vhi ||
|
||||
vhi >= caller_ptr->p_memmap[S].mem_vir + caller_ptr->p_memmap[S].mem_len)
|
||||
return(EFAULT);
|
||||
#endif
|
||||
if (function & SENDREC) {
|
||||
vb = (vir_bytes) m_ptr; /* virtual clicks */
|
||||
vlo = vb >> CLICK_SHIFT; /* bottom of message */
|
||||
vhi = (vb + MESS_SIZE - 1) >> CLICK_SHIFT; /* top of message */
|
||||
if (vlo < caller_ptr->p_memmap[D].mem_vir || vlo > vhi ||
|
||||
vhi >= caller_ptr->p_memmap[S].mem_vir +
|
||||
caller_ptr->p_memmap[S].mem_len) return(EFAULT);
|
||||
}
|
||||
|
||||
/* If the call is to send to a process, i.e., for SEND, SENDREC or NOTIFY,
|
||||
* verify that the caller is allowed to send to the given destination and
|
||||
* that the destination is still alive.
|
||||
*/
|
||||
if (function & SEND) {
|
||||
if (! get_sys_bit(priv(caller_ptr)->s_send_mask, nr_to_id(src_dst))) {
|
||||
kprintf("Warning, send_mask denied %d sending to %d\n",
|
||||
proc_nr(caller_ptr), src_dst);
|
||||
return(ECALLDENIED);
|
||||
}
|
||||
|
||||
if (isemptyn(src_dst)) return(EDEADDST); /* cannot send to the dead */
|
||||
}
|
||||
|
||||
/* Now check if the call is known and try to perform the request. The only
|
||||
* system calls that exist in MINIX are sending and receiving messages.
|
||||
* - SENDREC: combines SEND and RECEIVE in a single system call
|
||||
* - SEND: sender blocks until its message has been delivered
|
||||
* - RECEIVE: receiver blocks until an acceptable message has arrived
|
||||
* - NOTIFY: sender continues; either directly deliver the message or
|
||||
* queue the notification message until it can be delivered
|
||||
* - ECHO: the message directly will be echoed to the sender
|
||||
* - NOTIFY: nonblocking call; deliver notification or mark pending
|
||||
* - ECHO: nonblocking call; directly echo back the message
|
||||
*/
|
||||
switch(function) {
|
||||
case SENDREC: /* has FRESH_ANSWER flag */
|
||||
case SENDREC: /* has FRESH_ANSWER flag */
|
||||
/* fall through */
|
||||
case SEND:
|
||||
if (isemptyn(src_dst)) {
|
||||
result = EDEADDST; /* cannot send to the dead */
|
||||
break;
|
||||
}
|
||||
|
||||
#if DEAD_CODE /* to be replaced by better mechanism */
|
||||
mask_entry = isuserp(proc_addr(src_dst)) ? USER_PROC_NR : src_dst;
|
||||
if (! isallowed(caller_ptr->p_sendmask, mask_entry)) {
|
||||
kprintf("WARNING: sys_call denied %d ", caller_ptr->p_nr);
|
||||
kprintf("sending to %d\n", proc_addr(src_dst)->p_nr);
|
||||
result = ECALLDENIED; /* call denied by send mask */
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
result = mini_send(caller_ptr, src_dst, m_ptr, flags);
|
||||
if (function == SEND || result != OK) {
|
||||
break; /* done, or SEND failed */
|
||||
|
@ -191,18 +190,6 @@ message *m_ptr; /* pointer to message in the caller's space */
|
|||
default:
|
||||
result = EBADCALL; /* illegal system call */
|
||||
}
|
||||
|
||||
/* If the caller made a successfull, blocking system call it's priority may
|
||||
* be raised. The priority may have been lowered if a process consumed too
|
||||
* many full quantums in a row to prevent damage from infinite loops
|
||||
*/
|
||||
#if DEAD_CODE /* buggy ... do unready() first! */
|
||||
if ((caller_ptr->p_priority > caller_ptr->p_max_priority) &&
|
||||
! (flags & NON_BLOCKING) && (result == OK)) {
|
||||
caller_ptr->p_priority = caller_ptr->p_max_priority;
|
||||
caller_ptr->p_full_quantums = QUANTUMS(caller_ptr->p_priority);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Now, return the result of the system call to the caller. */
|
||||
return(result);
|
||||
|
@ -514,7 +501,7 @@ register struct proc *rp; /* this process is now runnable */
|
|||
|
||||
#if DEBUG_SCHED_CHECK
|
||||
check_runqueues("ready");
|
||||
if(rp->p_ready) kprintf("ready() already ready process\n", NO_NUM);
|
||||
if(rp->p_ready) kprintf("ready() already ready process\n");
|
||||
#endif
|
||||
|
||||
/* Processes, in principle, are added to the end of the queue. However,
|
||||
|
@ -562,7 +549,7 @@ register struct proc *rp; /* this process is no longer runnable */
|
|||
|
||||
#if DEBUG_SCHED_CHECK
|
||||
check_runqueues("unready");
|
||||
if (! rp->p_ready) kprintf("unready() already unready process\n", NO_NUM);
|
||||
if (! rp->p_ready) kprintf("unready() already unready process\n");
|
||||
#endif
|
||||
|
||||
/* Now make sure that the process is not in its ready queue. Remove the
|
||||
|
@ -582,6 +569,13 @@ register struct proc *rp; /* this process is no longer runnable */
|
|||
}
|
||||
prev_xp = *xpp; /* save previous in chain */
|
||||
}
|
||||
|
||||
/* The caller blocked. Reset the scheduling priority and quantums allowed.
|
||||
* The process' priority may have been lowered if a process consumed too
|
||||
* many full quantums in a row to prevent damage from infinite loops
|
||||
*/
|
||||
rp->p_priority = rp->p_max_priority;
|
||||
rp->p_full_quantums = QUANTUMS(rp->p_priority);
|
||||
|
||||
#if DEBUG_SCHED_CHECK
|
||||
rp->p_ready = 0;
|
||||
|
@ -598,19 +592,8 @@ struct proc *sched_ptr; /* quantum eating process */
|
|||
int q;
|
||||
|
||||
/* Check if this process is preemptible, otherwise leave it as is. */
|
||||
if (! (priv(sched_ptr)->s_flags & PREEMPTIBLE)) {
|
||||
#if DEAD_CODE
|
||||
kprintf("Warning, sched for nonpreemptible proc %d\n", sched_ptr->p_nr);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
if (! (priv(sched_ptr)->s_flags & PREEMPTIBLE)) return;
|
||||
|
||||
#if DEAD_CODE
|
||||
if (sched_ptr->p_nr == IS_PROC_NR) {
|
||||
kprintf("Scheduling IS: pri: %d, ", sched_ptr->p_priority);
|
||||
kprintf("qua %d", sched_ptr->p_full_quantums);
|
||||
}
|
||||
#endif
|
||||
/* Process exceeded the maximum number of full quantums it is allowed
|
||||
* to use in a row. Lower the process' priority, but make sure we don't
|
||||
* end up in the IDLE queue. This helps to limit the damage caused by
|
||||
|
@ -619,13 +602,10 @@ struct proc *sched_ptr; /* quantum eating process */
|
|||
*/
|
||||
if (-- sched_ptr->p_full_quantums <= 0) { /* exceeded threshold */
|
||||
if (sched_ptr->p_priority + 1 < IDLE_Q ) {
|
||||
q = sched_ptr->p_priority + 1; /* backup new priority */
|
||||
unready(sched_ptr); /* remove from queues */
|
||||
sched_ptr->p_priority ++; /* lower priority */
|
||||
sched_ptr->p_priority = q; /* lower priority */
|
||||
ready(sched_ptr); /* add to new queue */
|
||||
#if DEAD_CODE
|
||||
kprintf("Warning, proc %d got lower priority: ", sched_ptr->p_nr);
|
||||
kprintf("%d\n", sched_ptr->p_priority);
|
||||
#endif
|
||||
}
|
||||
sched_ptr->p_full_quantums = QUANTUMS(sched_ptr->p_priority);
|
||||
}
|
||||
|
@ -646,14 +626,6 @@ kprintf("%d\n", sched_ptr->p_priority);
|
|||
/* Give the expired process a new quantum and see who is next to run. */
|
||||
sched_ptr->p_sched_ticks = sched_ptr->p_quantum_size;
|
||||
pick_proc();
|
||||
|
||||
#if DEAD_CODE
|
||||
if (sched_ptr->p_nr == IS_PROC_NR) {
|
||||
kprintf("Next proc: %d, ", next_ptr->p_nr);
|
||||
kprintf("pri: %d, ", next_ptr->p_priority);
|
||||
kprintf("qua: %d\n", next_ptr->p_full_quantums);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ struct proc {
|
|||
#define IDLE_Q 15 /* lowest, only IDLE process goes here */
|
||||
|
||||
/* Each queue has a maximum number of full quantums associated with it. */
|
||||
#define QUANTUMS(q) (NR_SCHED_QUEUES - (q))
|
||||
#define QUANTUMS(q) (1 + (NR_SCHED_QUEUES - (q))/2)
|
||||
|
||||
/* Magic process table addresses. */
|
||||
#define BEG_PROC_ADDR (&proc[0])
|
||||
|
|
|
@ -40,7 +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 set_priv, (register struct proc *rc,int sys_proc_flag) );
|
||||
_PROTOTYPE( int get_priv, (register struct proc *rc, int proc_type) );
|
||||
_PROTOTYPE( phys_bytes numap_local, (int proc_nr, vir_bytes vir_addr,
|
||||
vir_bytes bytes) );
|
||||
_PROTOTYPE( void sys_task, (void) );
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
*
|
||||
* In addition to the main sys_task() entry point, which starts the main loop,
|
||||
* there are several other minor entry points:
|
||||
* set_priv: assign privilege structure to user or system process
|
||||
* get_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
|
||||
* umap_local: map virtual address in LOCAL_SEG to physical
|
||||
|
@ -164,9 +164,9 @@ PRIVATE void initialize(void)
|
|||
|
||||
|
||||
/*===========================================================================*
|
||||
* set_priv *
|
||||
* get_priv *
|
||||
*===========================================================================*/
|
||||
PUBLIC int set_priv(rc, proc_type)
|
||||
PUBLIC int get_priv(rc, proc_type)
|
||||
register struct proc *rc; /* new (child) process pointer */
|
||||
int proc_type; /* system or user process flag */
|
||||
{
|
||||
|
|
|
@ -27,6 +27,7 @@ register message *m_ptr; /* pointer to request message */
|
|||
#endif
|
||||
register struct proc *rpc; /* child process pointer */
|
||||
struct proc *rpp; /* parent process pointer */
|
||||
int i;
|
||||
|
||||
rpp = proc_addr(m_ptr->PR_PPROC_NR);
|
||||
rpc = proc_addr(m_ptr->PR_PROC_NR);
|
||||
|
@ -51,6 +52,16 @@ register message *m_ptr; /* pointer to request message */
|
|||
rpc->p_user_time = 0; /* set all the accounting times to 0 */
|
||||
rpc->p_sys_time = 0;
|
||||
|
||||
/* If this is a system process, make sure the child process gets its own
|
||||
* privilege structure for accounting.
|
||||
*/
|
||||
if (priv(rpc)->s_flags & SYS_PROC) {
|
||||
if (OK != (i=get_priv(rpc, SYS_PROC))) return(i); /* get structure */
|
||||
for (i=0; i< BITMAP_CHUNKS(NR_SYS_PROCS); i++) /* remove pending: */
|
||||
priv(rpc)->s_notify_pending.chunk[i] = 0; /* - notifications */
|
||||
priv(rpc)->s_int_pending = 0; /* - interrupts */
|
||||
sigemptyset(&priv(rpc)->s_sig_pending); /* - signals */
|
||||
}
|
||||
return(OK);
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ message *m_ptr; /* pointer to request message */
|
|||
register struct proc *rp;
|
||||
register struct priv *sp;
|
||||
int proc_nr;
|
||||
int i;
|
||||
|
||||
/* Extract message parameters. */
|
||||
proc_nr = m_ptr->CTL_PROC_NR;
|
||||
|
@ -32,10 +33,23 @@ message *m_ptr; /* pointer to request message */
|
|||
|
||||
/* Make sure this process has its own privileges structure. */
|
||||
if (! (priv(rp)->s_flags & SYS_PROC))
|
||||
set_priv(rp, SYS_PROC);
|
||||
get_priv(rp, SYS_PROC);
|
||||
|
||||
/* Now update the process' privileges as requested. */
|
||||
rp->p_priv->s_call_mask = SYSTEM_CALL_MASK;
|
||||
rp->p_priv->s_call_mask = FILLED_MASK;
|
||||
for (i=0; i<BITMAP_CHUNKS(NR_SYS_PROCS); i++) {
|
||||
rp->p_priv->s_send_mask.chunk[i] = FILLED_MASK;
|
||||
}
|
||||
unset_sys_bit(rp->p_priv->s_send_mask, USER_PRIV_ID);
|
||||
|
||||
/* All process that this process can send to must be able to reply.
|
||||
* Therefore, their send masks should be updated as well.
|
||||
*/
|
||||
for (i=0; i<NR_SYS_PROCS; i++) {
|
||||
if (get_sys_bit(rp->p_priv->s_send_mask, i)) {
|
||||
set_sys_bit(priv_addr(i)->s_send_mask, priv_id(rp));
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ register message *m_ptr;
|
|||
if (rp->p_memmap[T].mem_len != 0) {
|
||||
if ((src = umap_local(rp, T, tr_addr, TR_VLSIZE)) == 0) return(EIO);
|
||||
phys_copy(src, vir2phys(&tr_data), (phys_bytes) sizeof(long));
|
||||
m_ptr->CTL_DATA= tr_data;
|
||||
m_ptr->CTL_DATA = tr_data;
|
||||
break;
|
||||
}
|
||||
/* Text space is actually data space - fall through. */
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
#define CLOCK_S SMALL_STACK
|
||||
|
||||
/* Stack space for all the task stacks. Declared as (char *) to align it. */
|
||||
#define TOT_STACK_SPACE (IDLE_S+HARDWARE_S+CLOCK_S+SYSTEM_S)
|
||||
#define TOT_STACK_SPACE (IDLE_S + HARDWARE_S + CLOCK_S + SYSTEM_S)
|
||||
PUBLIC char *t_stack[TOT_STACK_SPACE / sizeof(char *)];
|
||||
|
||||
|
||||
|
@ -60,6 +60,7 @@ PUBLIC char *t_stack[TOT_STACK_SPACE / sizeof(char *)];
|
|||
* routine and stack size is also provided.
|
||||
*/
|
||||
#define USER_F (PREEMPTIBLE | BILLABLE | RDY_Q_HEAD)
|
||||
#define IDLE_F (BILLABLE | SYS_PROC)
|
||||
#define SYS_F (PREEMPTIBLE | SYS_PROC)
|
||||
#define TASK_F (SYS_PROC)
|
||||
|
||||
|
@ -68,37 +69,38 @@ PUBLIC char *t_stack[TOT_STACK_SPACE / sizeof(char *)];
|
|||
#define SYS_T 16 /* ticks */
|
||||
|
||||
PUBLIC struct system_image image[] = {
|
||||
{ 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" },
|
||||
{ IDLE, idle_task, IDLE_F, IDLE_T, IDLE_Q, IDLE_S, EMPTY_MASK, EMPTY_MASK, "IDLE" },
|
||||
{ CLOCK, clock_task, TASK_F, SYS_T, TASK_Q, CLOCK_S, FILLED_MASK, SYSTEM_SEND_MASK, "CLOCK" },
|
||||
{ SYSTEM, sys_task, TASK_F, SYS_T, TASK_Q, SYSTEM_S, FILLED_MASK, SYSTEM_SEND_MASK, "SYS" },
|
||||
{ HARDWARE, 0, TASK_F, SYS_T, TASK_Q, HARDWARE_S, EMPTY_MASK, SYSTEM_SEND_MASK, "KERNEL" },
|
||||
{ PM_PROC_NR, 0, SYS_F, SYS_T, 3, 0, FILLED_MASK, SERVER_SEND_MASK, "PM" },
|
||||
{ FS_PROC_NR, 0, SYS_F, SYS_T, 3, 0, FILLED_MASK, SERVER_SEND_MASK, "FS" },
|
||||
{ SM_PROC_NR, 0, SYS_F, SYS_T, 3, 0, FILLED_MASK, SYSTEM_SEND_MASK, "SM" },
|
||||
{ IS_PROC_NR, 0, SYS_F, SYS_T, 2, 0, FILLED_MASK, DRIVER_SEND_MASK, "IS" },
|
||||
{ TTY, 0, SYS_F, SYS_T, 1, 0, FILLED_MASK, SYSTEM_SEND_MASK, "TTY" },
|
||||
{ MEMORY, 0, SYS_F, SYS_T, 2, 0, FILLED_MASK, DRIVER_SEND_MASK, "MEMORY" },
|
||||
#if ENABLE_AT_WINI
|
||||
{ AT_WINI, 0, SYS_F, SYS_T, 2, 0, SYSTEM_CALL_MASK, 0, "AT_WINI" },
|
||||
{ AT_WINI, 0, SYS_F, SYS_T, 2, 0, FILLED_MASK, DRIVER_SEND_MASK, "AT_WINI" },
|
||||
#endif
|
||||
#if ENABLE_FLOPPY
|
||||
{ FLOPPY, 0, SYS_F, SYS_T, 2, 0, SYSTEM_CALL_MASK, 0, "FLOPPY" },
|
||||
{ FLOPPY, 0, SYS_F, SYS_T, 2, 0, FILLED_MASK, DRIVER_SEND_MASK, "FLOPPY" },
|
||||
#endif
|
||||
#if ENABLE_PRINTER
|
||||
{ PRINTER, 0, SYS_F, SYS_T, 3, 0, SYSTEM_CALL_MASK, 0, "PRINTER" },
|
||||
{ PRINTER, 0, SYS_F, SYS_T, 3, 0, FILLED_MASK, DRIVER_SEND_MASK, "PRINTER" },
|
||||
#endif
|
||||
#if ENABLE_RTL8139
|
||||
{ USR8139, 0, SYS_F, SYS_T, 2, 0, SYSTEM_CALL_MASK, 0, "RTL8139" },
|
||||
{ RTL8139, 0, SYS_F, SYS_T, 2, 0, FILLED_MASK, DRIVER_SEND_MASK, "RTL8139" },
|
||||
#endif
|
||||
#if ENABLE_FXP
|
||||
{ FXP, 0, SYS_F, SYS_T, 2, 0, SYSTEM_CALL_MASK, 0, "FXP" },
|
||||
{ FXP, 0, SYS_F, SYS_T, 2, 0, FILLED_MASK, DRIVER_SEND_MASK, "FXP" },
|
||||
#endif
|
||||
#if ENABLE_DPETH
|
||||
{ DPETH, 0, SYS_F, SYS_T, 2, 0, SYSTEM_CALL_MASK, 0, "DPETH" },
|
||||
{ DPETH, 0, SYS_F, SYS_T, 2, 0, FILLED_MASK, DRIVER_SEND_MASK, "DPETH" },
|
||||
#endif
|
||||
#if ENABLE_LOG
|
||||
{ LOG_PROC_NR, 0, SYS_F, SYS_T, 2, 0, SYSTEM_CALL_MASK, 0, "LOG" },
|
||||
{ LOG_PROC_NR, 0, SYS_F, SYS_T, 2, 0, FILLED_MASK, SYSTEM_SEND_MASK, "LOG" },
|
||||
#endif
|
||||
{ INIT_PROC_NR, 0, USER_F, USER_T, USER_Q, 0, USER_CALL_MASK, 0, "INIT" },
|
||||
{ INIT_PROC_NR, 0, USER_F, USER_T, USER_Q, 0, USER_CALL_MASK, USER_SEND_MASK, "INIT" },
|
||||
};
|
||||
|
||||
/* Verify the size of the system image table at compile time. If the number
|
||||
|
|
|
@ -18,7 +18,7 @@ struct system_image {
|
|||
int priority; /* scheduling priority */
|
||||
int stksize; /* stack size for tasks */
|
||||
char call_mask; /* allowed system calls */
|
||||
long send_mask; /* send mask protection */
|
||||
bitchunk_t send_mask; /* send mask protection */
|
||||
char proc_name[P_NAME_LEN]; /* name in process table */
|
||||
};
|
||||
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
* output driver when a new message is ready.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "kernel.h"
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
|
@ -58,6 +58,7 @@ int nr;
|
|||
PUBLIC void kprintf(const char *fmt, ...) /* format to be printed */
|
||||
{
|
||||
int c; /* next character in fmt */
|
||||
int d;
|
||||
unsigned long u; /* hold number argument */
|
||||
int base; /* base of number arg */
|
||||
int negative = 0; /* print minus sign */
|
||||
|
@ -79,8 +80,8 @@ PUBLIC void kprintf(const char *fmt, ...) /* format to be printed */
|
|||
* conversion after the switch statement.
|
||||
*/
|
||||
case 'd': /* output decimal */
|
||||
u = va_arg(argp, int);
|
||||
if (u < 0) { negative = 1; u = -u; }
|
||||
d = va_arg(argp, signed int);
|
||||
if (d < 0) { negative = 1; u = -d; } else { u = d; }
|
||||
base = 10;
|
||||
break;
|
||||
case 'u': /* output unsigned long */
|
||||
|
@ -116,6 +117,7 @@ PUBLIC void kprintf(const char *fmt, ...) /* format to be printed */
|
|||
/* This is where the actual output for format "%key" is done. */
|
||||
if (negative) kputc('-'); /* print sign if negative */
|
||||
while(*s != 0) { kputc(*s++); } /* print string/ number */
|
||||
s = NULL; /* reset for next round */
|
||||
}
|
||||
else {
|
||||
kputc(c); /* print and continue */
|
||||
|
|
Loading…
Reference in a new issue