Various updates.
* Removed some variants of the SYS_GETINFO calls from the kernel; replaced them with new PM and utils libary functionality. Fixed bugs in utils library that used old get_kenv() variant. * Implemented a buffer in the kernel to gather random data. Memory driver periodically checks this for /dev/random. A better random algorithm can now be implemented in the driver. Removed SYS_RANDOM; the SYS_GETINFO call is used instead. * Remove SYS_KMALLOC from the kernel. Memory allocation can now be done at the process manager with new 'other' library functions.
This commit is contained in:
@@ -29,8 +29,8 @@
|
||||
/* How many bytes should the circular buffer for kernel diagnostics. */
|
||||
#define KMESS_BUF_SIZE 256
|
||||
|
||||
/* How many bytes for (port,value)-pairs vector to copy in. */
|
||||
#define VDEVIO_BUF_SIZE 128
|
||||
/* Maximum size in bytes for (port,value)-pairs vector to copy in. */
|
||||
#define VDEVIO_BUF_SIZE 64
|
||||
|
||||
/* How many elements in vector of virtual copy requests. */
|
||||
#define VCOPY_VEC_SIZE 16
|
||||
@@ -41,6 +41,9 @@
|
||||
/* How many buffers for notification messages should there be? */
|
||||
#define NR_NOTIFY_BUFS 32
|
||||
|
||||
/* Buffer to gather randomness. How many entries before wrapping? */
|
||||
#define RANDOM_ELEMENTS 32
|
||||
|
||||
/* Constants and macros for bit map manipulation. */
|
||||
#define BITCHUNK_BITS (sizeof(bitchunk_t) * CHAR_BIT)
|
||||
#define BITMAP_CHUNKS(nr_bits) (((nr_bits)+BITCHUNK_BITS-1)/BITCHUNK_BITS)
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
/* This file contains a simple exception handler. Exceptions in user
|
||||
* processes are converted to signals. Exceptions in the kernel, MM and
|
||||
* FS cause a panic.
|
||||
*
|
||||
* Changes:
|
||||
* Sep 28, 2004: skip_stop_sequence on exceptions in system processes
|
||||
*/
|
||||
|
||||
#include "kernel.h"
|
||||
@@ -78,7 +75,7 @@ unsigned vec_nr;
|
||||
* notification ...
|
||||
*/
|
||||
if (istaskp(saved_proc)) { /* serious problem */
|
||||
skip_stop_sequence = TRUE; /* directly shutdown */
|
||||
kernel_exception = TRUE; /* directly shutdown */
|
||||
panic("exception in a kernel task", NO_NUM);
|
||||
} else {
|
||||
clear_proc(saved_proc->p_nr);
|
||||
|
||||
40
kernel/glo.h
40
kernel/glo.h
@@ -1,32 +1,30 @@
|
||||
/* Global variables used in the kernel. This file contains the declarations;
|
||||
* storage space for the variables is allocated in table.c, because EXTERN is
|
||||
* defined as extern unless the _TABLE definition is seen.
|
||||
* defined as extern unless the _TABLE definition is seen. We rely on the
|
||||
* compiler's default initialization (0) for several global variables.
|
||||
*/
|
||||
#ifdef _TABLE
|
||||
#undef EXTERN
|
||||
#define EXTERN
|
||||
#endif
|
||||
|
||||
#include "const.h"
|
||||
#include <minix/config.h>
|
||||
|
||||
/* MINIX' shutdown sequence uses watchdog timers to stop system services. The
|
||||
* flag shutting_down must be initialized to FALSE. We rely on the compiler's
|
||||
* default initialization (0) of global variables here.
|
||||
*/
|
||||
EXTERN char skip_stop_sequence; /* set to TRUE in case of an exception() */
|
||||
EXTERN char shutting_down; /* TRUE if the system is shutting down */
|
||||
/* 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; /* watchdog function called after timeout */
|
||||
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 */
|
||||
EXTERN struct kinfo kinfo; /* kernel information for users */
|
||||
EXTERN struct machine machine; /* machine information for users */
|
||||
EXTERN struct kmessages kmess; /* diagnostic messages in kernel */
|
||||
EXTERN phys_bytes aout; /* address of a.out headers */
|
||||
EXTERN struct kinfo kinfo; /* kernel information for users */
|
||||
EXTERN struct machine machine; /* machine information for users */
|
||||
EXTERN struct kmessages kmess; /* diagnostic messages in kernel */
|
||||
EXTERN struct randomness krandom; /* gather kernel random information */
|
||||
EXTERN struct memory mem[NR_MEMS]; /* base and size of chunks of memory */
|
||||
|
||||
/* Process scheduling info and kernel entry count. */
|
||||
/* 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 char k_reenter; /* kernel reentry count (entry count less 1) */
|
||||
@@ -43,21 +41,21 @@ EXTERN bitchunk_t notify_bitmap[BITMAP_CHUNKS(NR_NOTIFY_BUFS)];
|
||||
EXTERN irq_hook_t irq_hooks[NR_IRQ_HOOKS]; /* hooks for general use */
|
||||
EXTERN irq_hook_t *irq_handlers[NR_IRQ_VECTORS];/* list of IRQ handlers */
|
||||
EXTERN int irq_actids[NR_IRQ_VECTORS]; /* IRQ ID bits active */
|
||||
EXTERN int irq_use; /* bit map of all in-use irq's */
|
||||
EXTERN int irq_use; /* map of all in-use irq's */
|
||||
|
||||
/* lock() timing data. */
|
||||
/* Data structure to store lock() timing data. */
|
||||
#if ENABLE_LOCK_TIMING
|
||||
EXTERN struct lock_timedata timingdata[TIMING_CATEGORIES];
|
||||
#endif
|
||||
|
||||
/* Miscellaneous. */
|
||||
EXTERN reg_t mon_ss, mon_sp; /* monitor stack */
|
||||
EXTERN int mon_return; /* true if return to the monitor possible */
|
||||
EXTERN reg_t mon_ss, mon_sp; /* boot monitor stack */
|
||||
EXTERN int mon_return; /* true if we can return to monitor */
|
||||
|
||||
/* Variables that are initialized elsewhere are just extern here. */
|
||||
extern struct system_image image[]; /* system image processes (table.c) */
|
||||
extern char *t_stack[]; /* stack space for kernel tasks (table.c) */
|
||||
extern struct segdesc_s gdt[]; /* protected mode global descriptor (protect.c) */
|
||||
extern struct system_image image[]; /* system image processes */
|
||||
extern char *t_stack[]; /* task stack space */
|
||||
extern struct segdesc_s gdt[]; /* global descriptor table */
|
||||
|
||||
EXTERN _PROTOTYPE( void (*level0_func), (void) );
|
||||
#endif /* (CHIP == INTEL) */
|
||||
|
||||
@@ -248,7 +248,7 @@ int how; /* 0 = halt, 1 = reboot, 2 = panic!, ... */
|
||||
*/
|
||||
shutting_down = TRUE; /* flag for sys_exit() */
|
||||
tmr_arg(&shutdown_timer)->ta_int = how; /* pass how in timer */
|
||||
if (skip_stop_sequence) { /* set in exception() */
|
||||
if (kernel_exception) { /* set in exception() */
|
||||
kprintf("\nAn exception occured; skipping stop sequence.\n", NO_ARG);
|
||||
shutdown(&shutdown_timer); /* TTY isn't scheduled */
|
||||
} else {
|
||||
|
||||
@@ -442,7 +442,6 @@ message *m_ptr; /* pointer to message buffer */
|
||||
struct proc *caller_ptr;
|
||||
|
||||
lock(0, "notify");
|
||||
kinfo.lock_notify ++;
|
||||
caller_ptr = (k_reenter >= 0) ? proc_addr(HARDWARE) : proc_ptr;
|
||||
result = mini_notify(caller_ptr, dst, m_ptr);
|
||||
unlock(0);
|
||||
@@ -654,7 +653,6 @@ message *m_ptr; /* pointer to message buffer */
|
||||
/* Safe gateway to mini_send() for tasks. */
|
||||
int result;
|
||||
lock(2, "send");
|
||||
kinfo.lock_send ++;
|
||||
result = mini_send(proc_ptr, dst, m_ptr, NON_BLOCKING);
|
||||
unlock(2);
|
||||
return(result);
|
||||
|
||||
@@ -62,6 +62,7 @@ _PROTOTYPE( void clear_proc, (int proc_nr) );
|
||||
_PROTOTYPE( phys_bytes numap_local, (int proc_nr, vir_bytes vir_addr,
|
||||
vir_bytes bytes) );
|
||||
_PROTOTYPE( void sys_task, (void) );
|
||||
_PROTOTYPE( void get_randomness, (void) );
|
||||
_PROTOTYPE( int virtual_copy, (struct vir_addr *src, struct vir_addr *dst,
|
||||
vir_bytes bytes) );
|
||||
_PROTOTYPE( phys_bytes umap_local, (struct proc *rp, int seg,
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
* umap_bios: map virtual address in BIOS_SEG to physical
|
||||
* numap_local: umap_local D segment from proc nr instead of pointer
|
||||
* virtual_copy: copy bytes from one virtual address to another
|
||||
* get_randomness: accumulate randomness in a buffer
|
||||
* generic_handler: interrupt handler for user-level device drivers
|
||||
*
|
||||
* Changes:
|
||||
@@ -152,7 +153,6 @@ PRIVATE void initialize(void)
|
||||
map(SYS_VDEVIO, do_vdevio); /* vector with devio requests */
|
||||
|
||||
/* Server and driver control. */
|
||||
map(SYS_KMALLOC, do_kmalloc); /* request chunk of free memory */
|
||||
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 */
|
||||
@@ -169,7 +169,6 @@ PRIVATE void initialize(void)
|
||||
/* Miscellaneous. */
|
||||
map(SYS_ABORT, do_abort); /* abort MINIX */
|
||||
map(SYS_GETINFO, do_getinfo); /* request system information */
|
||||
map(SYS_RANDOM, do_random); /* request kernel random data */
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
@@ -262,6 +261,20 @@ int proc_nr; /* slot of process to clean up */
|
||||
}
|
||||
|
||||
|
||||
/*===========================================================================*
|
||||
* get_randomness *
|
||||
*===========================================================================*/
|
||||
PUBLIC void get_randomness()
|
||||
{
|
||||
/* Gather random information with help of the CPU's cycle counter. Only use
|
||||
* the lowest bytes because the highest bytes won't differ that much.
|
||||
*/
|
||||
unsigned long tsc_high;
|
||||
read_tsc(&tsc_high, &krandom.r_buf[krandom.r_next]);
|
||||
if (krandom.r_size < RANDOM_ELEMENTS) krandom.r_size ++;
|
||||
krandom.r_next = (krandom.r_next + 1 ) % RANDOM_ELEMENTS;
|
||||
}
|
||||
|
||||
|
||||
/*===========================================================================*
|
||||
* generic_handler *
|
||||
@@ -272,8 +285,15 @@ irq_hook_t *hook;
|
||||
/* This function handles hardware interrupt in a simple and generic way. All
|
||||
* interrupts are transformed into messages to a driver. The IRQ line will be
|
||||
* reenabled if the policy says so.
|
||||
* In addition, the interrupt handler gathers random information in a buffer
|
||||
* by timestamping the interrupts.
|
||||
*/
|
||||
message m;
|
||||
|
||||
/* Gather random information. */
|
||||
get_randomness();
|
||||
|
||||
/* Build notification message and return. */
|
||||
m.NOTIFY_TYPE = HARD_INT;
|
||||
m.NOTIFY_ARG = hook->irq;
|
||||
lock_notify(hook->proc_nr, &m);
|
||||
|
||||
@@ -31,11 +31,9 @@ _PROTOTYPE( int do_umap, (message *m_ptr) );
|
||||
_PROTOTYPE( int do_unused, (message *m_ptr) ); /* miscellaneous */
|
||||
_PROTOTYPE( int do_abort, (message *m_ptr) );
|
||||
_PROTOTYPE( int do_getinfo, (message *m_ptr) );
|
||||
_PROTOTYPE( int do_random, (message *m_ptr) );
|
||||
|
||||
_PROTOTYPE( int do_exit, (message *m_ptr) ); /* system control */
|
||||
_PROTOTYPE( int do_svrctl, (message *m_ptr) );
|
||||
_PROTOTYPE( int do_kmalloc, (message *m_ptr) );
|
||||
_PROTOTYPE( int do_iopenable, (message *m_ptr) );
|
||||
_PROTOTYPE( int do_segctl, (message *m_ptr) );
|
||||
|
||||
|
||||
@@ -16,15 +16,6 @@ message *m; /* pointer to request message */
|
||||
}
|
||||
|
||||
|
||||
/*===========================================================================*
|
||||
* do_random *
|
||||
*===========================================================================*/
|
||||
PUBLIC int do_random(m)
|
||||
message *m; /* pointer to request message */
|
||||
{
|
||||
return(ENOSYS); /* no yet implemented */
|
||||
}
|
||||
|
||||
|
||||
/* The system call implemented in this file:
|
||||
* m_type: SYS_ABORT
|
||||
@@ -131,6 +122,7 @@ register message *m_ptr; /* pointer to request message */
|
||||
length);
|
||||
if (src_phys == 0 || dst_phys == 0) return(EFAULT);
|
||||
phys_copy(src_phys, dst_phys, length);
|
||||
/* fall through */
|
||||
}
|
||||
case GET_PROCTAB: {
|
||||
length = sizeof(struct proc) * (NR_PROCS + NR_TASKS);
|
||||
@@ -139,49 +131,22 @@ register message *m_ptr; /* pointer to request message */
|
||||
}
|
||||
case GET_PROC: {
|
||||
nr = (m_ptr->I_KEY_LEN == SELF) ? m_ptr->m_source : m_ptr->I_KEY_LEN;
|
||||
if (! isokprocn(nr)) return(EINVAL);
|
||||
if (! isokprocn(nr)) return(EINVAL); /* validate request */
|
||||
length = sizeof(struct proc);
|
||||
src_phys = vir2phys(proc_addr(nr));
|
||||
break;
|
||||
}
|
||||
case GET_MONPARAMS: {
|
||||
src_phys = kinfo.params_base; /* already is a physical address! */
|
||||
src_phys = kinfo.params_base; /* already is a physical */
|
||||
length = kinfo.params_size;
|
||||
break;
|
||||
}
|
||||
case GET_PROCNR: {
|
||||
if (m_ptr->I_KEY_LEN == 0) { /* get own process nr */
|
||||
/* GET_PROCNR functionality will be moved to the Process Manager! */
|
||||
kprintf("GET_PROCNR (own) from %d\n", m_ptr->m_source);
|
||||
src_phys = vir2phys(&proc_nr);
|
||||
length = sizeof(int);
|
||||
} else { /* lookup nr by name */
|
||||
int proc_found = FALSE;
|
||||
struct proc *pp;
|
||||
struct vir_addr vsrc, vdst;
|
||||
char key[8]; /* storage for process name to lookup */
|
||||
/* GET_PROCNR functionality will be moved to the Process Manager! */
|
||||
kprintf("GET_PROCNR (by name) from %d\n", m_ptr->m_source);
|
||||
proc_nr = m_ptr->m_source; /* only caller can request copy */
|
||||
if (m_ptr->I_KEY_LEN > sizeof(key)) return(EINVAL);
|
||||
vsrc.proc_nr = proc_nr; vsrc.segment = D; vsrc.offset = (vir_bytes) m_ptr->I_KEY_PTR;
|
||||
vdst.proc_nr = SYSTASK, vdst.segment = D; vdst.offset = (vir_bytes) key;
|
||||
if (virtual_copy(&vsrc, &vdst, m_ptr->I_KEY_LEN) != OK) return(EFAULT);
|
||||
#if DEAD_CODE
|
||||
if (vir_copy(proc_nr, (vir_bytes) m_ptr->I_KEY_PTR, SYSTASK,
|
||||
(vir_bytes) key, m_ptr->I_KEY_LEN) != OK) return(EFAULT);
|
||||
#endif
|
||||
for (pp=BEG_PROC_ADDR; pp<END_PROC_ADDR; pp++) {
|
||||
if (kstrncmp(pp->p_name, key, m_ptr->I_KEY_LEN) == 0) {
|
||||
src_phys = vir2phys(&(pp->p_nr));
|
||||
length = sizeof(int);
|
||||
proc_found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (! proc_found) return(ESRCH);
|
||||
}
|
||||
break;
|
||||
case GET_RANDOMNESS: {
|
||||
struct randomness copy = krandom; /* copy to keep counters */
|
||||
krandom.r_next = krandom.r_size = 0; /* invalidate random data */
|
||||
length = sizeof(struct randomness);
|
||||
src_phys = vir2phys(©);
|
||||
break;
|
||||
}
|
||||
case GET_KMESSAGES: {
|
||||
length = sizeof(struct kmessages);
|
||||
|
||||
@@ -219,38 +219,3 @@ register message *m_ptr; /* pointer to request message */
|
||||
}
|
||||
|
||||
|
||||
/* The system call implemented in this file:
|
||||
* m_type: SYS_KMALLOC
|
||||
*
|
||||
* The parameters for this system call are:
|
||||
* m4_l2: MEM_CHUNK_SIZE (request a buffer of this size)
|
||||
* m4_l1: MEM_CHUNK_BASE (return physical address on success)
|
||||
*
|
||||
* Author:
|
||||
* Jorrit N. Herder <jnherder@cs.vu.nl>
|
||||
*/
|
||||
|
||||
/*===========================================================================*
|
||||
* do_kmalloc *
|
||||
*===========================================================================*/
|
||||
PUBLIC int do_kmalloc(m_ptr)
|
||||
register message *m_ptr; /* pointer to request message */
|
||||
{
|
||||
/* Request a (DMA) buffer to be allocated in one of the memory chunks. */
|
||||
phys_clicks tot_clicks;
|
||||
struct memory *memp;
|
||||
|
||||
kprintf("SYS_KMALLOC called by %d\n", m_ptr->m_source);
|
||||
|
||||
tot_clicks = (m_ptr->MEM_CHUNK_SIZE + CLICK_SIZE-1) >> CLICK_SHIFT;
|
||||
memp = &mem[NR_MEMS];
|
||||
while ((--memp)->size < tot_clicks) {
|
||||
if (memp == mem) {
|
||||
return(ENOMEM);
|
||||
}
|
||||
}
|
||||
memp->size -= tot_clicks;
|
||||
m_ptr->MEM_CHUNK_BASE = (memp->base + memp->size) << CLICK_SHIFT;
|
||||
return(OK);
|
||||
}
|
||||
|
||||
|
||||
@@ -52,6 +52,11 @@ struct kmessages {
|
||||
char km_buf[KMESS_BUF_SIZE]; /* buffer for messages */
|
||||
};
|
||||
|
||||
struct randomness {
|
||||
int r_next; /* next index to write */
|
||||
int r_size; /* number of random elements */
|
||||
unsigned long r_buf[RANDOM_ELEMENTS]; /* buffer for random info */
|
||||
};
|
||||
|
||||
#if (CHIP == INTEL)
|
||||
typedef unsigned reg_t; /* machine register */
|
||||
|
||||
Reference in New Issue
Block a user