diff --git a/commands/ibm/readclock.c b/commands/ibm/readclock.c index 9f1ed0011..b756929ce 100755 --- a/commands/ibm/readclock.c +++ b/commands/ibm/readclock.c @@ -55,6 +55,7 @@ #include #include +#include #include #include #include @@ -94,8 +95,11 @@ int bcd_to_dec(int n); 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; @@ -105,6 +109,7 @@ PUBLIC int main(int argc, char **argv) unsigned char mach_id, cmos_state; struct sysgetenv sysgetenv; message m; + int request; /* Process options. */ @@ -144,14 +149,17 @@ PUBLIC int main(int argc, char **argv) /* 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); @@ -159,7 +167,9 @@ PUBLIC int main(int argc, char **argv) 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", @@ -168,7 +178,7 @@ PUBLIC int main(int argc, char **argv) } if (i >= MAX_RETRIES) exit(1); - /* Set system time. */ + /* Now set system time. */ if (nflag) { printf("stime(%lu)\n", (unsigned long) rtc); } else { diff --git a/drivers/Makefile b/drivers/Makefile index d59007568..ea9199725 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -26,4 +26,5 @@ all install depend clean: cd ./dpeth && $(MAKE) $@ cd ./log && $(MAKE) $@ cd ./bios_wini && $(MAKE) $@ + cd ./cmos && $(MAKE) $@ cd ./random && $(MAKE) $@ diff --git a/drivers/at_wini/at_wini.c b/drivers/at_wini/at_wini.c index 2c5ff0e5a..2ae7df4a4 100644 --- a/drivers/at_wini/at_wini.c +++ b/drivers/at_wini/at_wini.c @@ -352,12 +352,14 @@ message *m_ptr; 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, diff --git a/drivers/cmos/Makefile b/drivers/cmos/Makefile new file mode 100644 index 000000000..09bbcb742 --- /dev/null +++ b/drivers/cmos/Makefile @@ -0,0 +1,49 @@ +# 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 + diff --git a/servers/fs/cmostime.c b/drivers/cmos/cmos.c similarity index 54% rename from servers/fs/cmostime.c rename to drivers/cmos/cmos.c index 06e5e9012..2f951a927 100644 --- a/servers/fs/cmostime.c +++ b/drivers/cmos/cmos.c @@ -1,12 +1,12 @@ -#include "fs.h" -#include -#include -#include -#include -#include - - -/* 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. * @@ -15,20 +15,126 @@ * published by Microsoft Press */ +#include "../drivers.h" +#include +#include +#include +#include + +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; -PUBLIC int do_cmostime(void) + 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); +} + + +/*===========================================================================* + * 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. diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile index e401ccc7b..7e35f4696 100644 --- a/drivers/memory/Makefile +++ b/drivers/memory/Makefile @@ -29,11 +29,6 @@ $(DRIVER): $(OBJ) $(LIBDRIVER) $(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) diff --git a/drivers/memory/memory.c b/drivers/memory/memory.c index 553f1a2f1..7e2bd28fe 100644 --- a/drivers/memory/memory.c +++ b/drivers/memory/memory.c @@ -9,7 +9,6 @@ * * 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) diff --git a/drivers/tty/console.c b/drivers/tty/console.c index 839d618a6..de4e3a0cb 100644 --- a/drivers/tty/console.c +++ b/drivers/tty/console.c @@ -874,7 +874,7 @@ tty_t *tp; * 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); diff --git a/drivers/tty/tty.c b/drivers/tty/tty.c index 4c24a4c33..438295b78 100644 --- a/drivers/tty/tty.c +++ b/drivers/tty/tty.c @@ -181,6 +181,7 @@ PUBLIC void main(void) panic("TTY","Couldn't obtain kernel environment.", s); } +printf("\n"); while (TRUE) { /* Check for and handle any events on any of the ttys. */ diff --git a/etc/rc b/etc/rc index 4312e1372..4fa646b3a 100755 --- a/etc/rc +++ b/etc/rc @@ -11,6 +11,20 @@ usage() 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 @@ -37,6 +51,12 @@ start) # 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 diff --git a/etc/usr/rc b/etc/usr/rc index 88f1f3db2..1aacef5ae 100644 --- a/etc/usr/rc +++ b/etc/usr/rc @@ -75,7 +75,7 @@ start) 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 @@ -95,7 +95,6 @@ start) fi done up inet "" - up is "" up printer "" /dev/lp # up floppy "" /dev/fd0 echo . diff --git a/include/minix/callnr.h b/include/minix/callnr.h index 710315e75..c8af59c2e 100755 --- a/include/minix/callnr.h +++ b/include/minix/callnr.h @@ -66,7 +66,7 @@ /* 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 */ diff --git a/include/minix/com.h b/include/minix/com.h index 3ce68029b..8c2881d64 100755 --- a/include/minix/com.h +++ b/include/minix/com.h @@ -135,7 +135,7 @@ * 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 @@ -143,18 +143,22 @@ #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 @@ -187,41 +191,41 @@ */ #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_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_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_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_TRACE (KERNEL_CALL + 13) /* sys_trace() */ - -# define SYS_SETALARM (KERNEL_CALL + 16) /* sys_setalarm() */ +# 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_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_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_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 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 NR_SYS_CALLS 28 /* number of system calls */ /* Field names for SYS_MEMSET, SYS_SEGCTL. */ #define MEM_PTR m2_p1 /* base */ diff --git a/include/sys/ioc_cmos.h b/include/sys/ioc_cmos.h new file mode 100755 index 000000000..e89355ef2 --- /dev/null +++ b/include/sys/ioc_cmos.h @@ -0,0 +1,15 @@ +/* sys/ioc_cmos.h - CMOS ioctl() command codes. + */ + +#ifndef _S_I_CMOS_H +#define _S_I_CMOS_H + +#include + +#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 */ + diff --git a/include/sys/ioctl.h b/include/sys/ioctl.h index 2cfb735d8..289f28735 100755 --- a/include/sys/ioctl.h +++ b/include/sys/ioctl.h @@ -18,6 +18,7 @@ #include /* 'd' */ #include /* 'f' */ #include /* 'm' */ +#include /* 'c' */ #include /* 'M' */ #include /* 'S' */ #include /* 's' */ diff --git a/kernel/const.h b/kernel/const.h index 4bff11036..a9b551d86 100755 --- a/kernel/const.h +++ b/kernel/const.h @@ -14,9 +14,8 @@ */ #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'. diff --git a/kernel/main.c b/kernel/main.c index 242f24e2f..5eb48cbeb 100755 --- a/kernel/main.c +++ b/kernel/main.c @@ -82,8 +82,9 @@ PUBLIC void main() 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; diff --git a/kernel/priv.h b/kernel/priv.h index a51bcc0d4..6c54a00fd 100755 --- a/kernel/priv.h +++ b/kernel/priv.h @@ -21,9 +21,10 @@ struct priv { 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 */ diff --git a/kernel/proc.c b/kernel/proc.c index 1de7c4476..e66cd27be 100755 --- a/kernel/proc.c +++ b/kernel/proc.c @@ -112,7 +112,7 @@ message *m_ptr; /* pointer to message in the caller's space */ * 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); @@ -141,7 +141,7 @@ message *m_ptr; /* pointer to message in the caller's space */ * 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); diff --git a/kernel/system.c b/kernel/system.c index 8ab22bcaf..6fb2f810c 100755 --- a/kernel/system.c +++ b/kernel/system.c @@ -22,6 +22,7 @@ * * 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) @@ -62,22 +63,30 @@ PUBLIC void sys_task() /* 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); + /* 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); - /* 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); + /* See if the caller made a valid request and try to handle it. */ + if (! (priv(caller_ptr)->s_call_mask & (1<= 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 @@ -86,9 +95,8 @@ PUBLIC void sys_task() */ 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); } } } diff --git a/kernel/system/do_privctl.c b/kernel/system/do_privctl.c index 003f16d91..8c2e8011c 100644 --- a/kernel/system/do_privctl.c +++ b/kernel/system/do_privctl.c @@ -58,18 +58,18 @@ message *m_ptr; /* pointer to request message */ 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; ip_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; ip_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)); } } diff --git a/kernel/table.c b/kernel/table.c index 2c15deb5c..8645c1d3d 100755 --- a/kernel/table.c +++ b/kernel/table.c @@ -22,7 +22,7 @@ * 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) */ @@ -48,7 +48,7 @@ PUBLIC char *t_stack[TOT_STACK_SPACE / sizeof(char *)]; /* 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 @@ -64,19 +64,26 @@ PUBLIC char *t_stack[TOT_STACK_SPACE / sizeof(char *)]; * 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 @@ -86,25 +93,29 @@ extern int dummy[(BITCHUNK_BITS-NR_TASKS > INIT_PROC_NR) ? 1 : -1]; * 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]; + diff --git a/kernel/type.h b/kernel/type.h index 12e3d41ce..a8b75c63b 100755 --- a/kernel/type.h +++ b/kernel/type.h @@ -17,9 +17,9 @@ struct boot_image { 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 */ }; diff --git a/servers/fs/Makefile b/servers/fs/Makefile index fbe337dac..30bfb1765 100644 --- a/servers/fs/Makefile +++ b/servers/fs/Makefile @@ -16,7 +16,7 @@ LIBS = -lsys -lsysutil -ltimers 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 diff --git a/servers/fs/dmap.c b/servers/fs/dmap.c index 0e9afbea8..6251ae8c9 100644 --- a/servers/fs/dmap.c +++ b/servers/fs/dmap.c @@ -50,6 +50,7 @@ struct dmap dmap[NR_DEVICES] = { 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 */ }; @@ -61,7 +62,6 @@ PUBLIC int do_devctl() { int result; - switch(m_in.ctl_req) { case DEV_MAP: /* Try to update device mapping. */ diff --git a/servers/fs/main.c b/servers/fs/main.c index 37e006dd0..de4b4b1b7 100644 --- a/servers/fs/main.c +++ b/servers/fs/main.c @@ -366,7 +366,7 @@ PRIVATE void load_ram(void) 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; @@ -398,7 +398,8 @@ PRIVATE void load_ram(void) 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. */ diff --git a/servers/fs/proto.h b/servers/fs/proto.h index 81cb74cc0..9eaf914c0 100644 --- a/servers/fs/proto.h +++ b/servers/fs/proto.h @@ -164,9 +164,6 @@ _PROTOTYPE( int get_block_size, (dev_t dev) ); _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) ); diff --git a/servers/fs/table.c b/servers/fs/table.c index 23129b6f1..45ebd1c70 100644 --- a/servers/fs/table.c +++ b/servers/fs/table.c @@ -95,7 +95,7 @@ PUBLIC _PROTOTYPE (int (*call_vec[]), (void) ) = { 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 */ diff --git a/servers/is/Makefile b/servers/is/Makefile index 4dac26067..724f46a5b 100644 --- a/servers/is/Makefile +++ b/servers/is/Makefile @@ -26,8 +26,8 @@ $(SERVER): $(OBJ) # 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 $? $@ diff --git a/servers/is/dmp_kernel.c b/servers/is/dmp_kernel.c index a532f6211..488fa9323 100644 --- a/servers/is/dmp_kernel.c +++ b/servers/is/dmp_kernel.c @@ -189,25 +189,25 @@ PUBLIC void image_dmp() { 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; msend_mask & (1<ipc_to & (1<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"); } @@ -344,7 +344,7 @@ PUBLIC void privileges_dmp() 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. */ @@ -357,7 +357,7 @@ PUBLIC void privileges_dmp() 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; @@ -373,15 +373,15 @@ PUBLIC void privileges_dmp() } 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; diff --git a/servers/pm/signal.c b/servers/pm/signal.c index 49ef40c9b..f29c0f64d 100644 --- a/servers/pm/signal.c +++ b/servers/pm/signal.c @@ -193,8 +193,6 @@ PUBLIC int do_kill() { /* 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); } @@ -417,7 +415,6 @@ int signo; /* signal to send to process (1 to _NSIG) */ } /* 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)) { @@ -434,7 +431,6 @@ int signo; /* signal to send to process (1 to _NSIG) */ 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 @@ -464,7 +460,6 @@ int signo; /* signal to send to process (1 to _NSIG) */ 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); @@ -483,7 +478,6 @@ int signo; /* signal to send to process (1 to _NSIG) */ } 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; @@ -499,7 +493,6 @@ doterminate: 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 */ } diff --git a/servers/pm/table.c b/servers/pm/table.c index 4f0ee23ef..d38d6126c 100644 --- a/servers/pm/table.c +++ b/servers/pm/table.c @@ -94,7 +94,7 @@ _PROTOTYPE (int (*call_vec[NCALLS]), (void) ) = { 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 */ diff --git a/servers/sm/manager.c b/servers/sm/manager.c index 8df0738a8..9cdf607d3 100644 --- a/servers/sm/manager.c +++ b/servers/sm/manager.c @@ -45,15 +45,16 @@ PUBLIC int do_start(message *m_ptr) 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