Removed stop sequence when MINIX is shut down.
Disabled send mask checks --- to be replaced by proper mechanism.
Fixed bug relating to 'shutdown -x'.
Simplified clock accounting of realtime.
Updated Makefiles for mkdept script.
# Directories
u = /usr
i = $u/include
-s = $i/sys
-h = $i/minix
-b = $i/ibm
l = $u/lib
-n = $i/net
-g = $n/gen
+s = system
# Programs, flags, etc.
CC = exec cc
HEAD = mpx.o
OBJS = start.o protect.o klibc.o klib.o table.o main.o proc.o \
i8259.o exception.o system.o clock.o misc.o
-SYS = system/system.a
+SYS_OBJS = $s/proctl.o $s/copying.o $s/devio.o $s/sysctl.o $s/misc.o \
+ $s/sigctl.o $s/tracing.o $s/clock.o $s/irqctl.o $s/debugging.o
LIBS = -ltimers
# What to make.
-kernel build: $(HEAD) $(OBJS) $(SYS)
- $(LD) $(CFLAGS) $(LDFLAGS) -o kernel $(HEAD) $(OBJS) $(SYS) $(LIBS)
+kernel build: $(HEAD) $(OBJS) $(SYS_OBJS)
+ $(LD) $(CFLAGS) $(LDFLAGS) -o kernel $(HEAD) $(OBJS) $(SYS_OBJS) $(LIBS)
install -S 0 kernel
-$(SYS):
+$(SYS_OBJS):
cd system && $(MAKE)
all install:
cd system && $(MAKE) -$(MAKEFLAGS) $@
rm -f *.o *.bak kernel
-# Dependencies
-a = kernel.h const.h type.h proto.h glo.h \
- $h/config.h $h/const.h $h/type.h $h/ipc.h \
- $s/types.h \
- $i/string.h $i/limits.h $i/errno.h $i/timers.h \
- $b/portio.h $b/interrupt.h $b/bios.h $b/ports.h
-
-klibc.o: $a
-
-klib.o: $h/config.h $h/const.h const.h sconst.h protect.h
-klib.o: klib88.s klib386.s
-
-mpx.o: $h/config.h $h/const.h $h/com.h const.h protect.h sconst.h
-mpx.o: mpx88.s mpx386.s
-mpx.o: mpx88.s mpx386.s
-
-clock.o: $a
-clock.o: $i/signal.h
-clock.o: $h/callnr.h
-clock.o: $h/com.h
-clock.o: proc.h
-
-start.o: $a
-start.o: $i/stdlib.h
-start.o: protect.h
-
-exception.o: $a
-exception.o: $i/signal.h
-exception.o: $h/com.h
-exception.o: proc.h
-
-driver.o: $a $d
-driver.o: $h/ioctl.h
-driver.o: $s/ioc_disk.h
-
-drvlib.o: $a $d $(dl)
-
-i8259.o: $a
-
-main.o: $a
-main.o: $i/unistd.h
-main.o: $i/signal.h
-main.o: $i/a.out.h
-main.o: $h/callnr.h
-main.o: $h/com.h
-main.o: proc.h
-main.o: sendmask.h
-
-misc.o: $a
-misc.o: $i/stdlib.h
-misc.o: $h/com.h
-
-printer.o: $a
-printer.o: $h/callnr.h
-printer.o: $h/com.h
-printer.o: proc.h
-
-proc.o: $a
-proc.o: $h/callnr.h
-proc.o: $h/com.h
-proc.o: proc.h
-proc.o: ipc.h
-proc.o: sendmask.h
-
-protect.o: $a
-protect.o: $h/com.h
-protect.o: proc.h
-protect.o: protect.h
-
-system.o: $a
-system.o: $i/stdlib.h
-system.o: $i/signal.h
-system.o: $i/unistd.h
-system.o: $s/sigcontext.h
-system.o: $s/ptrace.h
-system.o: $h/ioctl.h
-system.o: $s/svrctl.h
-system.o: $h/callnr.h
-system.o: $h/com.h
-system.o: system.h
-system.o: proc.h
-system.o: protect.h
-system.o: sendmask.h
-
-table.o: $a
-table.o: $i/stdlib.h
-table.o: $i/termios.h
-table.o: $h/com.h
-table.o: proc.h
-table.o: sendmask.h
-table.o: $b/int86.h
+depend:
+ cd system && $(MAKE) -$(MAKEFLAGS) $@
+ /usr/bin/mkdep "$(CC) -E $(CPPFLAGS)" *.c system/*.c > .depend
-system/system.a: $a $h/devio.h $h/com.h
-system/system.a: proc.h protect.h system.h sendmask.h
-system/system.a: $s/ptrace.h $s/sigcontext.h
-system/system.a: $i/signal.h $i/unistd.h
-system/system.a: system/clock.c
-system/system.a: system/copying.c
-system/system.a: system/devio.c
-system/system.a: system/irqctl.c
-system/system.a: system/misc.c
-system/system.a: system/proctl.c
-system/system.a: system/sigctl.c
-system/system.a: system/sysctl.c
-system/system.a: system/tracing.c
-system/system.a: system/debugging.c
+# Include generated dependencies.
+include .depend
-#define NEW_TIME_COUNT 1
/* The file contais the clock task, which handles all time related functions.
* Important events that are handled by the CLOCK include alarm timers and
* (re)scheduling user processes.
/* Variables for and changed by the CLOCK's interrupt handler. */
PRIVATE irq_hook_t clock_hook;
-#if ! NEW_TIME_COUNT
-PRIVATE clock_t pending_ticks; /* ticks seen by low level only */
-#endif
PRIVATE int sched_ticks = SCHED_RATE; /* counter: when 0, call scheduler */
PRIVATE struct proc *prev_ptr; /* last user process run by clock */
/* Main loop of the clock task. Get work, process it, sometimes reply. */
while (TRUE) {
+
/* Go get a message. */
receive(ANY, &m);
-#if ! NEW_TIME_COUNT
- /* Transfer ticks seen by the low level handler. */
- lock(8, "realtime");
- realtime += pending_ticks;
- pending_ticks = 0;
- unlock(8);
-#endif
-
/* Handle the request. */
switch (m.m_type) {
case HARD_INT:
/* If a process has been running too long, pick another one. */
if (--sched_ticks <= 0) {
if (bill_ptr == prev_ptr)
- lock_sched(PPRI_USER); /* process has run too long */
+ lock_sched(USER_Q); /* process has run too long */
sched_ticks = SCHED_RATE; /* reset quantum */
prev_ptr = bill_ptr; /* new previous process */
}
* is changing them, provided they are always valid pointers,
* since at worst the previous process would be billed.
* next_timeout, realtime, sched_ticks, bill_ptr, prev_ptr
- * rdy_head[PPRI_USER]
+ * rdy_head[USER_Q]
* These are tested to decide whether to call notify(). It
* does not matter if the test is sometimes (rarely) backwards
* due to a race, since this will only delay the high-level
* The variables which are changed require more care:
* rp->p_user_time, rp->p_sys_time:
* These are protected by explicit locks in system.c.
-#if ! NEW_TIME_COUNT
- * pending_ticks:
- * This is protected by explicit locks in clock.c. Don't
- * update realtime directly, since there are too many
- * references to it to guard conveniently.
-#endif
* lost_ticks:
* Clock ticks counted outside the clock task.
* sched_ticks, prev_ptr:
*/
register unsigned ticks;
message m;
-#if ! NEW_TIME_COUNT
- clock_t now;
-#endif
/* Acknowledge the PS/2 clock interrupt. */
if (machine.ps_mca) outb(PORT_B, inb(PORT_B) | CLOCK_ACK_BIT);
* process is running, charge the billable process for system time as well.
* Thus the unbillable process' user time is the billable user's system time.
*/
-#if NEW_TIME_COUNT
ticks = lost_ticks + 1;
lost_ticks = 0;
realtime += ticks;
-#else
- ticks = lost_ticks + 1;
- lost_ticks = 0;
- pending_ticks += ticks;
- now = realtime + pending_ticks;
-#endif
/* Update administration. */
proc_ptr->p_user_time += ticks;
/* Check if do_clocktick() must be called. Done for alarms and scheduling.
* If bill_ptr == prev_ptr, there are no ready users so don't need sched().
*/
-#if NEW_TIME_COUNT
if (next_timeout <= realtime || (sched_ticks == 1 && bill_ptr == prev_ptr
-#else
- if (next_timeout <= now || (sched_ticks == 1 && bill_ptr == prev_ptr
-#endif
- && rdy_head[PPRI_USER] != NIL_PROC))
+ && rdy_head[USER_Q] != NIL_PROC))
{
m.NOTIFY_TYPE = HARD_INT;
lock_notify(CLOCK, &m);
/* Get and return the current clock uptime in ticks.
* Be careful about pending_ticks.
*/
-#if NEW_TIME_COUNT
return(realtime);
-#else
- clock_t uptime;
-
- lock(9, "get_uptime");
- uptime = realtime + pending_ticks;
- unlock(9);
- return(uptime);
-#endif
}
return;
}
- if (k_reenter == 0 && ! istaskp(saved_proc)) {
+ if (k_reenter == 0 && ! iskernelp(saved_proc)) {
cause_sig(proc_nr(saved_proc), ep->signum);
return;
}
/* Variables relating to shutting down MINIX. */
EXTERN char kernel_exception; /* TRUE after system exceptions */
-EXTERN char shutting_down; /* TRUE if shutting down */
-EXTERN struct proc *shutdown_process; /* process awaiting shutdown of */
-EXTERN timer_t shutdown_timer; /* timer for watchdog function */
/* Kernel information structures. This groups vital kernel information. */
EXTERN phys_bytes aout; /* address of a.out headers */
/* Process scheduling information and the kernel reentry count. */
EXTERN struct proc *proc_ptr; /* pointer to currently running process */
-EXTERN struct proc *next_ptr; /* pointer to next process to run */
+EXTERN struct proc *next_ptr; /* next process to run after restart() */
+EXTERN struct proc *bill_ptr; /* process to bill for clock ticks */
EXTERN char k_reenter; /* kernel reentry count (entry count less 1) */
EXTERN unsigned lost_ticks; /* clock ticks counted outside clock task */
* The routine main() initializes the system and starts the ball rolling by
* setting up the process table, interrupt vectors, and scheduling each task
* to run to initialize itself.
- * The routine prepare_shutdown() tries to cleanly shuts down MINIX by running
- * the stop_sequence() to notify all system services and allowing them some
- * time to finalize. In case of an exception(), the stop sequence is skipped.
+ * The routine shutdown() does the opposite and brings down MINIX.
*
* The entries into this file are:
* main: MINIX main program
* prepare_shutdown: prepare to take MINIX down
- * stop_sequence: take down all system services
*
* Changes:
* Nov 24, 2004 simplified main() with system image (Jorrit N. Herder)
- * Oct 21, 2004 moved copyright to announce() (Jorrit N. Herder)
- * Sep 04, 2004 created stop_sequence() to cleanup (Jorrit N. Herder)
- * Aug 20, 2004 split wreboot() and shutdown() (Jorrit N. Herder)
- * Jun 15, 2004 moved wreboot() to this file (Jorrit N. Herder)
+ * Aug 20, 2004 new prepare_shutdown() and shutdown() (Jorrit N. Herder)
*/
#include "kernel.h"
#include <signal.h>
FORWARD _PROTOTYPE( void announce, (void));
FORWARD _PROTOTYPE( void shutdown, (timer_t *tp));
-#define STOP_TICKS (5*HZ) /* time allowed to stop */
/*===========================================================================*
* main *
/* Initialize the interrupt controller. */
intr_init(1);
- /* Clear the process table. Anounce each slot as empty and
- * set up mappings for proc_addr() and proc_nr() macros.
+ /* Clear the process table. Anounce each slot as empty and set up mappings
+ * for proc_addr() and proc_nr() macros.
*/
for (rp = BEG_PROC_ADDR, i = -NR_TASKS; rp < END_PROC_ADDR; ++rp, ++i) {
- rp->p_type = P_NONE; /* isemptyp() tests on this */
+ rp->p_flags = SLOT_FREE; /* initialize free slot */
rp->p_nr = i; /* proc number from ptr */
(pproc_addr + NR_TASKS)[i] = rp; /* proc ptr from number */
}
rp = proc_addr(ttp->proc_nr); /* t's process slot */
kstrncpy(rp->p_name, ttp->proc_name, P_NAME_LEN); /* set name */
rp->p_name[P_NAME_LEN-1] = '\0'; /* just for safety */
- rp->p_type = ttp->type; /* type of process */
rp->p_priority = ttp->priority; /* scheduling priority */
rp->p_call_mask = ttp->call_mask; /* allowed system calls */
rp->p_sendmask = ttp->sendmask; /* sendmask protection */
* access I/O; this is not allowed to less-privileged processes
*/
rp->p_reg.pc = (reg_t) ttp->initial_pc;
- rp->p_reg.psw = (isidlep(rp)||istaskp(rp)) ? INIT_TASK_PSW : INIT_PSW;
+ rp->p_reg.psw = (iskernelp(rp)) ? INIT_TASK_PSW : INIT_PSW;
/* Initialize the server stack pointer. Take it down one word
* to give crtso.s something to use as "argc".
kprintf("Executing in %s mode\n\n",
machine.protected ? karg("32-bit protected") : karg("real"));
#endif
-
- /* Check if boot device was loaded with the kernel. */
- if (kinfo.bootdev_base > 0)
- kprintf("Image of /dev/boot loaded. Size: %u KB.\n", kinfo.bootdev_size);
-
}
* prepare_shutdown *
*==========================================================================*/
PUBLIC void prepare_shutdown(how)
-int how; /* 0 = halt, 1 = reboot, 2 = panic!, ... */
+int how; /* reason to shut down */
{
/* 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
- * stop_sequence() is started.
*/
+ static timer_t shutdown_timer; /* timer for watchdog function */
message m;
- if (shutting_down)
- return;
/* Show debugging dumps on panics. Make sure that the TTY task is still
* available to handle them. This is done with help of a non-blocking send.
m.NOTIFY_TYPE = HARD_STOP;
lock_notify(TTY, &m);
- /* Run the stop sequence. The timer argument passes the shutdown status.
- * The stop sequence is skipped for fatal CPU exceptions.
+ /* Allow processes to be scheduled to clean up, unless a CPU exception
+ * occurred. This is done by setting a timer. The timer argument passes
+ * the shutdown status.
*/
- shutting_down = TRUE; /* flag for sys_exit() */
tmr_arg(&shutdown_timer)->ta_int = how; /* pass how in timer */
if (kernel_exception) { /* set in exception() */
kprintf("\nAn exception occured; skipping stop sequence.\n", NO_NUM);
shutdown(&shutdown_timer); /* TTY isn't scheduled */
} else {
kprintf("\nNotifying system services about MINIX shutdown.\n", NO_NUM);
- set_timer(&shutdown_timer, get_uptime(), stop_sequence);
+ set_timer(&shutdown_timer, get_uptime(), shutdown);
}
}
-/*==========================================================================*
- * stop_sequence *
- *==========================================================================*/
-PUBLIC void stop_sequence(tp)
-timer_t *tp;
-{
-/* Try to cleanly stop all system services before shutting down. For each
- * process type, all processes are notified and given STOP_TICKS to cleanly
- * shutdown. The notification order is servers, drivers, tasks. The variable
- * 'shutdown_process' is set globally to indicate the process next to stop
- * so that the stop sequence can directly continue if it has exited. Only if
- * stop sequence has finished, MINIX is brought down.
- */
- static int level = P_SERVER; /* start at the highest level */
- static struct proc *p = NIL_PROC; /* next process to stop */
- static message m;
-
- /* See if the last process' shutdown was successful. Else, force exit. */
- if (p != NIL_PROC) {
- kprintf("[%s]\n", isalivep(p) ? karg("FAILED") : karg("OK"));
- if (isalivep(p))
- clear_proc(p->p_nr); /* now force process to exit */
- }
-
- /* Find the next process that must be stopped. Continue where last search
- * ended or start at begin. Possibly go to next level while searching. If
- * the last level is completely searched, shutdown MINIX. Processes are
- * stopped in the order of dependencies, that is, from the highest level to
- * the lowest level so that, for example, the file system can still rely on
- * device drivers to cleanly shutdown.
- */
- if (p == NIL_PROC) p = BEG_PROC_ADDR;
- while (TRUE) {
- if (isalivep(p) && p->p_type == level) { /* found a process */
- kprintf("- Stopping %s ... ", karg(p->p_name));
- shutdown_process = p; /* directly continue if exited */
- m.NOTIFY_TYPE = HARD_STOP;
- m.NOTIFY_ARG = tmr_arg(tp)->ta_int; /* how */
- lock_notify(proc_nr(p), &m);
- set_timer(tp, get_uptime()+STOP_TICKS, stop_sequence);
- return; /* allow the process to shut down */
- }
- p++; /* proceed to next process */
- if (p >= END_PROC_ADDR) { /* proceed to next level */
- p = BEG_PROC_ADDR;
- level = level - 1;
- if (level == P_TASK) { /* done; tasks must remain alive */
- shutdown(tp);
- /* no return */
- return;
- }
- }
- }
-}
/*==========================================================================*
* shutdown *
timer_t *tp;
{
/* This function is called from prepare_shutdown or stop_sequence to bring
- * down MINIX. How to shutdown is in the argument: RBT_REBOOT, RBT_HALT,
- * RBT_RESET.
+ * down MINIX. How to shutdown is in the argument: RBT_HALT (return to the
+ * monitor), RBT_MONITOR (execute given code), RBT_RESET (hard reset).
*/
- static u16_t magic = STOP_MEM_CHECK;
int how = tmr_arg(tp)->ta_int;
+ u16_t magic;
/* Now mask all interrupts, including the clock, and stop the clock. */
outb(INT_CTLMASK, ~0);
outb(INT_CTLMASK, 0);
outb(INT2_CTLMASK, 0);
- /* Return to the boot monitor. Set the program for the boot monitor.
- * For RBT_MONITOR, the MM has provided the program.
- */
- if (how == RBT_REBOOT)
- phys_copy(vir2phys("delay;boot"), kinfo.params_base, 11);
- else
- phys_copy(vir2phys("delay"), kinfo.params_base, 6);
+ /* Return to the boot monitor. Set the program if not already done. */
+ if (how != RBT_MONITOR) phys_copy(vir2phys(""), kinfo.params_base, 1);
level0(monitor);
}
- /* Stop BIOS memory test. */
- phys_copy(vir2phys(&magic), SOFT_RESET_FLAG_ADDR, SOFT_RESET_FLAG_SIZE);
-
/* Reset the system by jumping to the reset address (real mode), or by
- * forcing a processor shutdown (protected mode).
+ * forcing a processor shutdown (protected mode). First stop the BIOS
+ * memory test by setting a soft reset flag.
*/
+ magic = STOP_MEM_CHECK;
+ phys_copy(vir2phys(&magic), SOFT_RESET_FLAG_ADDR, SOFT_RESET_FLAG_SIZE);
level0(reset);
}
case SENDREC: /* has FRESH_ANSWER flag */
/* fall through */
case SEND:
- if (! isalive(src_dst)) {
+ if (isemptyp(proc_addr(src_dst))) {
result = EDEADDST; /* cannot send to the dead */
break;
}
- mask_entry = isuser(src_dst) ? USER_PROC_NR : src_dst;
+
+#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) {
/* Destination is not ready. Add the notification to the pending queue.
* Get pointer to notification message. Don't copy if already in kernel.
*/
- if (! istaskp(caller_ptr)) {
+ if (! iskernelp(caller_ptr)) {
CopyMess(proc_nr(caller_ptr), caller_ptr, m_ptr,
proc_addr(HARDWARE), &ntf_mess);
m_ptr = &ntf_mess;
rp->p_ready = 0;
#endif
- /* Side-effect for tasks: check if the task's stack still is ok? */
- if (istaskp(rp)) {
+ /* Side-effect for kernel: check if the task's stack still is ok? */
+ if (iskernelp(rp)) {
if (*rp->p_stguard != STACK_GUARD)
panic("stack overrun by task", proc_nr(rp));
}
#ifndef PROC_H
#define PROC_H
-/* Here is the declaration of the process table. It contains the process'
- * registers, memory map, accounting, and message send/receive information.
+/* Here is the declaration of the process table. It contains all process
+ * data, including registers, flags, scheduling priority, memory map,
+ * accounting, message passing (IPC) information, and so on.
+ *
* Many assembly code routines reference fields in it. The offsets to these
* fields are defined in the assembler include file sconst.h. When changing
- * 'proc', be sure to change sconst.h to match.
- *
- * Changes:
- * May 24, 2005 new field for pending notifications (Jorrit N. Herder)
- * Nov 10, 2004 separated process types/ priorities (Jorrit N. Herder)
- * Sep 24, 2004 one timer per type of alarm (Jorrit N. Herder)
- * May 01, 2004 new p_sendmask to protect syscalls (Jorrit N. Herder)
+ * struct proc, be sure to change sconst.h to match.
*/
#include <minix/com.h>
#include "protect.h"
#if (CHIP == INTEL)
reg_t p_ldt_sel; /* selector in gdt with ldt base and limit */
struct segdesc_s p_ldt[2+NR_REMOTE_SEGS]; /* CS, DS and remote segments */
-#endif /* (CHIP == INTEL) */
+#endif
#if (CHIP == M68000)
/* M68000 specific registers and FPU details go here. */
-#endif /* (CHIP == M68000) */
+#endif
reg_t *p_stguard; /* stack guard word */
-
proc_nr_t p_nr; /* number of this process (for fast access) */
+
struct mem_map p_memmap[NR_LOCAL_SEGS]; /* local memory map (T, D, S) */
struct far_mem p_farmem[NR_REMOTE_SEGS]; /* remote memory map */
char p_flags; /* SENDING, RECEIVING, etc. */
- char p_type; /* task, system, driver, server, user, idle */
- char p_priority; /* scheduling priority */
- char p_call_mask; /* bit map with allowed system call traps */
+ char p_priority; /* current scheduling priority */
+ char p_max_priority; /* maximum (default) scheduling priority */
+ char p_used_quantums; /* number of full quantums used in a row */
+ char p_allowed_quantums; /* maximum quantums allowed in a row */
+ char p_call_mask; /* bit map with allowed system call traps */
send_mask_t p_sendmask; /* mask indicating to whom proc may send */
clock_t p_user_time; /* user time in ticks */
timer_t p_alarm_timer; /* timer shared by different alarm types */
sigset_t p_pending; /* bit map for pending kernel signals */
- unsigned p_pendcount; /* count of pending and unfinished signals */
char p_name[P_NAME_LEN]; /* name of the process, including \0 */
/* Guard word for task stacks. */
#define STACK_GUARD ((reg_t) (sizeof(reg_t) == 2 ? 0xBEEF : 0xDEADBEEF))
-/* Bits for p_flags in proc[]. A process is runnable iff p_flags == 0. */
-#define NO_MAP 0x01 /* keeps unmapped forked child from running */
-#define SENDING 0x02 /* process blocked trying to SEND */
-#define RECEIVING 0x04 /* process blocked trying to RECEIVE */
-#define PENDING 0x10 /* set when inform() of signal pending */
-#define SIG_PENDING 0x20 /* keeps to-be-signalled proc from running */
+/* Bits for the process flags. A process is runnable iff p_flags == 0. */
+#define SLOT_FREE 0x01 /* process slot is free */
+#define NO_MAP 0x02 /* keeps unmapped forked child from running */
+#define SENDING 0x04 /* process blocked trying to SEND */
+#define RECEIVING 0x08 /* process blocked trying to RECEIVE */
+#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 */
-/* Values for p_type. Non-negative values represent active process types.
- * Process types are important to model inter-process relationships. When
- * MINIX is shutdown, all system services are notified in order of possible
- * dependencies, so that, e.g., the FS can rely on drivers to synchronize.
- */
-#define P_RESERVED -2 /* slot is not in use, but reserved */
-#define P_NONE -1 /* slot is not in use, and free */
-#define P_TASK 0 /* kernel process */
-#define P_SYSTEM 1 /* low-level system service */
-#define P_DRIVER 2 /* device driver */
-#define P_SERVER 3 /* system service outside the kernel */
-#define P_USER 4 /* user process */
-#define P_IDLE 5 /* idle process */
-
-/* Scheduling priorities for p_priority. Values must start at zero and
- * increment. Priorities of system services can be set in the task table.
- * Task, user, and idle priorities are fixed; the rest can be selected.
+
+/* Scheduling priorities for p_priority. Values must start at zero (highest
+ * priority) and increment. Priorities of the processes in the boot image can
+ * be set in table.c.
*/
-#define PPRI_TASK 0 /* reserved for kernel tasks */
-#define PPRI_HIGHER 1
-#define PPRI_HIGH 2
-#define PPRI_NORMAL 3
-#define PPRI_LOW 4
-#define PPRI_LOWER 5
-#define PPRI_USER 6 /* reserved for user processes */
-#define PPRI_IDLE 7 /* only IDLE process goes here */
+#define NR_SCHED_QUEUES 8 /* MUST equal minimum priority + 1 */
+#define TASK_Q 0 /* highest, reserved for kernel tasks */
+#define USER_Q 4 /* default priority for user processes */
+#define IDLE_Q 7 /* lowest, only IDLE process goes here */
-#define NR_SCHED_QUEUES 8 /* MUST equal minimum priority + 1 */
/* Magic process table addresses. */
#define BEG_PROC_ADDR (&proc[0])
#define proc_nr(p) ((p)->p_nr)
#define iskerneltask(n) ((n) == CLOCK || (n) == SYSTASK)
-#define isidlehardware(n) ((n) == IDLE || (n) == HARDWARE)
#define isokprocn(n) ((unsigned) ((n) + NR_TASKS) < NR_PROCS + NR_TASKS)
#define isokprocp(p) ((p) >= BEG_PROC_ADDR && (p) < END_PROC_ADDR)
-#define isalive(n) (proc_addr(n)->p_type > P_NONE)
-#define isalivep(p) ((p)->p_type > P_NONE)
-#define isemptyp(p) ((p)->p_type == P_NONE)
-#define istaskp(p) ((p)->p_type == P_TASK)
-#define isdriverp(p) ((p)->p_type == P_DRIVER)
-#define isserverp(p) ((p)->p_type == P_SERVER)
-#define isuserp(p) ((p)->p_type == P_USER)
-#define isidlep(p) ((p)->p_type == P_IDLE)
-#define isuser(n) (proc_addr(n)->p_type == P_USER)
+#define iskernelp(p) ((p)->p_nr < 0)
+#define isuserp(p) ((p)->p_nr >= 0)
+#define isidlep(p) ((p)->p_nr == IDLE)
+#define isemptyp(p) ((p)->p_flags == SLOT_FREE)
/* The process table and pointers to process table slots. The pointers allow
* faster access because now a process entry can be found by indexing the
*/
EXTERN struct proc proc[NR_TASKS + NR_PROCS]; /* process table */
EXTERN struct proc *pproc_addr[NR_TASKS + NR_PROCS];
-EXTERN struct proc *bill_ptr; /* ptr to process to bill for clock ticks */
EXTERN struct proc *rdy_head[NR_SCHED_QUEUES]; /* ptrs to ready list headers */
EXTERN struct proc *rdy_tail[NR_SCHED_QUEUES]; /* ptrs to ready list tails */
code_bytes = data_bytes; /* common I&D, poor protect */
else
code_bytes = (phys_bytes) rp->p_memmap[T].mem_len << CLICK_SHIFT;
- privilege = (isidlep(rp) || istaskp(rp)) ?
- TASK_PRIVILEGE : USER_PRIVILEGE;
+ privilege = (iskernelp(rp)) ? TASK_PRIVILEGE : USER_PRIVILEGE;
init_codeseg(&rp->p_ldt[CS_LDT_INDEX],
(phys_bytes) rp->p_memmap[T].mem_phys << CLICK_SHIFT,
code_bytes, privilege);
* Note the one always must start with a default mask like allow_all_mask.
* From that point, one can, for example, deny several processes.
*/
-#define allow_all_mask ALLOW_ALL_MASK
-#define deny_all_mask DENY_ALL_MASK
#define allow(enabled,n) | (enabled << ((n) + NR_TASKS))
#define deny(enabled,n) & ~(enabled << ((n) + NR_TASKS))
#define send_mask_allow(mask,n) ((mask) |= (1 << ((n) + NR_TASKS)))
/* Check if the bit for the given process number is set. */
#define isallowed(mask,n) ((mask) & (BIT_0 << ((n) + NR_TASKS)))
-
-/* The masks below match the processes (and order) in src/kernel/table.c.
- * Note that the masks are made effective the inclusion in the task table
- * which is used to set up the process table on start up.
- */
-
-#define TTY_SENDMASK \
- allow_all_mask
-
-#define DP8390_SENDMASK \
- allow_all_mask
-
-#define RTL8139_SENDMASK \
- allow_all_mask
-
-#define IDLE_SENDMASK \
- deny_all_mask
-
-/* The tasktab in src/kernel/table.c supports up to 4 controllers
- * it is possible to define separate masks for them here, but then
- * a small update in table.c is required to make them effective
- */
-#define CTRLR_SENDMASK \
- allow_all_mask
-
-#define SB16DSP_SENDMASK \
- allow_all_mask
-
-#define SB16MIX_SENDMASK \
- allow_all_mask
-
-#define FLOPPY_SENDMASK \
- allow_all_mask
-
-#define CLOCK_SENDMASK \
- allow_all_mask
-
-#define SYSTEM_SENDMASK \
- allow_all_mask
-
-#define HARDWARE_SENDMASK \
- allow_all_mask \
- deny(1, USER_PROC_NR)
-
-#define PM_SENDMASK \
- deny_all_mask \
- allow(1, IS_PROC_NR) /* output diagnostics */ \
- allow(1, SYSTASK) \
- allow(1, TTY) \
- allow(1, MEMORY) \
- allow(1, CLOCK) \
- allow(1, INIT_PROC_NR) \
- allow(1, FS_PROC_NR) \
- allow(1, USR8139) \
- allow(1, USER_PROC_NR) /* reply to system calls */
-
-#define AT_SENDMASK \
- allow_all_mask
-
-#define FS_SENDMASK \
- allow_all_mask
-#if 0
- deny_all_mask \
- allow(1, IS_PROC_NR) /* output diagnostics */ \
- allow(1, SYSTASK) /* need system functionality */ \
- allow(1, CLOCK) /* need clock functionality */ \
- allow(1, IS_PROC_NR) /* output diagnostics */ \
- allow(1, TTY) /* a.o. observe function keys */ \
- allow(1, FLOPPY) \
- allow(ENABLE_SB16, SB16DSP ) \
- allow(ENABLE_SB16, SB16MIX ) \
- allow(ENABLE_PRINTER, PRINTER ) \
- allow(1, MEMORY ) \
- allow((NR_CTRLRS >= 1), CTRLR(0)) \
- allow((NR_CTRLRS >= 2), CTRLR(1)) \
- allow((NR_CTRLRS >= 3), CTRLR(2)) \
- allow((NR_CTRLRS >= 4), CTRLR(3)) \
- allow(1, INIT_PROC_NR) \
- allow(1, PM_PROC_NR) /* cooperates with process manager */ \
- allow(1, USER_PROC_NR) /* reply to system calls */
-#endif
-
-#define IS_SENDMASK \
- allow_all_mask /* IS handles all diagnostic messages */
-#if 0
- deny_all_mask \
- allow(1, CLOCK) /* clock delays and flag alarm needed */ \
- allow(1, FS_PROC_NR) /* open /dev/mem to read CMOS clock */ \
- allow(1, SYSTASK) /* copy tables from kernel space */ \
- allow(1, TTY) /* request function key notifications */ \
- allow(1, USER_PROC_NR) /* reply to system calls */
-#endif
-
-#define MEM_SENDMASK \
- deny_all_mask \
- allow(1, IS_PROC_NR) /* output diagnostics */ \
- allow(1, SYSTASK) /* system functionality needed */ \
- allow(1, CLOCK) /* check clock alarms */ \
- allow(1, TTY) /* output diagnostics */ \
- allow(1, PM_PROC_NR) /* PM alloc mem */ \
- allow(1, FS_PROC_NR) /* FS is interface to the driver */
-
-#define PRN_SENDMASK \
- deny_all_mask \
- allow(1, IS_PROC_NR) /* output diagnostics */ \
- allow(1, SYSTASK) /* device port I/O needed */ \
- allow(1, TTY) /* output diagnostics */ \
- allow(1, CLOCK) /* need small delays */ \
- allow(1, FS_PROC_NR) /* FS is interface to the driver */
-
-#define FXP_SENDMASK \
- allow_all_mask
-
-#define INIT_SENDMASK \
- deny_all_mask \
- allow(1, FS_PROC_NR) /* init makes system calls to FS and MM */ \
- allow(1, PM_PROC_NR)
-
#define USER_PROC_SENDMASK \
- deny_all_mask \
- allow(1, FS_PROC_NR) /* users can only make system calls */ \
- allow(1, PM_PROC_NR) \
- allow(1, IS_PROC_NR) \
- allow(ENABLE_TASKSERVER, TS_PROC_NR)
-
+ DENY_ALL_MASK allow(1, PM_PROC_NR) allow(1, FS_PROC_NR)
#endif /* SENDMASK_H */
/* Initialize protected mode descriptors. */
prot_init();
- /* Copy the boot parameters to kernel memory. */
+ /* Copy the boot parameters to the local buffer. */
kinfo.params_base = seg2phys(mds) + parmoff;
kinfo.params_size = MIN(parmsize,sizeof(params)-2);
phys_copy(kinfo.params_base, vir2phys(params), kinfo.params_size);
#define map(call_nr, handler) \
{extern int dummy[NR_SYS_CALLS > (unsigned) (call_nr) ? 1 : -1];} \
- call_vec[(call_nr)] = (handler)
+ call_vec[(call_nr)] = (handler)
FORWARD _PROTOTYPE( void initialize, (void));
{
/* Main entry point of sys_task. Get the message and dispatch on type. */
static message m;
- register int result, debug;
+ register int result;
/* Initialize the system task. */
initialize();
* is known to be blocked waiting for a message.
*/
if (result != EDONTREPLY) {
- debug = m.m_type;
m.m_type = result; /* report status of call */
if (OK != lock_send(m.m_source, &m)) {
- kprintf("Warning, SYSTASK couldn't reply to request %d", debug);
- kprintf(" from %d\n", m.m_source);
+ kprintf("Warning, SYSTASK couldn't reply to request from %d\n",
+ m.m_source);
}
}
}
map(SYS_SEGCTL, do_segctl); /* add segment and get selector */
map(SYS_IOPENABLE, do_iopenable); /* enable CPU I/O protection bits */
map(SYS_SVRCTL, do_svrctl); /* kernel control functions */
- map(SYS_EXIT, do_exit); /* exit a system process*/
/* Copying. */
map(SYS_UMAP, do_umap); /* map virtual to physical address */
int proc_nr; /* slot of process to clean up */
{
register struct proc *rp, *rc;
-#if DEAD_CODE
- struct proc *np, *xp;
-#else
register struct proc **xpp; /* iterate over caller queue */
-#endif
int i;
/* Get a pointer to the process that exited. */
/* 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;
-#if DEAD_CODE
- if (rp->p_caller_q == rc) {
- /* Exiting process is on front of this queue. */
- rp->p_caller_q = rc->p_q_link;
- break;
- } else {
- /* See if exiting process is in middle of queue. */
- np = rp->p_caller_q;
- while ( ( xp = np->p_q_link) != NIL_PROC) {
- if (xp == rc) {
- np->p_q_link = xp->p_q_link;
- break;
- } else {
- np = xp;
- }
- }
- }
-#else
/* Make sure that the exiting process is not on the queue. */
xpp = &rp->p_caller_q;
while (*xpp != NIL_PROC) { /* check entire queue */
}
xpp = &(*xpp)->p_q_link; /* proceed to next queued */
}
-#endif
}
}
/* Now clean up the process table entry. Reset to defaults. */
kstrncpy(rc->p_name, "<none>", P_NAME_LEN); /* unset name */
sigemptyset(&rc->p_pending); /* remove pending signals */
- rc->p_pendcount = 0; /* all signals are gone */
- rc->p_flags = 0; /* remove all flags */
- rc->p_type = P_NONE; /* announce slot empty */
+ rc->p_flags = SLOT_FREE; /* announce slot empty */
rc->p_sendmask = DENY_ALL_MASK; /* set most restrictive mask */
#if (CHIP == M68000)
* Signals are handled by sending a message to PM. This function handles the
* signals and makes sure the PM gets them by sending a notification. The
* process being signaled is blocked while PM has not finished all signals
- * for it. These signals are counted in p_pendcount, and the SIG_PENDING
- * flag is kept nonzero while there are some. It is not sufficient to ready
- * the process when PM is informed, because PM can block waiting for FS to
- * do a core dump.
+ * for it.
+ * It is not sufficient to ready the process when PM is informed, because
+ * PM can block waiting for FS to do a core dump.
*/
register struct proc *rp;
message m;
+ /* Check if the signal is already pending. Process it otherwise. */
rp = proc_addr(proc_nr);
- if (sigismember(&rp->p_pending, sig_nr))
- return; /* this signal already pending */
- sigaddset(&rp->p_pending, sig_nr);
- ++rp->p_pendcount; /* count new signal pending */
- if (rp->p_flags & PENDING)
- return; /* another signal already pending */
- if (rp->p_flags == 0) lock_unready(rp);
- rp->p_flags |= PENDING | SIG_PENDING;
- m.NOTIFY_TYPE = KSIG_PENDING;
- m.NOTIFY_ARG = 0;
- m.NOTIFY_FLAGS = 0;
- lock_notify(PM_PROC_NR, &m);
+ if (! sigismember(&rp->p_pending, sig_nr)) {
+ sigaddset(&rp->p_pending, sig_nr);
+ if (rp->p_flags & SIGNALED) return; /* other signal pending */
+ if (rp->p_flags == 0) lock_unready(rp); /* unready if not yet done */
+ rp->p_flags |= SIGNALED | SIG_PENDING; /* update signal flags */
+ m.NOTIFY_TYPE = KSIG_PENDING;
+ m.NOTIFY_ARG = 0;
+ m.NOTIFY_FLAGS = 0;
+ lock_notify(PM_PROC_NR, &m);
+ }
}
*/
/* Check all acceptable ranges. */
-#if DEAD_CODE
+#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)
_PROTOTYPE( int do_abort, (message *m_ptr) );
_PROTOTYPE( int do_getinfo, (message *m_ptr) );
-_PROTOTYPE( int do_exit, (message *m_ptr) ); /* system control */
-_PROTOTYPE( int do_svrctl, (message *m_ptr) );
+_PROTOTYPE( int do_svrctl, (message *m_ptr) ); /* system control */
_PROTOTYPE( int do_iopenable, (message *m_ptr) );
_PROTOTYPE( int do_segctl, (message *m_ptr) );
# Directories
u = /usr
i = $u/include
-s = $i/sys
-h = $i/minix
-m = $i/ibm
-l = $u/lib
-n = $i/net
-g = $n/gen
-x = .
-k = ..
# Programs, flags, etc.
CC = exec cc
LDFLAGS = -i
SYS = clock.o copying.o debugging.o devio.o irqctl.o proctl.o \
- sysctl.o misc.o sigctl.o tracing.o \
+ sysctl.o misc.o sigctl.o tracing.o
# What to make.
all build: $(SYS)
- aal cr system.a $(SYS)
clean:
rm -f *.a *.o *.bak
-# Dependencies from src/kernel/kernel.h
-a = $h/config.h $h/const.h $h/type.h $h/ipc.h \
- $i/string.h $i/limits.h $i/errno.h $i/stddef.h \
- $s/types.h \
- $m/portio.h \
- $k/proc.h $k/const.h $k/type.h $k/proto.h $k/glo.h
-
-# Dependencies from src/kernel/system.h
-b = $k/system.h $h/com.h $k/proc.h
-
-clock.o: $a $b
-copying.o: $a $b
-debugging.o: $a $b
-devio.o: $a $b $h/devio.h
-irqctl.o: $a $b
-misc.o: $a $b $i/unistd.h
-proctl.o: $a $b $k/sendmask.h $k/protect.h $i/signal.h
-sigctl.o: $a $b $i/signal.h $s/sigcontext.h
-sysctl.o: $a $b $s/svrctl.h $k/sendmask.h
-tracing.o: $a $b $s/ptrace.h
+depend:
+ /usr/bin/mkdep "$(CC) -E $(CPPFLAGS)" *.c > .depend
+
+# Include generated dependencies.
+include .depend
}
for (xp = BEG_PROC_ADDR; xp < END_PROC_ADDR; ++xp) {
- if(isalivep(xp) && xp->p_ready && !xp->p_found) {
+ if(! isempty(xp) && xp->p_ready && ! xp->p_found) {
kprintf("scheduling error: ready not on queue: %s\n", (karg_t) when);
panic("ready proc not on scheduling queue", NO_NUM);
if(l++ > PROCLIMIT) { panic("loop in proc.t?", NO_NUM); }
int how = m_ptr->ABRT_HOW;
if (how == RBT_MONITOR) {
- /* The monitor is to run user specified instructions. */
+ /* 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;
/* Validate length and address of shutdown code before copying. */
if (length > kinfo.params_size || src_phys == 0)
- kprintf("Warning, skipping shutdown code\n", NO_NUM);
+ phys_copy(vir2phys("delay;boot"), kinfo.params_base, 11);
else
phys_copy(src_phys, kinfo.params_base, (phys_bytes) length);
}
#endif
rpc->p_nr = m_ptr->PR_PROC_NR; /* this was obliterated by copy */
rpc->p_ntf_q = NULL; /* remove pending notifications */
- rpc->p_flags |= NO_MAP; /* inhibit process from running */
-
- rpc->p_flags &= ~(PENDING | SIG_PENDING | P_STOP);
- /* Only 1 in group should have PENDING, child does not inherit trace status*/
+ /* Only one in group should have SIGNALED, child doesn't inherit tracing. */
+ rpc->p_flags |= NO_MAP; /* inhibit process from running */
+ rpc->p_flags &= ~(SIGNALED | SIG_PENDING | P_STOP);
sigemptyset(&rpc->p_pending);
- rpc->p_pendcount = 0;
- rpc->p_reg.retreg = 0; /* child sees pid = 0 to know it is child */
+ rpc->p_reg.retreg = 0; /* child sees pid = 0 to know it is child */
rpc->p_user_time = 0; /* set all the accounting times to 0 */
rpc->p_sys_time = 0;
*
* The parameters for this system call are:
* m1_i1: PR_PROC_NR (slot number of exiting process)
- * m1_i2: PR_PPROC_NR (slot number of parent process)
*/
PUBLIC int do_xit(m_ptr)
message *m_ptr; /* pointer to request message */
{
-/* Handle sys_exit. A user process has exited (the PM sent the request).
+/* Handle sys_exit. A user process has exited or a system process requests
+ * to exit. Only the PM can request other process slots to be cleared.
+ * The routine to clean up a process table slot cancels outstanding timers,
+ * possibly removes the process from the message queues, and resets certain
+ * process table fields to the default values.
*/
- register struct proc *rc;
int exit_proc_nr;
- /* Get a pointer to the process that exited. */
- exit_proc_nr = m_ptr->PR_PROC_NR;
- if (exit_proc_nr == SELF) exit_proc_nr = m_ptr->m_source;
- if (! isokprocn(exit_proc_nr)) return(EINVAL);
- rc = proc_addr(exit_proc_nr);
-
-#if DEAD_CODE
- /* If this is a user process and the PM passed in a valid parent process,
- * accumulate the child times at the parent.
- */
- if (isuserp(rc) && isokprocn(m_ptr->PR_PPROC_NR)) {
- rp = proc_addr(m_ptr->PR_PPROC_NR);
- lock(15, "do_xit");
- rp->child_utime += rc->user_time + rc->child_utime;
- rp->child_stime += rc->sys_time + rc->child_stime;
- unlock(15);
- }
-#endif
-
- /* Now call the routine to clean up of the process table slot. This cancels
- * outstanding timers, possibly removes the process from the message queues,
- * and resets important process table fields.
- */
- clear_proc(exit_proc_nr);
- return(OK); /* tell PM that cleanup succeeded */
+ /* Determine what process exited. */
+ if (PM_PROC_NR == m_ptr->m_source) {
+ exit_proc_nr = m_ptr->PR_PROC_NR; /* get exiting process */
+ if (exit_proc_nr != SELF) { /* PM tries to exit self */
+ if (! isokprocn(exit_proc_nr)) return(EINVAL);
+ clear_proc(exit_proc_nr); /* exit a user process */
+ return(OK); /* report back to PM */
+ }
+ }
+
+ /* The PM or some other system process requested to be exited. */
+ clear_proc(m_ptr->m_source);
+ return(EDONTREPLY);
}
/* Find the next process with pending signals. */
for (rp = BEG_USER_ADDR; rp < END_PROC_ADDR; rp++) {
- if (rp->p_flags & PENDING) {
+ if (rp->p_flags & SIGNALED) {
m_ptr->SIG_PROC = rp->p_nr;
m_ptr->SIG_MAP = rp->p_pending;
sigemptyset(&rp->p_pending); /* ball is in PM's court */
- rp->p_flags &= ~PENDING; /* blocked by SIG_PENDING */
+ rp->p_flags &= ~SIGNALED; /* blocked by SIG_PENDING */
return(OK);
}
}
register struct proc *rp;
rp = proc_addr(m_ptr->SIG_PROC);
- if (isemptyp(rp)) return(EINVAL); /* process already dead? */
+ if (isemptyp(rp)) return(EINVAL); /* process already dead? */
/* PM has finished one kernel signal. Perhaps process is ready now? */
- if (rp->p_pendcount != 0 && --rp->p_pendcount == 0
- && (rp->p_flags &= ~SIG_PENDING) == 0)
- lock_ready(rp);
+ if (! (rp->p_flags & SIGNALED)) /* new signal arrived */
+ if ((rp->p_flags &= ~SIG_PENDING) == 0) /* remove pending flag */
+ lock_ready(rp); /* ready if no flags */
return(OK);
}
-
-/* The system call implemented in this file:
- * m_type: SYS_EXIT
- *
- * The parameters for this system call are:
- * m1_i1: EXIT_STATUS (exit status, 0 if normal exit)
- *
- * Author:
- * Jorrit N. Herder <jnherder@cs.vu.nl>
- */
-
#include "../kernel.h"
#include "../ipc.h"
#include "../system.h"
#include <sys/svrctl.h>
#include "../sendmask.h"
-/*===========================================================================*
- * do_exit *
- *===========================================================================*/
-PUBLIC int do_exit(m_ptr)
-message *m_ptr; /* pointer to request message */
-{
-/* Handle sys_exit. A server or driver wants to exit. This may happen
- * on a panic, but also is done when MINIX is shutdown.
- */
- int proc_nr = m_ptr->m_source; /* can only exit own process */
-
- if (m_ptr->EXIT_STATUS != 0) {
- kprintf("WARNING: system process %d exited with an error.\n", proc_nr );
- }
-
- /* Now call the routine to clean up of the process table slot. This cancels
- * outstanding timers, possibly removes the process from the message queues,
- * and reset important process table fields.
- */
- clear_proc(proc_nr);
-
- /* If the shutdown sequence is active, see if it was awaiting the shutdown
- * of this system service. If so, directly continue the stop sequence.
- */
- if (shutting_down && shutdown_process == proc_addr(proc_nr)) {
- stop_sequence(&shutdown_timer);
- }
- return(EDONTREPLY); /* no reply is sent */
-}
-
/* The system call implemented in this file:
}
case SYSSENDMASK: {
rp->p_call_mask = SYSTEM_CALL_MASK;
- rp->p_type = P_SERVER;
rp->p_sendmask = ALLOW_ALL_MASK;
send_mask_allow(proc_addr(USR8139)->p_sendmask, proc_nr);
send_mask_allow(proc_addr(PM_PROC_NR)->p_sendmask, proc_nr);
* Changes:
* Nov 10, 2004 removed controller->driver mappings (Jorrit N. Herder)
* Oct 17, 2004 updated above and tasktab comments (Jorrit N. Herder)
- * Aug 18, 2004 included p_type in tasktab (Jorrit N. Herder)
* May 01, 2004 included p_sendmask in tasktab (Jorrit N. Herder)
*/
* routine and stack size is also provided.
*/
PUBLIC struct system_image image[] = {
- { IDLE, idle_task, P_IDLE, PPRI_IDLE, IDLE_STACK, EMPTY_CALL_MASK, IDLE_SENDMASK, "IDLE" },
- { CLOCK, clock_task, P_TASK, PPRI_TASK, CLOCK_STACK, SYSTEM_CALL_MASK, CLOCK_SENDMASK, "CLOCK" },
- { SYSTASK, sys_task, P_TASK, PPRI_TASK, SYS_STACK, SYSTEM_CALL_MASK, SYSTEM_SENDMASK, "SYS" },
- { HARDWARE, 0, P_TASK, PPRI_TASK, HARDWARE_STACK, EMPTY_CALL_MASK, HARDWARE_SENDMASK,"HARDW." },
- { PM_PROC_NR, 0, P_SERVER, PPRI_NORMAL, 0, SYSTEM_CALL_MASK, PM_SENDMASK, "PM" },
- { FS_PROC_NR, 0, P_SERVER, PPRI_NORMAL, 0, SYSTEM_CALL_MASK, FS_SENDMASK, "FS" },
- { IS_PROC_NR, 0, P_SYSTEM, PPRI_HIGH, 0, SYSTEM_CALL_MASK, IS_SENDMASK, "IS" },
- { TTY, 0, P_SYSTEM, PPRI_HIGHER, 0, SYSTEM_CALL_MASK, TTY_SENDMASK, "TTY" },
- { MEMORY, 0, P_DRIVER, PPRI_HIGH, 0, SYSTEM_CALL_MASK, MEM_SENDMASK, "MEMORY" },
+ { IDLE, idle_task, 0, IDLE_Q, IDLE_STACK, EMPTY_CALL_MASK, DENY_ALL_MASK, "IDLE" },
+ { CLOCK, clock_task, 0, TASK_Q, CLOCK_STACK, SYSTEM_CALL_MASK, ALLOW_ALL_MASK, "CLOCK" },
+ { SYSTASK, sys_task, 0, TASK_Q, SYS_STACK, SYSTEM_CALL_MASK, ALLOW_ALL_MASK, "SYS" },
+ { HARDWARE, 0, 0, TASK_Q, HARDWARE_STACK, EMPTY_CALL_MASK, ALLOW_ALL_MASK,"HARDW." },
+ { PM_PROC_NR, 0, 0, 3, 0, SYSTEM_CALL_MASK, ALLOW_ALL_MASK, "PM" },
+ { FS_PROC_NR, 0, 0, 3, 0, SYSTEM_CALL_MASK, ALLOW_ALL_MASK, "FS" },
+ { SM_PROC_NR, 0, 0, 2, 0, SYSTEM_CALL_MASK, ALLOW_ALL_MASK, "SM" },
+ { IS_PROC_NR, 0, 0, 2, 0, SYSTEM_CALL_MASK, ALLOW_ALL_MASK, "IS" },
+ { TTY, 0, 0, 1, 0, SYSTEM_CALL_MASK, ALLOW_ALL_MASK, "TTY" },
+ { MEMORY, 0, 0, 2, 0, SYSTEM_CALL_MASK, ALLOW_ALL_MASK, "MEMORY" },
#if ENABLE_AT_WINI
- { AT_WINI, 0, P_DRIVER, PPRI_HIGH, 0, SYSTEM_CALL_MASK, AT_SENDMASK, "AT_WINI" },
+ { AT_WINI, 0, 0, 2, 0, SYSTEM_CALL_MASK, ALLOW_ALL_MASK, "AT_WINI" },
#endif
#if ENABLE_FLOPPY
- { FLOPPY, 0, P_DRIVER, PPRI_HIGH, 0, SYSTEM_CALL_MASK, FLOPPY_SENDMASK, "FLOPPY" },
+ { FLOPPY, 0, 0, 2, 0, SYSTEM_CALL_MASK, ALLOW_ALL_MASK, "FLOPPY" },
#endif
#if ENABLE_PRINTER
- { PRINTER, 0, P_DRIVER, PPRI_NORMAL, 0, SYSTEM_CALL_MASK, PRN_SENDMASK, "PRINTER" },
+ { PRINTER, 0, 0, 3, 0, SYSTEM_CALL_MASK, ALLOW_ALL_MASK, "PRINTER" },
#endif
#if ENABLE_RTL8139
- { USR8139, 0, P_DRIVER, PPRI_HIGH, 0, SYSTEM_CALL_MASK, RTL8139_SENDMASK, "RTL8139" },
+ { USR8139, 0, 0, 2, 0, SYSTEM_CALL_MASK, ALLOW_ALL_MASK, "RTL8139" },
#endif
#if ENABLE_FXP
- { FXP, 0, P_DRIVER, PPRI_HIGH, 0, SYSTEM_CALL_MASK, FXP_SENDMASK, "FXP" },
+ { FXP, 0, 0, 2, 0, SYSTEM_CALL_MASK, ALLOW_ALL_MASK, "FXP" },
#endif
- { INIT_PROC_NR, 0, P_USER, PPRI_USER, 0, USER_CALL_MASK, INIT_SENDMASK, "INIT" },
+ { INIT_PROC_NR, 0, 0, USER_Q, 0, USER_CALL_MASK, USER_PROC_SENDMASK, "INIT" },
};
/* Verify the size of the system image table at compile time. If the number