#include <limits.h>
#include <stddef.h>
#include <errno.h>
+#include <unistd.h>
#include "../drivers.h"
#include "../libdriver/driver.h"
+#include <sys/ioc_memory.h>
#include "../../kernel/const.h"
#include "../../kernel/type.h"
-#include <sys/ioc_memory.h>
#define NR_DEVS 7 /* number of minor devices */
+#define KRANDOM_PERIOD 10 /* ticks between krandom calls */
PRIVATE struct device m_geom[NR_DEVS]; /* base and size of each device */
PRIVATE int m_seg[NR_DEVS]; /* segment index of each device */
PRIVATE int m_device; /* current device */
-PRIVATE struct kinfo kinfo; /* need kernel info */
-PRIVATE struct machine machine; /* need machine info */
+PRIVATE struct kinfo kinfo; /* kernel information */
+PRIVATE struct machine machine; /* machine information */
+PRIVATE struct randomness krandom; /* randomness from the kernel */
+
+extern int errno; /* error number for PM calls */
FORWARD _PROTOTYPE( char *m_name, (void) );
FORWARD _PROTOTYPE( struct device *m_prepare, (int device) );
FORWARD _PROTOTYPE( void m_init, (void) );
FORWARD _PROTOTYPE( int m_ioctl, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( void m_geometry, (struct partition *entry) );
+FORWARD _PROTOTYPE( void m_random, (struct driver *dp) );
/* Entry points to this driver. */
PRIVATE struct driver m_dtab = {
nop_cleanup, /* no need to clean up */
m_geometry, /* memory device "geometry" */
nop_stop, /* no need to clean up on shutdown */
- nop_alarm, /* ignore leftover alarms */
+ m_random, /* get randomness from kernel */
};
/* Buffer for the /dev/zero null byte feed. */
#define ZERO_BUF_SIZE 1024
-PRIVATE char zero[ZERO_BUF_SIZE];
+PRIVATE char dev_zero[ZERO_BUF_SIZE];
/* Buffer for the /dev/random number generator. */
#define RANDOM_BUF_SIZE 1024
-PRIVATE char random[RANDOM_BUF_SIZE];
+PRIVATE char dev_random[RANDOM_BUF_SIZE];
#define click_to_round_k(n) \
/* Random number generator. Character instead of block device. */
case RANDOM_DEV:
- printf("MEMORY: please note /dev/random is NOT yet random!\n");
left = count;
while (left > 0) {
chunk = (left > RANDOM_BUF_SIZE) ? RANDOM_BUF_SIZE : left;
if (opcode == DEV_GATHER) {
- sys_vircopy(SELF, D, (vir_bytes) random,
+ sys_vircopy(SELF, D, (vir_bytes) dev_random,
proc_nr, D, user_vir, chunk);
} else if (opcode == DEV_SCATTER) {
sys_vircopy(proc_nr, D, user_vir,
- SELF, D, (vir_bytes) random, chunk);
+ SELF, D, (vir_bytes) dev_random, chunk);
}
left -= chunk;
}
left = count;
while (left > 0) {
chunk = (left > ZERO_BUF_SIZE) ? ZERO_BUF_SIZE : left;
- if (OK != (s=sys_vircopy(SELF, D, (vir_bytes) zero,
+ if (OK != (s=sys_vircopy(SELF, D, (vir_bytes) dev_zero,
proc_nr, D, user_vir, chunk)))
report("MEM","sys_vircopy failed", s);
left -= chunk;
}
}
- /* Initialize /dev/random and /dev/zero. */
+ /* Initialize /dev/zero. Simply write zeros into the buffer. */
for (i=0; i<ZERO_BUF_SIZE; i++) {
- zero[i] = '\0';
- }
- for (i=0; i<RANDOM_BUF_SIZE; i++) {
- random[i] = 'a' + i % 256;
+ dev_zero[i] = '\0';
}
+ /* Initialize /dev/random. Seed the buffer and get kernel randomness. */
+ for (i=0; i<RANDOM_BUF_SIZE; i++) {
+ dev_random[i] = 'a' + i % 256; /* from file in future !!! */
+ }
+ m_random(NULL); /* also set periodic timer */
+
/* Set up memory ranges for /dev/mem. */
#if (CHIP == INTEL)
if (OK != (s=sys_getmachine(&machine))) {
/* Try to allocate a piece of memory for the RAM disk. */
ramdev_size = m_ptr->POSITION;
-
- printf("MEM: about to send to PM (ramdev_size %u)\n", ramdev_size);
- m.m_type = MEM_ALLOC;
- m.m4_l1 = ramdev_size;
- if (OK != (s=sendrec(PM_PROC_NR, &m)))
- report("MEM", "Couldn't sendrec to PM", s);
- dv->dv_size = cvul64(m.m4_l1);
- dv->dv_base = cvul64(m.m4_l2);
- printf("MEM: PM (s=%d) gave base 0x%06x, size 0x%06x\n", s, dv->dv_base, dv->dv_size);
-
- if (OK != (s=sys_kmalloc(ramdev_size, &ramdev_base)))
- panic("MEM","Couldn't allocate kernel memory", s);
+ if (allocmem(ramdev_size, &ramdev_base) < 0) return(ENOMEM);
dv->dv_base = cvul64(ramdev_base);
dv->dv_size = cvul64(ramdev_size);
- printf("MEM allocated: base 0x%06x, size 0x%06x\n", dv->dv_base, dv->dv_size);
+
if (OK != (s=sys_segctl(&m_seg[RAM_DEV], (u16_t *) &s, (vir_bytes *) &s,
ramdev_base, ramdev_size))) {
panic("MEM","Couldn't install remote segment.",s);
}
+/*============================================================================*
+ * m_random *
+ *============================================================================*/
+PRIVATE void m_random(dp)
+struct driver *dp; /* pointer to driver structure */
+{
+ /* Fetch random information from the kernel to update /dev/random. */
+ struct randomness krandom;
+ static unsigned long *next_ptr = (unsigned long *) &dev_random[0];
+ int i,s;
+ if (OK != (s=sys_getrandomness(&krandom)))
+ report("MEM", "sys_getrandomness failed", s);
+
+ i= (krandom.r_next + RANDOM_ELEMENTS -1) % RANDOM_ELEMENTS;
+ while (krandom.r_size -- > 0) {
+ *next_ptr = krandom.r_buf[i]; /* set dev_random data */
+ next_ptr ++; /* proceed to next */
+ if ((next_ptr - (unsigned long *) &dev_random[RANDOM_BUF_SIZE-1]) >=
+ RANDOM_ELEMENTS) next_ptr = (unsigned long *) &dev_random[0];
+ i = (i + 1) % RANDOM_ELEMENTS; /* next kernel random data */
+ }
+
+ /* Schedule new alarm for next m_random call. */
+ if (OK != (s=sys_syncalrm(SELF, KRANDOM_PERIOD, 0)))
+ report("MEM", "sys_syncalarm failed", s);
+}
+
/*============================================================================*
* m_geometry *
*============================================================================*/
rep->re_name[8] += i;
rep->re_seen= FALSE;
envvar[sizeof(RL_ENVVAR)-1]= '0'+i;
+#if DEAD_CODE
if (0 == sys_getkenv(envvar, strlen(envvar), val, sizeof(val)) &&
+#else
+ if (0 == get_mon_param(envvar, val, sizeof(val)) &&
+#endif
! env_prefix(envvar, "pci")) {
env_panic(envvar);
}
}
printf(" %sShift-F%d: ", i+1<10? " ":"", i+1);
- if (sfkey_obs[i] != NONE) {
+ if (i==0) {
+ printf("%-14.14s", "<reserved by TTY>");
+ } else if (sfkey_obs[i] != NONE) {
if ((s=sys_getproc(&proc, sfkey_obs[i]))!=OK)
printf("sys_getproc: %d\n", s);
printf("%-14.14s", proc.p_name);
#define GETPROCNR 80 /* to PM */
#define FSTATFS 82 /* to FS */
-#define MEM_ALLOC 83 /* to PM */
-#define MEM_FREE 84 /* to PM */
+#define ALLOCMEM 83 /* to PM */
+#define FREEMEM 84 /* to PM */
# define SYS_ABORT 9 /* sys_abort() */
# define SYS_KILL 10 /* sys_kill(proc_nr, sig) */
# define SYS_UMAP 11 /* sys_umap(proc_nr, etc) */
-# define SYS_RANDOM 12 /* sys_random(...) */
+
# define SYS_TRACE 13 /* sys_trace(req,pid,addr,data) */
# define SYS_SIGNALRM 15 /* sys_signalrm(proc_nr, ticks) */
# define SYS_DEVIO 23 /* sys_devio(port, value) */
# define SYS_VDEVIO 24 /* sys_vdevio(buf_ptr, nr_ports) */
# define SYS_IRQCTL 25 /* sys_irqctl() */
-# define SYS_KMALLOC 26 /* sys_kmalloc(size, phys_base) */
+
# define SYS_IOPENABLE 27 /* sys_enable_iop() */
# define SYS_SEGCTL 28 /* sys_segctl(*idx, *seg, *off, phys, size) */
# define SYS_EXIT 29 /* sys_exit(status) */
# define SYS_PHYSZERO 33 /* sys_physzero(addr,count) */
#define NR_SYS_CALLS 34 /* number of system calls */
-/* Field names for SYS_MEM, SYS_KMALLOC. */
+/* Field names for SYS_SEGCTL. */
#define MEM_CHUNK_BASE m4_l1 /* physical base address */
#define MEM_CHUNK_SIZE m4_l2 /* size of mem chunk */
#define MEM_TOT_SIZE m4_l3 /* total memory size */
#define I_REQUEST m7_i3 /* what info to get */
# define GET_KINFO 0 /* get kernel information structure */
# define GET_IMAGE 1 /* get system image table */
-# define GET_PROCTAB 2 /* get (kernel) process table */
-# define GET_PROCNR 3 /* find nr of process with name */
+# define GET_PROCTAB 2 /* get kernel process table */
+# define GET_RANDOMNESS 3 /* get randomness buffer */
# define GET_MONPARAMS 4 /* get monitor parameters */
# define GET_KENV 5 /* get kernel environment string */
# define GET_IRQHOOKS 6 /* get the IRQ table */
_PROTOTYPE(int sys_segctl, (int *index, u16_t *seg, vir_bytes *off,
phys_bytes phys, vir_bytes size));
_PROTOTYPE(int sys_enable_iop, (int proc_nr) );
-_PROTOTYPE(int sys_kmalloc, (size_t size, phys_bytes *phys_base) );
/* Shorthands for sys_getinfo() system call. */
#define sys_getkmessages(dst) sys_getinfo(GET_KMESSAGES, dst, 0,0,0)
#define sys_getmachine(dst) sys_getinfo(GET_MACHINE, dst, 0,0,0)
#define sys_getproctab(dst) sys_getinfo(GET_PROCTAB, dst, 0,0,0)
#define sys_getproc(dst,nr) sys_getinfo(GET_PROC, dst, 0,0, nr)
-#define sys_getprocnr(dst,k,kl) sys_getinfo(GET_PROCNR, dst, 0,k,kl)
+#define sys_getrandomness(dst) sys_getinfo(GET_RANDOMNESS, dst, 0,0,0)
#define sys_getimage(dst) sys_getinfo(GET_IMAGE, dst, 0,0,0)
#define sys_getirqhooks(dst) sys_getinfo(GET_IRQHOOKS, dst, 0,0,0)
#define sys_getmemchunks(dst) sys_getinfo(GET_MEMCHUNKS, dst, 0,0,0)
#define sys_getmonparams(v,vl) sys_getinfo(GET_MONPARAMS, v,vl, 0,0)
-#define sys_getkenv(k,kl,v,vl) sys_getinfo(GET_KENV, v,vl, k,kl)
#define sys_getschedinfo(v1,v2) sys_getinfo(GET_SCHEDINFO, v1,0, v2,0)
-#define sys_getkaddr(dst) sys_getinfo(GET_KADDRESSES, dst, 0,0,0)
#define sys_getlocktimings(dst) sys_getinfo(GET_LOCKTIMING, dst, 0,0,0)
_PROTOTYPE(int sys_getinfo, (int request, void *val_ptr, int val_len,
void *key_ptr, int key_len) );
#ifndef _TYPE_H
#define _TYPE_H
+#ifndef _CONFIG_H
+#include <minix/config.h>
+#endif
+
#ifndef _TYPES_H
#include <sys/types.h>
#endif
phys_bytes bootdev_size;
phys_bytes params_base; /* parameters passed by boot monitor */
phys_bytes params_size;
- long nr_ntf_pending;
- long lock_notify;
- long lock_send;
int nr_procs; /* number of user processes */
int nr_tasks; /* number of kernel tasks */
char version[8]; /* kernel version number */
_PROTOTYPE( ssize_t write, (int _fd, const void *_buf, size_t _n) );
#ifdef _MINIX
+#ifndef _TYPE_H
+#include <minix/type.h>
+#endif
_PROTOTYPE( int brk, (char *_addr) );
_PROTOTYPE( int chroot, (const char *_name) );
_PROTOTYPE( int mknod, (const char *_name, Mode_t _mode, Dev_t _addr) );
_PROTOTYPE( int getsysinfo, (int who, int what, void *where) );
_PROTOTYPE( int getprocnr, (int *proc_nr) );
_PROTOTYPE( int findproc, (char *proc_name, int *proc_nr) );
+_PROTOTYPE( int allocmem, (phys_bytes size, phys_bytes *base) );
+_PROTOTYPE( int freemem, (phys_bytes size, phys_bytes base) );
#endif
_PROTOTYPE( int setcache, (int kb));
/* 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
/* 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)
/* 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"
* 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);
/* 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) */
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) */
*/
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 {
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);
/* 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);
_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,
* 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:
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 */
/* 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 */
}
/*===========================================================================*
}
+/*===========================================================================*
+ * 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 *
/* 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);
_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) );
}
-/*===========================================================================*
- * 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
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);
}
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);
}
-/* 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);
-}
-
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 */
all: $(LIBRARY)
OBJECTS = \
+ $(LIBRARY)(_allocmem.o) \
+ $(LIBRARY)(_freemem.o) \
$(LIBRARY)(_brk.o) \
$(LIBRARY)(_reboot.o) \
$(LIBRARY)(_seekdir.o) \
aal cr $@ *.o
rm *.o
+$(LIBRARY)(_allocmem.o): _allocmem.c
+ $(CC1) _allocmem.c
+
+$(LIBRARY)(_freemem.o): _freemem.c
+ $(CC1) _freemem.c
+
$(LIBRARY)(_brk.o): _brk.c
$(CC1) _brk.c
--- /dev/null
+#include <lib.h>
+#define allocmem _allocmem
+#include <unistd.h>
+
+
+PUBLIC int allocmem(size, base)
+phys_bytes size; /* size of mem chunk requested */
+phys_bytes *base; /* return base address */
+{
+ message m;
+ m.m4_l1 = size;
+ if (_syscall(MM, ALLOCMEM, &m) < 0) return(-1);
+ *base = m.m4_l2;
+ return(0);
+}
+
--- /dev/null
+#include <lib.h>
+#define freemem _freemem
+#include <unistd.h>
+
+
+PUBLIC int freemem(size, base)
+phys_bytes size; /* size of mem chunk requested */
+phys_bytes base; /* base address of mem chunk */
+{
+ message m;
+ m.m4_l1 = size;
+ m.m4_l2 = base;
+ if (_syscall(MM, FREEMEM, &m) < 0) return(-1);
+ return(0);
+}
+
$(LIBRARY)(_exit.o) \
$(LIBRARY)(access.o) \
$(LIBRARY)(alarm.o) \
+ $(LIBRARY)(allocmem.o) \
+ $(LIBRARY)(freemem.o) \
$(LIBRARY)(brk.o) \
$(LIBRARY)(cfgetispeed.o) \
$(LIBRARY)(cfgetospeed.o) \
$(LIBRARY)(alarm.o): alarm.s
$(CC1) alarm.s
+$(LIBRARY)(allocmem.o): allocmem.s
+ $(CC1) allocmem.s
+
+$(LIBRARY)(freemem.o): freemem.s
+ $(CC1) freemem.s
+
$(LIBRARY)(brk.o): brk.s
$(CC1) brk.s
--- /dev/null
+.sect .text
+.extern __allocmem
+.define _allocmem
+.align 2
+
+_allocmem:
+ jmp __allocmem
--- /dev/null
+.sect .text
+.extern __freemem
+.define _freemem
+.align 2
+
+_freemem:
+ jmp __freemem
$(LIBSYS)(sys_xit.o) \
$(LIBSYS)(sys_sdevio.o) \
$(LIBSYS)(sys_getinfo.o) \
- $(LIBSYS)(sys_kmalloc.o) \
$(LIBSYS)(sys_irqctl.o) \
$(LIBSYS)(sys_eniop.o) \
$(LIBSYS)(sys_segctl.o) \
$(LIBSYS)(sys_getinfo.o): sys_getinfo.c
$(CC1) sys_getinfo.c
-$(LIBSYS)(sys_kmalloc.o): sys_kmalloc.c
- $(CC1) sys_kmalloc.c
-
$(LIBSYS)(sys_irqctl.o): sys_irqctl.c
$(CC1) sys_irqctl.c
-/* printf() - kernel printf() Author: Kees J. Bot
+/* printf() - system services printf() Author: Kees J. Bot
* 15 Jan 1994
*/
#define nil 0
m.DIAG_PRINT_BUF = print_buf;
m.DIAG_PROC_NR = SELF;
m.m_type = DIAGNOSTICS;
- if (_sendrec(TTY, &m) != 0) {
+ if (_sendrec(IS_PROC_NR, &m) != 0) {
m.m1_i1 = 2;
m.m1_i2 = buf_count;
m.m1_p1 = print_buf;
{
static char value[EP_BUF_SIZE] = "<unknown>";
int s;
- if ((s=sys_getkenv(key, strlen(key), value, sizeof(value))) == 0) {
+ if ((s=get_mon_param(key, value, sizeof(value))) == 0) {
if (s != ESRCH) /* only error allowed */
- printf("WARNING: sys_getkenv() failed in env_panic(): %d\n", s);
+ printf("WARNING: get_mon_param() failed in env_panic(): %d\n", s);
}
printf("Bad environment setting: '%s = %s'\n", key, value);
panic("","", NO_NUM);
if ((s=get_mon_param(env, value, sizeof(value))) != 0) {
if (s == ESRCH) return(EP_UNSET); /* only error allowed */
- printf("WARNING: sys_getkenv() failed in env_parse(): %d\n",s);
+ printf("WARNING: get_mon_param() failed in env_parse(): %d\n",s);
return(EP_EGETKENV);
}
val = value;
int s;
size_t n;
- if ((s = sys_getkenv(env, strlen(env), value, sizeof(value))) != 0) {
+ if ((s = get_mon_param(env, value, sizeof(value))) != 0) {
if (s != ESRCH) /* only error allowed */
- printf("WARNING: sys_getkenv() failed in env_prefix(): %d\n", s);
+ printf("WARNING: get_mon_param() failed in env_prefix(): %d\n", s);
}
n = strlen(prefix);
return(value != NULL
*
* Changes:
* Mar 23, 2005 allow arbitrary partitions as RAM disk (Jorrit N. Herder)
- * Jan 10, 2005 register fkeys with TTY for debug dumps (Jorrit N. Herder)
*/
struct super_block; /* proto.h needs to know this */
if (call_nr == HARD_STOP) {
do_sync();
sys_exit(0); /* never returns */
- } else if (call_nr == FKEY_PRESSED) {
- do_fkey_pressed();
- continue; /* get work again */
}
/* Call the internal function that does the work. */
rfp->fp_workdir = rip;
}
}
-
- /* Register function keys with TTY. */
- for (key=SF5; key<=SF6; key++) {
- if ((i=fkey_enable(key))!=OK) {
- printf("Warning: FS couldn't register Shift+F%d key: %d\n",
- key-SF1+1, i);
- }
- }
}
#define ZERO 0 /* Used to comment out initialization code that does nothing. */
#include <sys/types.h>
+#include <minix/type.h>
#include <errno.h>
#include <stddef.h>
#include <stdlib.h>
#define _MINIX 1
#include <stdlib.h>
-#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <minix/config.h>
#include <minix/type.h>
#include <minix/syslib.h>
+#include <unistd.h>
#include "inet_config.h"
#define CRAMPED (_EM_WSIZE==2) /* 64K code and data is quite cramped. */
* down.
*/
+#include <minix/type.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
*===========================================================================*/
PUBLIC int do_fkey_pressed(message *m)
{
-#if DEAD_CODE
- if (F1 <= m->FKEY_CODE && m->FKEY_CODE <= F12) {
- switch(m->FKEY_CODE) {
-#else
if (F1 <= m->NOTIFY_ARG && m->NOTIFY_ARG <= F12) {
switch(m->NOTIFY_ARG) {
-#endif
case F1: proctab_dmp(); break;
case F2: memmap_dmp(); break;
case F3: image_dmp(); break;
case F11: memchunks_dmp(); break;
case F12: sched_dmp(); break;
default:
-#if DEAD_CODE
- printf("IS: unhandled notification for F%d\n", m->FKEY_NUM);
-#else
printf("IS: unhandled notify for F%d (code %d)\n",
m->NOTIFY_FLAGS, m->NOTIFY_ARG);
-#endif
+ }
+ }
+ if (SF1 <= m->NOTIFY_ARG && m->NOTIFY_ARG <= SF12) {
+ switch(m->NOTIFY_ARG) {
+ default:
+ printf("IS: unhandled notify for Shift-F%d (code %d)\n",
+ m->NOTIFY_FLAGS, m->NOTIFY_ARG);
}
}
return(EDONTREPLY);
printf("- bootdev_size: %5u\n", kinfo.bootdev_size);
printf("- params_base: %5u\n", kinfo.params_base);
printf("- params_size: %5u\n", kinfo.params_size);
- printf("- notify_pending:%8u\n", kinfo.nr_ntf_pending);
- printf("- lock_notify: %6u\n", kinfo.lock_notify);
- printf("- lock_send: %6u\n", kinfo.lock_send);
printf("- nr_procs: %3u\n", kinfo.nr_procs);
printf("- nr_tasks: %3u\n", kinfo.nr_tasks);
printf("- version: %.6s\n", kinfo.version);
(key-F1+1), r);
}
}
+ for (key=SF1; key<=SF12; key++) {
+ if ((r=fkey_enable(key)) != OK) {
+ printf("IS: WARNING: couldn't register SF%d key: %d\n",
+ (key-SF1+1), r);
+ }
+ }
/* Display status message ... */
printf("IS: information service is alive and kicking; press F1-F12 for dumps\n");
PRIVATE phys_clicks swap_maxsize;/* maximum amount of swap "memory" possible */
PRIVATE struct mproc *in_queue; /* queue of processes wanting to swap in */
PRIVATE struct mproc *outswap = &mproc[0]; /* outswap candidate? */
-#else /* !SWAP */
+#else /* ! ENABLE_SWAP */
#define swap_base ((phys_clicks) -1)
-#endif /* !SWAP */
+#endif /* ENABLE_SWAP */
FORWARD _PROTOTYPE( void del_slot, (struct hole *prev_ptr, struct hole *hp) );
FORWARD _PROTOTYPE( void merge, (struct hole *hp) );
* always on a click boundary. This procedure is called when memory is
* needed for FORK or EXEC. Swap other processes out if needed.
*/
-
register struct hole *hp, *prev_ptr;
phys_clicks old_base;
* to the hole list. If it is contiguous with an existing hole on either end,
* it is merged with the hole or holes.
*/
-
register struct hole *hp, *new_ptr, *prev_ptr;
if (clicks == 0) return;
* the numbers of holes in memory, and requiring the elimination of one
* entry in the hole list.
*/
-
if (hp == hole_head)
hole_head = hp->h_next;
else
* either or both ends. The pointer 'hp' points to the first of a series of
* three holes that can potentially all be merged together.
*/
-
register struct hole *next_ptr;
/* If 'hp' points to the last hole, no merging is possible. If it does not,
/* Ask the kernel for chunks of physical memory and allocate holes. */
*free = 0;
- for (i=0; i<NR_MEMS; i++) {
+ for (i=NR_MEMS-1; i>=0; i--) {
if (mem[i].size > 0) {
free_mem(mem[i].base, mem[i].size);
*free += mem[i].size;
check_sig(-1, SIGKILL); /* kill all processes */
sys_exit(0);
/* never reached */
- } else if (call_nr == FKEY_PRESSED) { /* create debug dump */
- (void) do_fkey_pressed();
- result = SUSPEND; /* don't reply */
} else if (call_nr == KSIG_PENDING) { /* signals pending */
(void) ksig_pending();
result = SUSPEND; /* don't reply */
printf("System services=%uK ", click_to_round_k(minix_clicks));
printf("Available=%uK\n\n", click_to_round_k(free_clicks));
- /* Register function keys with TTY for debug dumps. */
- for (key=SF7; key<=SF8; key++) {
- if ((i=fkey_enable(key))!=OK) {
- printf("Warning: PM couldn't register Shift+F%d key: %d\n",
- key-SF1+1, i);
- }
- }
}
/* PM gets a copy of all boot monitor parameters. */
PRIVATE char monitor_params[128*sizeof(char *)];
-/*=====================================================================*
- * do_memalloc *
- *=====================================================================*/
-PUBLIC int do_memalloc()
+/*===========================================================================*
+ * do_allocmem *
+ *===========================================================================*/
+PUBLIC int do_allocmem()
{
vir_clicks mem_clicks;
phys_clicks mem_base;
- printf("PM got request to allocate %u KB\n", m_in.memsize);
mem_clicks = (m_in.memsize + CLICK_SIZE -1 ) >> CLICK_SHIFT;
mem_base = alloc_mem(mem_clicks);
return(OK);
}
-/*=====================================================================*
- * do_memfree *
- *=====================================================================*/
-PUBLIC int do_memfree()
+/*===========================================================================*
+ * do_freemem *
+ *===========================================================================*/
+PUBLIC int do_freemem()
{
+ vir_clicks mem_clicks;
+ phys_clicks mem_base;
+
+ mem_clicks = (m_in.memsize + CLICK_SIZE -1 ) >> CLICK_SHIFT;
+ mem_base = (m_in.membase + CLICK_SIZE -1 ) >> CLICK_SHIFT;
+ free_mem(mem_base, mem_clicks);
return(OK);
}
_PROTOTYPE( int do_getsysinfo, (void) );
_PROTOTYPE( int do_getprocnr, (void) );
_PROTOTYPE( int do_svrctl, (void) );
-_PROTOTYPE( int do_memalloc, (void) );
-_PROTOTYPE( int do_memfree, (void) );
+_PROTOTYPE( int do_allocmem, (void) );
+_PROTOTYPE( int do_freemem, (void) );
_PROTOTYPE( int do_mstats, (void) );
#if (MACHINE == MACINTOSH)
do_getprocnr, /* 80 = getprocnr */
no_sys, /* 81 = unused */
no_sys, /* 82 = fstatfs */
- do_memalloc, /* 83 = memalloc */
- do_memfree, /* 84 = memfree */
+ do_allocmem, /* 83 = memalloc */
+ do_freemem, /* 84 = memfree */
};
/* This should not fail with "array size is negative": */
extern int dummy[sizeof(call_vec) == NCALLS * sizeof(call_vec[0]) ? 1 : -1];