#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/ioc_cmos.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
int dec_to_bcd(int n);
void usage(void);
+#define CMOS_DEV "/dev/cmos"
+
PUBLIC int main(int argc, char **argv)
{
+ int fd;
struct tm time1;
struct tm time2;
struct tm tmnow;
unsigned char mach_id, cmos_state;
struct sysgetenv sysgetenv;
message m;
+ int request;
/* Process options. */
/* sleep, unless first iteration */
if (i > 0) sleep(5);
- /* get_time(&time1); */
- m.m_type = CMOSTIME;
- m.ADDRESS = (void *) &time1;
- m.REQUEST = y2kflag;
- if (0 != (s=sendrec(FS_PROC_NR, &m))) {
- fprintf(stderr, "Couldn't get CMOS time from FS: %d.\n",s);
+ /* Open the CMOS device to read the system time. */
+ if ((fd = open(CMOS_DEV, O_RDONLY)) < 0) {
+ fprintf(stderr, "Couldn't open CMOS device: %d.\n",s);
+ exit(1);
+ }
+ request = (y2kflag) ? CIOCGETTIME : CIOCGETTIMEY2K;
+ if ((s=ioctl(fd, request, (void *) &time1)) < 0) {
+ fprintf(stderr, "Couldn't do CMOS ioctl: %d.\n",s);
exit(1);
}
+ close(fd);
now = time(NULL);
time2 = time1;
rtc= mktime(&time1); /* Transform to a time_t. */
- if (rtc != -1) break;
+ if (rtc != -1) {
+ break;
+ }
fprintf(stderr,
"readclock: Invalid time read from CMOS RTC: %d-%02d-%02d %02d:%02d:%02d\n",
}
if (i >= MAX_RETRIES) exit(1);
- /* Set system time. */
+ /* Now set system time. */
if (nflag) {
printf("stime(%lu)\n", (unsigned long) rtc);
} else {
cd ./dpeth && $(MAKE) $@
cd ./log && $(MAKE) $@
cd ./bios_wini && $(MAKE) $@
+ cd ./cmos && $(MAKE) $@
cd ./random && $(MAKE) $@
return(ENXIO);
}
+#if VERBOSE
printf("%s: AT driver detected ", w_name());
if (wn->state & (SMART|ATAPI)) {
printf("%.40s\n", w_id_string);
} else {
printf("%ux%ux%u\n", wn->pcylinders, wn->pheads, wn->psectors);
}
+#endif
}
/* Partition the drive if it's being opened for the first time,
--- /dev/null
+# Makefile for the CMOS driver
+DRIVER = cmos
+
+# directories
+u = /usr
+i = $u/include
+s = $i/sys
+m = $i/minix
+b = $i/ibm
+d = ..
+
+# programs, flags, etc.
+MAKE = exec make
+CC = exec cc
+CFLAGS = -I$i
+LDFLAGS = -i
+LIBS = -lsys -lsysutil
+
+OBJ = cmos.o
+LIBDRIVER = $d/libdriver/driver.o
+
+
+# build local binary
+all build: $(DRIVER)
+$(DRIVER): $(OBJ) $(LIBDRIVER) readclock.o
+ $(CC) -o $@ $(LDFLAGS) $(OBJ) $(LIBDRIVER) $(LIBS)
+ install -S 1024w $(DRIVER)
+ $(CC) -o readclock readclock.c
+
+$(LIBDRIVER):
+ cd $d/libdriver && $(MAKE)
+
+
+# install with other drivers
+install: /sbin/$(DRIVER)
+/sbin/$(DRIVER): $(DRIVER)
+ install -o root -cs $? $@
+
+# clean up local files
+clean:
+ rm -f $(DRIVER) *.o *.bak
+
+
+depend:
+ /usr/bin/mkdep "$(CC) -E $(CPPFLAGS)" *.c ../libdriver/*.c > .depend
+
+# Include generated dependencies.
+include .depend
+
-#include "fs.h"
-#include <minix/com.h>
-#include <minix/callnr.h>
-#include <time.h>
-#include <ibm/cmos.h>
-#include <ibm/bios.h>
-
-
-/* Manufacturers usually use the ID value of the IBM model they emulate.
+/* This file contains a device driver that can access the CMOS chip to
+ * get or set the system time. It drives the special file:
+ *
+ * /dev/cmos - CMOS chip
+ *
+ * Changes:
+ * Aug 04, 2005 Created. Read CMOS time. (Jorrit N. Herder)
+ *
+ * Manufacturers usually use the ID value of the IBM model they emulate.
* However some manufacturers, notably HP and COMPAQ, have had different
* ideas in the past.
*
* published by Microsoft Press
*/
+#include "../drivers.h"
+#include <sys/ioc_cmos.h>
+#include <time.h>
+#include <ibm/cmos.h>
+#include <ibm/bios.h>
+
+extern int errno; /* error number for PM calls */
+
+FORWARD _PROTOTYPE( int gettime, (int who, int y2kflag, vir_bytes dst_time));
+FORWARD _PROTOTYPE( void reply, (int reply, int replyee, int proc, int s));
+
FORWARD _PROTOTYPE( int read_register, (int register_address));
FORWARD _PROTOTYPE( int get_cmostime, (struct tm *tmp, int y2kflag));
FORWARD _PROTOTYPE( int dec_to_bcd, (int dec));
FORWARD _PROTOTYPE( int bcd_to_dec, (int bcd));
+/*===========================================================================*
+ * main *
+ *===========================================================================*/
+PUBLIC void main(void)
+{
+ message m;
+ int y2kflag;
+ int result;
+ int suspended = NONE;
+ int s;
+
+ while(TRUE) {
+
+ /* Get work. */
+ if (OK != (s=receive(ANY, &m)))
+ panic("CMOS", "attempt to receive work failed", s);
+
+ /* Handle request. */
+ switch(m.m_type) {
+
+ case DEV_OPEN:
+ case DEV_CLOSE:
+ case CANCEL:
+ reply(TASK_REPLY, m.m_source, m.PROC_NR, OK);
+ break;
+
+ case DEV_IOCTL:
+
+ /* Probably best to SUSPEND the caller, CMOS I/O has nasty timeouts.
+ * This way we don't block the rest of the system. First check if
+ * another process is already suspended. We cannot handle multiple
+ * requests at a time.
+ */
+ if (suspended != NONE) {
+ reply(TASK_REPLY, m.m_source, m.PROC_NR, EBUSY);
+ break;
+ }
+ suspended = m.PROC_NR;
+ reply(TASK_REPLY, m.m_source, m.PROC_NR, SUSPEND);
+
+ switch(m.REQUEST) {
+ case CIOCGETTIME: /* get CMOS time */
+ case CIOCGETTIMEY2K:
+ y2kflag = (m.REQUEST = CIOCGETTIME) ? 0 : 1;
+ result = gettime(m.PROC_NR, y2kflag, (vir_bytes) m.ADDRESS);
+ break;
+ case CIOCSETTIME:
+ case CIOCSETTIMEY2K:
+ default: /* unsupported ioctl */
+ result = ENOSYS;
+ }
+
+ /* Request completed. Tell the caller to check our status. */
+ notify(m.m_source);
+ break;
+
+ case DEV_STATUS:
+
+ /* The FS calls back to get our status. Revive the suspended
+ * processes and return the status of reading the CMOS.
+ */
+ if (suspended == NONE)
+ reply(DEV_NO_STATUS, m.m_source, NONE, OK);
+ else
+ reply(DEV_REVIVE, m.m_source, suspended, result);
+ suspended = NONE;
+ break;
+
+ case SYN_ALARM: /* shouldn't happen */
+ case SYS_SIG: /* ignore system events */
+ continue;
+
+ default:
+ reply(TASK_REPLY, m.m_source, m.PROC_NR, EINVAL);
+ }
+ }
+}
+
+
+/*===========================================================================*
+ * reply *
+ *===========================================================================*/
+PRIVATE void reply(int code, int replyee, int process, int status)
+{
+ message m;
+ int s;
+
+ m.m_type = code; /* TASK_REPLY or REVIVE */
+ m.REP_STATUS = status; /* result of device operation */
+ m.REP_PROC_NR = process; /* which user made the request */
+ if (OK != (s=send(replyee, &m)))
+ panic("CMOS", "sending reply failed", s);
+}
+
-PUBLIC int do_cmostime(void)
+/*===========================================================================*
+ * gettime *
+ *===========================================================================*/
+PRIVATE int gettime(int who, int y2kflag, vir_bytes dst_time)
{
unsigned char mach_id, cmos_state;
struct tm time1;
int i, s;
- int y2kflag = m_in.REQUEST;
- vir_bytes dst_time = (vir_bytes) m_in.ADDRESS;
/* First obtain the machine ID to see if we can read the CMOS clock. Only
* for PS_386 and PC_AT this is possible. Otherwise, return an error.
$(LIBDRIVER):
cd $d/libdriver && $(MAKE)
-aes/rijndael_api.o:
- $(CC) -c -o $@ aes/rijndael_api.c
-
-aes/rijndael_alg.o:
- $(CC) -c -o $@ aes/rijndael_alg.c
# install with other drivers
install: /usr/sbin/$(DRIVER)
*
* Changes:
* Apr 29, 2005 added null byte generator (Jorrit N. Herder)
- * Apr 27, 2005 added random device handling (Jorrit N. Herder)
* Apr 09, 2005 added support for boot device (Jorrit N. Herder)
* Jul 26, 2004 moved RAM driver to user-space (Jorrit N. Herder)
* Apr 20, 1992 device dependent/independent split (Kees J. Bot)
* is updated automatically later.
*/
scroll_screen(cons, SCROLL_UP);
- cons->c_row = scr_lines-1;
+ cons->c_row = scr_lines - 1;
cons->c_column = 0;
}
select_console(0);
panic("TTY","Couldn't obtain kernel environment.", s);
}
+printf("\n");
while (TRUE) {
/* Check for and handle any events on any of the ttys. */
exec intr sh
}
+up()
+{
+ service=$1
+ args=$2
+ device=$3
+
+ # Function to dynamically start a system service
+ command="/sbin/$service"
+ if [ ! -z "$args" ]; then command="$command -args \"$args\""; fi
+ if [ ! -z "$device" ]; then command="$command -dev \"$device\""; fi
+ echo -n " $service"
+ eval service up $command
+}
+
while getopts 'saf' opt
do
case $opt in
# National keyboard?
test -f /etc/keymap && loadkeys /etc/keymap
+ # Start crucial system services
+ echo -n "Starting services:"
+ up is ""
+ up cmos "" /dev/cmos
+ echo .
+
# Set timezone.
. /etc/profile
rm -rf /tmp/. /usr/run/. /usr/spool/lpd/. /usr/spool/locks/.
# Start servers and drivers set at the boot monitor.
- echo -n "Starting services:"
+ echo -n "More services:"
up random "" /dev/random
# load random number generator
fi
done
up inet ""
- up is ""
up printer "" /dev/lp
# up floppy "" /dev/fd0
echo .
/* MINIX specific calls, e.g., to support system services. */
#define SVRCTL 77
-#define CMOSTIME 78 /* to FS */
+ /* unused */
#define GETSYSINFO 79 /* to PM or FS */
#define GETPROCNR 80 /* to PM */
#define DEVCTL 81 /* to FS */
* Messages for networking layer *
*===========================================================================*/
-/* Message types for network layer requests. */
+/* Message types for network layer requests. This layer acts like a driver. */
#define NW_OPEN DEV_OPEN
#define NW_CLOSE DEV_CLOSE
#define NW_READ DEV_READ
#define NW_IOCTL DEV_IOCTL
#define NW_CANCEL CANCEL
+/* Base type for data link layer requests and responses. */
+#define DL_RQ_BASE 0x800
+#define DL_RS_BASE 0x900
+
/* Message types for data link layer requests. */
-#define DL_WRITE 3
-#define DL_WRITEV 4
-#define DL_READ 5
-#define DL_READV 6
-#define DL_INIT 7
-#define DL_STOP 8
-#define DL_GETSTAT 9
+#define DL_WRITE (DL_RQ_BASE + 3)
+#define DL_WRITEV (DL_RQ_BASE + 4)
+#define DL_READ (DL_RQ_BASE + 5)
+#define DL_READV (DL_RQ_BASE + 6)
+#define DL_INIT (DL_RQ_BASE + 7)
+#define DL_STOP (DL_RQ_BASE + 8)
+#define DL_GETSTAT (DL_RQ_BASE + 9)
/* Message type for data link layer replies. */
-#define DL_INIT_REPLY 20
-#define DL_TASK_REPLY 21
+#define DL_INIT_REPLY (DL_RS_BASE + 20)
+#define DL_TASK_REPLY (DL_RS_BASE + 21)
/* Field names for data link layer messages. */
#define DL_PORT m2_i1
*/
#define KERNEL_CALL 0x600 /* base for kernel calls to SYSTEM */
-# define SYS_TIMES (KERNEL_CALL + 0) /* sys_times() */
-# define SYS_EXIT (KERNEL_CALL + 1) /* sys_exit() */
-# define SYS_GETKSIG (KERNEL_CALL + 2) /* sys_getsig() */
-# define SYS_ENDKSIG (KERNEL_CALL + 3) /* sys_endsig() */
-# define SYS_FORK (KERNEL_CALL + 4) /* sys_fork() */
-# define SYS_NEWMAP (KERNEL_CALL + 5) /* sys_newmap() */
-
-# define SYS_EXEC (KERNEL_CALL + 7) /* sys_exec() */
-# define SYS_SIGSEND (KERNEL_CALL + 8) /* sys_sigsend() */
-# define SYS_ABORT (KERNEL_CALL + 9) /* sys_abort() */
-# define SYS_KILL (KERNEL_CALL + 10) /* sys_kill() */
-# define SYS_UMAP (KERNEL_CALL + 11) /* sys_umap() */
+# define SYS_FORK (KERNEL_CALL + 0) /* sys_fork() */
+# define SYS_EXEC (KERNEL_CALL + 1) /* sys_exec() */
+# define SYS_EXIT (KERNEL_CALL + 2) /* sys_exit() */
+# define SYS_NICE (KERNEL_CALL + 3) /* sys_nice() */
+# define SYS_PRIVCTL (KERNEL_CALL + 4) /* sys_privctl() */
+# define SYS_TRACE (KERNEL_CALL + 5) /* sys_trace() */
+# define SYS_KILL (KERNEL_CALL + 6) /* sys_kill() */
+
+# define SYS_GETKSIG (KERNEL_CALL + 7) /* sys_getsig() */
+# define SYS_ENDKSIG (KERNEL_CALL + 8) /* sys_endsig() */
+# define SYS_SIGSEND (KERNEL_CALL + 9) /* sys_sigsend() */
+# define SYS_SIGRETURN (KERNEL_CALL + 10) /* sys_sigreturn() */
+
+# define SYS_NEWMAP (KERNEL_CALL + 11) /* sys_newmap() */
+# define SYS_SEGCTL (KERNEL_CALL + 12) /* sys_segctl() */
+# define SYS_MEMSET (KERNEL_CALL + 13) /* sys_memset() */
+
+# define SYS_UMAP (KERNEL_CALL + 14) /* sys_umap() */
+# define SYS_VIRCOPY (KERNEL_CALL + 15) /* sys_vircopy() */
+# define SYS_PHYSCOPY (KERNEL_CALL + 16) /* sys_physcopy() */
+# define SYS_VIRVCOPY (KERNEL_CALL + 17) /* sys_virvcopy() */
+# define SYS_PHYSVCOPY (KERNEL_CALL + 18) /* sys_physvcopy() */
-# define SYS_TRACE (KERNEL_CALL + 13) /* sys_trace() */
+# define SYS_IRQCTL (KERNEL_CALL + 19) /* sys_irqctl() */
+# define SYS_INT86 (KERNEL_CALL + 20) /* sys_int86() */
+# define SYS_DEVIO (KERNEL_CALL + 21) /* sys_devio() */
+# define SYS_SDEVIO (KERNEL_CALL + 22) /* sys_sdevio() */
+# define SYS_VDEVIO (KERNEL_CALL + 23) /* sys_vdevio() */
-# define SYS_SETALARM (KERNEL_CALL + 16) /* sys_setalarm() */
+# define SYS_SETALARM (KERNEL_CALL + 24) /* sys_setalarm() */
+# define SYS_TIMES (KERNEL_CALL + 25) /* sys_times() */
+# define SYS_GETINFO (KERNEL_CALL + 26) /* sys_getinfo() */
+# define SYS_ABORT (KERNEL_CALL + 27) /* sys_abort() */
-# define SYS_PHYSVCOPY (KERNEL_CALL + 18) /* sys_physvcopy() */
-# define SYS_PRIVCTL (KERNEL_CALL + 19) /* sys_privctl() */
-# define SYS_SDEVIO (KERNEL_CALL + 20) /* sys_sdevio() */
-# define SYS_SIGRETURN (KERNEL_CALL + 21) /* sys_sigreturn() */
-# define SYS_GETINFO (KERNEL_CALL + 22) /* sys_getinfo() */
-# define SYS_DEVIO (KERNEL_CALL + 23) /* sys_devio() */
-# define SYS_VDEVIO (KERNEL_CALL + 24) /* sys_vdevio() */
-# define SYS_IRQCTL (KERNEL_CALL + 25) /* sys_irqctl() */
-
-# define SYS_SEGCTL (KERNEL_CALL + 28) /* sys_segctl() */
-
-# define SYS_VIRCOPY (KERNEL_CALL + 30) /* sys_vircopy() */
-# define SYS_PHYSCOPY (KERNEL_CALL + 31) /* sys_physcopy() */
-# define SYS_VIRVCOPY (KERNEL_CALL + 32) /* sys_virvcopy() */
-# define SYS_MEMSET (KERNEL_CALL + 33) /* sys_memset() */
-# define SYS_NICE (KERNEL_CALL + 34) /* sys_nice() */
-# define SYS_INT86 (KERNEL_CALL + 35) /* sys_int86() */
-#define NR_SYS_CALLS 36 /* number of system calls */
+#define NR_SYS_CALLS 28 /* number of system calls */
/* Field names for SYS_MEMSET, SYS_SEGCTL. */
#define MEM_PTR m2_p1 /* base */
--- /dev/null
+/* sys/ioc_cmos.h - CMOS ioctl() command codes.
+ */
+
+#ifndef _S_I_CMOS_H
+#define _S_I_CMOS_H
+
+#include <minix/ioctl.h>
+
+#define CIOCGETTIME _IOR('c', 1, u32_t)
+#define CIOCGETTIMEY2K _IOR('c', 2, u32_t)
+#define CIOCSETTIME _IOW('c', 3, u32_t)
+#define CIOCSETTIMEY2K _IOW('c', 4, u32_t)
+
+#endif /* _S_I_CMOS_H */
+
#include <sys/ioc_disk.h> /* 'd' */
#include <sys/ioc_file.h> /* 'f' */
#include <sys/ioc_memory.h> /* 'm' */
+#include <sys/ioc_cmos.h> /* 'c' */
#include <sys/ioc_tape.h> /* 'M' */
#include <sys/ioc_scsi.h> /* 'S' */
#include <sys/ioc_sound.h> /* 's' */
*/
#define vir2phys(vir) (kinfo.data_base + (vir_bytes) (vir))
-/* Map a process number to a privilege structure id. Used at boot time. */
+/* Map a process number to a privilege structure id. */
#define s_nr_to_id(n) (NR_TASKS + (n) + 1)
-#define s(n) (1 << s_nr_to_id(n))
/* Translate a pointer to a field in a structure to a pointer to the structure
* itself. So it translates '&struct_ptr->field' back to 'struct_ptr'.
strncpy(rp->p_name, ip->proc_name, P_NAME_LEN); /* set process name */
(void) get_priv(rp, (ip->flags & SYS_PROC)); /* assign structure */
priv(rp)->s_flags = ip->flags; /* process flags */
- priv(rp)->s_call_mask = ip->call_mask; /* allowed traps */
- priv(rp)->s_send_mask.chunk[0] = ip->send_mask; /* restrict targets */
+ priv(rp)->s_trap_mask = ip->trap_mask; /* allowed traps */
+ priv(rp)->s_call_mask = ip->call_mask; /* kernel call mask */
+ priv(rp)->s_ipc_to.chunk[0] = ip->ipc_to; /* restrict targets */
if (iskerneln(proc_nr(rp))) { /* part of the kernel? */
if (ip->stksize > 0) { /* HARDWARE stack size is 0 */
rp->p_priv->s_stack_guard = (reg_t *) ktsb;
sys_id_t s_id; /* index of this system structure */
short s_flags; /* PREEMTIBLE, BILLABLE, etc. */
- short s_call_mask; /* allowed system call traps */
- sys_map_t s_send_mask; /* allowed send destinations */
- long s_sys_mask; /* allowed kernel calls */
+ short s_trap_mask; /* allowed system call traps */
+ sys_map_t s_ipc_from; /* allowed callers to receive from */
+ sys_map_t s_ipc_to; /* allowed destination processes */
+ long s_call_mask; /* allowed kernel calls */
sys_map_t s_notify_pending; /* bit map with pending notifications */
irq_id_t s_int_pending; /* pending hardware interrupts */
* kernel may only be SENDREC, because tasks always reply and may not block
* if the caller doesn't do receive().
*/
- if (! (priv(caller_ptr)->s_call_mask & (1 << function)) ||
+ if (! (priv(caller_ptr)->s_trap_mask & (1 << function)) ||
(iskerneln(src_dst) && function != SENDREC))
return(ECALLDENIED);
* that the destination is still alive.
*/
if (function & CHECK_DST) {
- if (! get_sys_bit(priv(caller_ptr)->s_send_mask, nr_to_id(src_dst))) {
+ if (! get_sys_bit(priv(caller_ptr)->s_ipc_to, nr_to_id(src_dst))) {
kprintf("Warning, send_mask denied %d sending to %d\n",
proc_nr(caller_ptr), src_dst);
return(ECALLDENIED);
*
* Changes:
* 2004 to 2005 many new system calls (see system.h) (Jorrit N. Herder)
+ * Aug 04, 2005 check if kernel call is allowed (Jorrit N. Herder)
* Jul 20, 2005 send signal to services with message (Jorrit N. Herder)
* Jan 15, 2005 new, generalized virtual copy function (Jorrit N. Herder)
* Oct 10, 2004 dispatch system calls from call vector (Jorrit N. Herder)
/* Main entry point of sys_task. Get the message and dispatch on type. */
static message m;
register int result;
- unsigned int call;
+ register struct proc *caller_ptr;
+ unsigned int call_nr;
+ int s;
/* Initialize the system task. */
initialize();
while (TRUE) {
- /* Get work. */
- receive(ANY, &m);
-
- /* Handle the request. */
- call = (unsigned) m.m_type - KERNEL_CALL; /* substract offset */
- if (call < NR_SYS_CALLS) { /* check call number */
- result = (*call_vec[call])(&m); /* handle the kernel call */
- } else {
- kprintf("Warning, illegal SYSTASK request from %d.\n", m.m_source);
+ /* Get work. Block and wait until a request message arrives. */
+ receive(ANY, &m);
+ call_nr = (unsigned) m.m_type - KERNEL_CALL;
+ caller_ptr = proc_addr(m.m_source);
+
+ /* See if the caller made a valid request and try to handle it. */
+ if (! (priv(caller_ptr)->s_call_mask & (1<<call_nr))) {
+ kprintf("SYSTEM: request %d from %d denied.\n", call_nr,m.m_source);
+ result = ECALLDENIED; /* illegal message type */
+ }
+ if (call_nr >= NR_SYS_CALLS) { /* check call number */
+ kprintf("SYSTEM: illegal request %d from %d.\n", call_nr,m.m_source);
result = EBADREQUEST; /* illegal message type */
+ }
+ else {
+ result = (*call_vec[call_nr])(&m); /* handle the kernel call */
}
/* Send a reply, unless inhibited by a handler function. Use the kernel
*/
if (result != EDONTREPLY) {
m.m_type = result; /* report status of call */
- if (OK != lock_send(m.m_source, &m)) {
- kprintf("Warning, SYSTASK couldn't reply to request from %d.\n",
- m.m_source);
+ if (OK != (s=lock_send(m.m_source, &m))) {
+ kprintf("SYSTEM, reply to %d failed: %d\n", m.m_source, s);
}
}
}
sigemptyset(&priv(rp)->s_sig_pending); /* - signals */
/* Now update the process' privileges as requested. */
- rp->p_priv->s_call_mask = FILLED_MASK;
+ rp->p_priv->s_trap_mask = FILLED_MASK;
for (i=0; i<BITMAP_CHUNKS(NR_SYS_PROCS); i++) {
- rp->p_priv->s_send_mask.chunk[i] = FILLED_MASK;
+ rp->p_priv->s_ipc_to.chunk[i] = FILLED_MASK;
}
- unset_sys_bit(rp->p_priv->s_send_mask, USER_PRIV_ID);
+ unset_sys_bit(rp->p_priv->s_ipc_to, USER_PRIV_ID);
/* All process that this process can send to must be able to reply.
* Therefore, their send masks should be updated as well.
*/
for (i=0; i<NR_SYS_PROCS; i++) {
- if (get_sys_bit(rp->p_priv->s_send_mask, i)) {
- set_sys_bit(priv_addr(i)->s_send_mask, priv_id(rp));
+ if (get_sys_bit(rp->p_priv->s_ipc_to, i)) {
+ set_sys_bit(priv_addr(i)->s_ipc_to, priv_id(rp));
}
}
* include 'boot_image' (this file) and 'idt' and 'gdt' (protect.c).
*
* Changes:
- * Aug 02, 2005 minimal boot image and cleanup (Jorrit N. Herder)
+ * Aug 02, 2005 set privileges and minimal boot image (Jorrit N. Herder)
* Oct 17, 2004 updated above and tasktab comments (Jorrit N. Herder)
* May 01, 2004 changed struct for system image (Jorrit N. Herder)
*/
/* Define flags for the various process types. */
#define IDL_F (BILLABLE | SYS_PROC) /* idle task */
#define TSK_F (SYS_PROC) /* kernel tasks */
-#define SRV_F (PREEMPTIBLE | SYS_PROC) /* system services */
+#define SRV_F (BILLABLE | PREEMPTIBLE | SYS_PROC) /* system services */
#define USR_F (PREEMPTIBLE | BILLABLE) /* user processes */
/* Define system call traps for the various process types. These call masks
* processes in the boot image, so that the send mask that is defined here
* can be directly copied onto map[0] of the actual send mask. Privilege
* structure 0 is shared by user processes.
- *
- * Note that process numbers in the boot image should not be higher than
- * "BITCHUNK_BITS - NR_TASKS", because a bitchunk_t field is used to store
- * the send masks in the table that describes that processes in the image.
*/
+#define s(n) (1 << s_nr_to_id(n))
#define SRV_M (~0)
#define SYS_M (~0)
-#define USR_M (s(PM_PROC_NR)|s(FS_PROC_NR)|s(SM_PROC_NR))
-#define DRV_M (USR_M | s(SYSTEM)|s(CLOCK)|s(LOG_PROC_NR)|s(TTY_PROC_NR))
-
-/* Sanity check to make sure the send masks can be set. */
-extern int dummy[(BITCHUNK_BITS-NR_TASKS > INIT_PROC_NR) ? 1 : -1];
+#define USR_M (s(PM_PROC_NR) | s(FS_PROC_NR) | s(SM_PROC_NR))
+#define DRV_M (USR_M | s(SYSTEM) | s(CLOCK) | s(LOG_PROC_NR) | s(TTY_PROC_NR))
+/* Define kernel calls that processes are allowed to make. This is not looking
+ * very nice, but we really need to set access rights on a per call basis.
+ * Note that the system services manager has all bits on, because it should
+ * be allowed to distribute rights to services that it starts.
+ */
+#define c(n) (1 << ((n)-KERNEL_CALL))
+#define SM_C ~0
+#define PM_C ~(c(SYS_DEVIO) | c(SYS_SDEVIO) | c(SYS_VDEVIO) \
+ | c(SYS_IRQCTL) | c(SYS_INT86))
+#define FS_C (c(SYS_KILL) | c(SYS_VIRCOPY) | c(SYS_VIRVCOPY) | c(SYS_UMAP) \
+ | c(SYS_GETINFO) | c(SYS_EXIT) | c(SYS_TIMES) | c(SYS_SETALARM))
+#define DRV_C (FS_C | c(SYS_SEGCTL) | c(SYS_IRQCTL) | c(SYS_INT86) \
+ | c(SYS_DEVIO) | c(SYS_VDEVIO) | c(SYS_SDEVIO))
/* The system image table lists all programs that are part of the boot image.
* The order of the entries here MUST agree with the order of the programs
* initial program counter and stack size is also provided for kernel tasks.
*/
PUBLIC struct boot_image image[] = {
-/* process nr, pc, flags, qs, queue, stack, traps, ipc, sys, name */
- { IDLE, idle_task, IDL_F, 32, IDLE_Q, IDL_S, 0, 0, 0, "IDLE" },
- { CLOCK,clock_task, TSK_F, 0, TASK_Q, TSK_S, TSK_T, 0, 0, "CLOCK" },
- { SYSTEM, sys_task, TSK_F, 0, TASK_Q, TSK_S, TSK_T, 0, 0, "SYSTEM" },
- { HARDWARE, 0, TSK_F, 0, TASK_Q, HRD_S, 0, 0, 0, "KERNEL" },
- { PM_PROC_NR, 0, SRV_F, 16, 3, 0, SRV_T, SRV_M, ~0, "pm" },
- { FS_PROC_NR, 0, SRV_F, 16, 4, 0, SRV_T, SRV_M, ~0, "fs" },
- { SM_PROC_NR, 0, SRV_F, 16, 3, 0, SRV_T, SYS_M, ~0, "sm" },
- { TTY_PROC_NR, 0, SRV_F, 16, 1, 0, SRV_T, SYS_M, ~0, "tty" },
- { MEM_PROC_NR, 0, SRV_F, 16, 2, 0, SRV_T, DRV_M, ~0, "memory" },
- { LOG_PROC_NR, 0, SRV_F, 16, 2, 0, SRV_T, SYS_M, ~0, "log" },
- { DRVR_PROC_NR, 0, SRV_F, 16, 2, 0, SRV_T, DRV_M, ~0, "driver" },
- { INIT_PROC_NR, 0, USR_F, 8, USER_Q, 0, USR_T, USR_M, 0, "init" },
+/* process nr, pc, flags, qs, queue, stack, traps, ipcto, call, name */
+ { IDLE, idle_task, IDL_F, 32, IDLE_Q, IDL_S, 0, 0, 0, "IDLE" },
+ { CLOCK,clock_task, TSK_F, 0, TASK_Q, TSK_S, TSK_T, 0, 0, "CLOCK" },
+ { SYSTEM, sys_task, TSK_F, 0, TASK_Q, TSK_S, TSK_T, 0, 0, "SYSTEM"},
+ { HARDWARE, 0, TSK_F, 0, TASK_Q, HRD_S, 0, 0, 0, "KERNEL"},
+ { PM_PROC_NR, 0, SRV_F, 16, 3, 0, SRV_T, SRV_M, PM_C, "pm" },
+ { FS_PROC_NR, 0, SRV_F, 16, 4, 0, SRV_T, SRV_M, FS_C, "fs" },
+ { SM_PROC_NR, 0, SRV_F, 16, 3, 0, SRV_T, SYS_M, SM_C, "sm" },
+ { TTY_PROC_NR, 0, SRV_F, 16, 1, 0, SRV_T, SYS_M, DRV_C, "tty" },
+ { MEM_PROC_NR, 0, SRV_F, 16, 2, 0, SRV_T, DRV_M, DRV_C, "memory"},
+ { LOG_PROC_NR, 0, SRV_F, 16, 2, 0, SRV_T, SYS_M, DRV_C, "log" },
+ { DRVR_PROC_NR, 0, SRV_F, 16, 2, 0, SRV_T, SYS_M, DRV_C, "driver"},
+ { INIT_PROC_NR, 0, USR_F, 8, USER_Q, 0, USR_T, USR_M, 0, "init" },
};
-/* Verify the size of the system image table at compile time. If the number
- * is not correct, the size of the 'dummy' array will be negative, causing
- * a compile time error. Note that no space is allocated because 'dummy' is
- * declared extern.
- */
+/* Verify the size of the system image table at compile time. Also verify that
+ * the first chunk of the ipc mask has enough bits to accommodate the processes
+ * in the image.
+ * If a problem is detected, the size of the 'dummy' array will be negative,
+ * causing a compile time error. Note that no space is actually allocated
+ * because 'dummy' is declared extern.
+ */
extern int dummy[(NR_BOOT_PROCS==sizeof(image)/sizeof(struct boot_image))?1:-1];
+extern int dummy[(BITCHUNK_BITS > NR_BOOT_PROCS - 1) ? 1 : -1];
+
char quantum; /* quantum (tick count) */
int priority; /* scheduling priority */
int stksize; /* stack size for tasks */
- short call_mask; /* allowed system call traps */
- bitchunk_t send_mask; /* send mask protection */
- long sys_mask; /* system call protection */
+ short trap_mask; /* allowed system call traps */
+ bitchunk_t ipc_to; /* send mask protection */
+ long call_mask; /* system call protection */
char proc_name[P_NAME_LEN]; /* name in process table */
};
OBJ = main.o open.o read.o write.o pipe.o dmap.o \
device.o path.o mount.o link.o super.o inode.o \
cache.o cache2.o filedes.o stadir.o protect.o time.o \
- cmostime.o lock.o misc.o utility.o select.o timers.o table.o \
+ lock.o misc.o utility.o select.o timers.o table.o \
cdprobe.o
# build local binary
DT(0, gen_opcl, gen_io, NONE, DMAP_MUTABLE) /*14 = /dev/mixer */
DT(1, gen_opcl, gen_io, LOG_PROC_NR, 0) /*15 = /dev/klog */
DT(0, gen_opcl, gen_io, NONE, DMAP_MUTABLE) /*16 = /dev/random */
+ DT(0, gen_opcl, gen_io, NONE, DMAP_MUTABLE) /*17 = /dev/cmos */
#endif /* IBM_PC */
};
{
int result;
-
switch(m_in.ctl_req) {
case DEV_MAP:
/* Try to update device mapping. */
return;
/* Copy the blocks one at a time from the image to the RAM disk. */
- printf("Loading RAM disk onto /dev/ram:\33[23CLoaded: 0K ");
+ printf("Loading RAM disk onto /dev/ram:\33[23CLoaded: 0 KB");
inode[0].i_mode = I_BLOCK_SPECIAL; /* temp inode for rahead() */
inode[0].i_size = LONG_MAX;
put_block(bp1, FULL_DATA_BLOCK);
}
put_block(bp, FULL_DATA_BLOCK);
- printf("\b\b\b\b\b\b\b\b%6ldK ", ((long) b * block_size_image)/1024L);
+ if (b % 11 == 0)
+ printf("\b\b\b\b\b\b\b\b\b%6ld KB", ((long) b * block_size_image)/1024L);
}
/* Commit changes to RAM so dev_io will see it. */
_PROTOTYPE( int do_stime, (void) );
_PROTOTYPE( int do_utime, (void) );
-/* cmostime.c */
-_PROTOTYPE( int do_cmostime, (void) );
-
/* utility.c */
_PROTOTYPE( time_t clock_time, (void) );
_PROTOTYPE( unsigned conv2, (int norm, int w) );
do_reboot, /* 76 = reboot */
do_svrctl, /* 77 = svrctl */
- do_cmostime, /* 78 = cmostime */
+ no_sys, /* 78 = unused */
do_getsysinfo, /* 79 = getsysinfo */
no_sys, /* 80 = unused */
do_devctl, /* 81 = devctl */
# install -S 256w $@
# install with other servers
-install: /usr/sbin/$(SERVER)
-/usr/sbin/$(SERVER): $(SERVER)
+install: /sbin/$(SERVER)
+/sbin/$(SERVER): $(SERVER)
install -o root -c $? $@
# install -o root -cs $? $@
{
int m, i,j,r;
struct boot_image *ip;
- static char send_mask[BITCHUNK_BITS*2];
+ static char ipc_to[BITCHUNK_BITS*2];
if ((r = sys_getimage(image)) != OK) {
report("IS","warning: couldn't get copy of image table", r);
return;
}
printf("Image table dump showing all processes included in system image.\n");
- printf("---name-- -nr- -flags- -traps- -sq- ----pc- -stack- -sendmask[0]------\n");
+ printf("---name-- -nr- -flags- -traps- -sq- ----pc- -stack- -ipc_to[0]--------\n");
for (m=0; m<NR_BOOT_PROCS; m++) {
ip = &image[m];
for (i=j=0; i < BITCHUNK_BITS; i++, j++) {
- send_mask[j] = (ip->send_mask & (1<<i)) ? '1' : '0';
- if (i % 8 == 7) send_mask[++j] = ' ';
+ ipc_to[j] = (ip->ipc_to & (1<<i)) ? '1' : '0';
+ if (i % 8 == 7) ipc_to[++j] = ' ';
}
- send_mask[j] = '\0';
+ ipc_to[j] = '\0';
printf("%8s %4d %s %s %3d %7lu %7lu %s\n",
ip->proc_name, ip->proc_nr,
- s_flags_str(ip->flags), s_traps_str(ip->call_mask),
- ip->priority, (long)ip->initial_pc, ip->stksize, send_mask);
+ s_flags_str(ip->flags), s_traps_str(ip->trap_mask),
+ ip->priority, (long)ip->initial_pc, ip->stksize, ipc_to);
}
printf("\n");
}
register struct proc *rp;
static struct proc *oldrp = BEG_PROC_ADDR;
register struct priv *sp;
- static char send_mask[NR_SYS_PROCS + 1 + NR_SYS_PROCS/8];
+ static char ipc_to[NR_SYS_PROCS + 1 + NR_SYS_PROCS/8];
int r, i,j, n = 0;
/* First obtain a fresh copy of the current process and system table. */
return;
}
- printf("\n--nr-id-name---- -flags- -traps- -send mask------------------------- \n");
+ printf("\n--nr-id-name---- -flags- -traps- -ipc_to mask------------------------ \n");
for (rp = oldrp; rp < END_PROC_ADDR; rp++) {
if (isemptyp(rp)) continue;
}
printf("(%02u) %-7.7s %s %s ",
sp->s_id, rp->p_name,
- s_flags_str(sp->s_flags), s_traps_str(sp->s_call_mask)
+ s_flags_str(sp->s_flags), s_traps_str(sp->s_trap_mask)
);
for (i=j=0; i < NR_SYS_PROCS; i++, j++) {
- send_mask[j] = get_sys_bit(sp->s_send_mask, i) ? '1' : '0';
- if (i % 8 == 7) send_mask[++j] = ' ';
+ ipc_to[j] = get_sys_bit(sp->s_ipc_to, i) ? '1' : '0';
+ if (i % 8 == 7) ipc_to[++j] = ' ';
}
- send_mask[j] = '\0';
+ ipc_to[j] = '\0';
- printf(" %s \n", send_mask);
+ printf(" %s \n", ipc_to);
}
if (rp == END_PROC_ADDR) rp = BEG_PROC_ADDR; else printf("--more--\r");
oldrp = rp;
{
/* Perform the kill(pid, signo) system call. */
- DEBUG(m_in.pid == 11, printf("PM: detected do_kill PRINTER\n"));
-
return check_sig(m_in.pid, m_in.sig_nr);
}
}
/* Some signals are ignored by default. */
if (sigismember(&rmp->mp_ignore, signo)) {
- DEBUG(m_in.pid == 11, printf("PM: sig_proc ignored sig\n"));
return;
}
if (sigismember(&rmp->mp_sigmask, signo)) {
sigflags = rmp->mp_sigact[signo].sa_flags;
if (sigismember(&rmp->mp_catch, signo)) {
- DEBUG(m_in.pid == 11, printf("PM: sig_proc catch sig!\n"));
if (rmp->mp_flags & SIGSUSPENDED)
sm.sm_mask = rmp->mp_sigmask2;
else
rmp->mp_sigact[signo].sa_handler = SIG_DFL;
}
- DEBUG(m_in.pid == 11, printf("PM: sig_proc about to call sys_sigsend for %d \n",slot));
if (OK == (s=sys_sigsend(slot, &sm))) {
sigdelset(&rmp->mp_sigpending, signo);
}
doterminate:
- DEBUG(m_in.pid == 11, printf("PM: sig_proc doterminate\n"));
/* Signal should not or cannot be caught. Take default action. */
if (sigismember(&ign_sset, signo)) return;
tell_fs(CHDIR, slot, FALSE, 0);
dump_core(rmp);
}
- DEBUG(m_in.pid == 11, printf("PM: about to exit proc\n"));
mm_exit(rmp, 0); /* terminate process */
}
do_reboot, /* 76 = reboot */
do_svrctl, /* 77 = svrctl */
- no_sys, /* 78 = cmostime */
+ no_sys, /* 78 = unused */
do_getsysinfo, /* 79 = getsysinfo */
do_getprocnr, /* 80 = getprocnr */
no_sys, /* 81 = unused */
command[m_ptr->SRV_PATH_LEN] = '\0';
if (command[0] != '/') return(EINVAL);
+ args[0] = command;
if (m_ptr->SRV_ARGS_LEN > 0) {
if (m_ptr->SRV_ARGS_LEN > MAX_ARGS_LEN) return(E2BIG);
if (OK != (s=sys_datacopy(m_ptr->m_source, (vir_bytes) m_ptr->SRV_ARGS_ADDR,
SELF, (vir_bytes) arg_buf, m_ptr->SRV_ARGS_LEN))) return(s);
arg_buf[m_ptr->SRV_ARGS_LEN] = '\0';
- args[0] = &arg_buf[0];
- args[1] = NULL;
+ args[1] = &arg_buf[0];
+ args[2] = NULL;
} else {
- args[0] = NULL;
+ args[1] = NULL;
}
/* Now try to execute the new system service. Fork a new process. The child