diff --git a/kernel/const.h b/kernel/const.h index 477491fca..9225de17f 100755 --- a/kernel/const.h +++ b/kernel/const.h @@ -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 diff --git a/kernel/exception.c b/kernel/exception.c index f822154e7..4ca1f06b8 100755 --- a/kernel/exception.c +++ b/kernel/exception.c @@ -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); diff --git a/kernel/ipc.h b/kernel/ipc.h index 1540e8c9b..5101507d6 100644 --- a/kernel/ipc.h +++ b/kernel/ipc.h @@ -1,6 +1,8 @@ #ifndef IPC_H #define IPC_H +#include + /* 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 */ diff --git a/kernel/main.c b/kernel/main.c index fe35ad6b0..054afc937 100755 --- a/kernel/main.c +++ b/kernel/main.c @@ -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); diff --git a/kernel/priv.h b/kernel/priv.h index ce66e41b8..26f05d880 100755 --- a/kernel/priv.h +++ b/kernel/priv.h @@ -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 diff --git a/kernel/proc.c b/kernel/proc.c index 98db457eb..e404a8c29 100755 --- a/kernel/proc.c +++ b/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 } diff --git a/kernel/proc.h b/kernel/proc.h index eb30a06ea..e40beb234 100755 --- a/kernel/proc.h +++ b/kernel/proc.h @@ -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]) diff --git a/kernel/proto.h b/kernel/proto.h index 6ead2fdd7..31b30497f 100755 --- a/kernel/proto.h +++ b/kernel/proto.h @@ -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) ); diff --git a/kernel/system.c b/kernel/system.c index 64237c301..78158f2f9 100755 --- a/kernel/system.c +++ b/kernel/system.c @@ -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 */ { diff --git a/kernel/system/do_fork.c b/kernel/system/do_fork.c index 0c77771dc..8ae1df01c 100644 --- a/kernel/system/do_fork.c +++ b/kernel/system/do_fork.c @@ -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); } diff --git a/kernel/system/do_privctl.c b/kernel/system/do_privctl.c index cad78ad3b..ed4835faa 100644 --- a/kernel/system/do_privctl.c +++ b/kernel/system/do_privctl.c @@ -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; ip_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; ip_priv->s_send_mask, i)) { + set_sys_bit(priv_addr(i)->s_send_mask, priv_id(rp)); + } + } return(OK); } diff --git a/kernel/system/do_trace.c b/kernel/system/do_trace.c index ebf215fe2..4f559f3b5 100644 --- a/kernel/system/do_trace.c +++ b/kernel/system/do_trace.c @@ -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. */ diff --git a/kernel/table.c b/kernel/table.c index 03b700f08..850dc230a 100755 --- a/kernel/table.c +++ b/kernel/table.c @@ -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 diff --git a/kernel/type.h b/kernel/type.h index 98c16a094..684703abc 100755 --- a/kernel/type.h +++ b/kernel/type.h @@ -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 */ }; diff --git a/kernel/utility.c b/kernel/utility.c index ae772784f..110842601 100755 --- a/kernel/utility.c +++ b/kernel/utility.c @@ -12,9 +12,9 @@ * output driver when a new message is ready. */ +#include #include "kernel.h" #include -#include #include #include #include @@ -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 */