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:
Jorrit Herder 2005-07-26 12:48:34 +00:00
parent 153fdabb26
commit 8866b4d0ef
15 changed files with 160 additions and 124 deletions

View file

@ -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

View file

@ -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);

View file

@ -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 */

View file

@ -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);

View file

@ -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

View file

@ -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
}

View file

@ -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])

View file

@ -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) );

View file

@ -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 */
{

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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. */

View file

@ -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

View file

@ -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 */
};

View file

@ -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 */