]> Zhao Yanbai Git Server - minix.git/commitdiff
. removed readclock command and cmos driver.
authorBen Gras <ben@minix3.org>
Fri, 12 Jan 2007 16:35:04 +0000 (16:35 +0000)
committerBen Gras <ben@minix3.org>
Fri, 12 Jan 2007 16:35:04 +0000 (16:35 +0000)
. replaced by a readclock 'driver' that runs once, a re-imported version
  of the minix 2.0.4 readclock command.
. this has also restored cmos writing.
. readclock wrapper script calls service command to run /bin/readclock.drv
  once.

12 files changed:
commands/ibm/Makefile
commands/ibm/readclock.c [deleted file]
commands/scripts/MAKEDEV.sh
commands/scripts/Makefile
commands/scripts/readclock.sh [new file with mode: 0644]
drivers/Makefile
drivers/cmos/cmos.c [deleted file]
drivers/readclock/Makefile [moved from drivers/cmos/Makefile with 54% similarity]
drivers/readclock/readclock.c [new file with mode: 0644]
etc/Makefile
etc/drivers.conf
etc/rc

index f251b80a882c7782cb7ae41dad9e30a6c0296ac0..95337f1a6d8805e528e538a95aff46163c18d35d 100755 (executable)
@@ -20,7 +20,6 @@ ALL   = \
        partition \
        playwave \
        postmort \
-       readclock \
        recwave \
        repartition \
        screendump \
@@ -76,10 +75,6 @@ postmort:    postmort.c
        $(CCLD) -o $@ $?
        install -S 4kw $@
 
-readclock:     readclock.c
-       $(CCLD) -o $@ $?
-       install -S 4kw $@
-
 recwave:       recwave.c
        $(CCLD) -o $@ $?
        install -S 16kw $@
@@ -111,13 +106,11 @@ install:  \
        /usr/bin/partition \
        /usr/bin/playwave \
        /usr/bin/postmort \
-       /usr/bin/readclock \
        /usr/bin/recwave \
        /usr/bin/repartition \
        /usr/bin/screendump \
        /usr/bin/sdump \
        /bin/loadkeys \
-       /bin/readclock \
 
 /usr/bin/atnormalize:  atnormalize
        install -cs -o bin $? $@
@@ -158,9 +151,6 @@ install:    \
 /usr/bin/postmort:     postmort
        install -cs -o bin $? $@
 
-/usr/bin/readclock:    readclock
-       install -cs -o bin $? $@
-
 /usr/bin/recwave:      recwave
        install -cs -o bin $? $@
 
@@ -176,8 +166,5 @@ install:    \
 /bin/loadkeys: /usr/bin/loadkeys
        install -lcs $? $@
 
-/bin/readclock:        /usr/bin/readclock
-       install -lcs $? $@
-
 clean:
        rm -rf $(ALL) a.out core
diff --git a/commands/ibm/readclock.c b/commands/ibm/readclock.c
deleted file mode 100755 (executable)
index f4a5186..0000000
+++ /dev/null
@@ -1,226 +0,0 @@
-/* setime - set the system time from the real time clock
-                                       Authors: T. Holm & E. Froese
-                                       Adapted by: Jorrit .N. Herder */
-
-/************************************************************************/
-/*   Readclock was updated for security reasons: openeing /dev/mem no  */
-/*   longer automatically grants I/O privileges to the calling process */
-/*   so that the CMOS' clock could not be read from this program. The  */
-/*   new approach is to rely on the FS to do the CMOS I/O, via the new  */
-/*   system call CMOSTIME (which only reads the current clock value and */
-/*   cannot update the CMOS clock).                                    */
-/*   The original readclock.c is still available under backup.c.       */
-/************************************************************************/
-/*                                                                     */
-/*   readclock.c                                                       */
-/*                                                                     */
-/*             Read the clock value from the 64 byte CMOS RAM          */
-/*             area, then set system time.                             */
-/*                                                                     */
-/*             If the machine ID byte is 0xFC or 0xF8, the device      */
-/*             /dev/mem exists and can be opened for reading,          */
-/*             and no errors in the CMOS RAM are reported by the       */
-/*             RTC, then the time is read from the clock RAM           */
-/*             area maintained by the RTC.                             */
-/*                                                                     */
-/*             The clock RAM values are decoded and fed to mktime      */
-/*             to make a time_t value, then stime(2) is called.        */
-/*                                                                     */
-/*             This fails if:                                          */
-/*                                                                     */
-/*             If the machine ID does not match 0xFC or 0xF8 (no       */
-/*             error message.)                                         */
-/*                                                                     */
-/*             If the machine ID is 0xFC or 0xF8 and /dev/mem          */
-/*             is missing, or cannot be accessed.                      */
-/*                                                                     */
-/*             If the RTC reports errors in the CMOS RAM.              */
-/*                                                                     */
-/************************************************************************/
-/*    origination          1987-Dec-29              efth                */
-/*    robustness          1990-Oct-06              C. Sylvain          */
-/* incorp. B. Evans ideas  1991-Jul-06             C. Sylvain          */
-/*    set time & calibrate 1992-Dec-17             Kees J. Bot         */
-/*    clock timezone      1993-Oct-10              Kees J. Bot         */
-/*    set CMOS clock      1994-Jun-12              Kees J. Bot         */
-/*    removed set CMOS    2004-Sep-06              Jorrit N. Herder    */
-/************************************************************************/
-
-#include <minix/callnr.h>
-#include <minix/config.h>
-#include <minix/type.h>
-#include <minix/const.h>
-#include <minix/com.h>
-#include <minix/syslib.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioc_cmos.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-#include <errno.h>
-#include <signal.h>
-#include <minix/portio.h>
-#include <ibm/cmos.h>
-#include <sys/svrctl.h>
-
-#define MAX_RETRIES    1
-
-int nflag = 0;         /* Tell what, but don't do it. */
-int y2kflag = 0;       /* Interpret 1980 as 2000 for clock with Y2K bug. */
-
-char clocktz[128];     /* Timezone of the clock. */
-
-#define MACH_ID_ADDR   0xFFFFE         /* BIOS Machine ID at FFFF:000E */
-
-#define PC_AT             0xFC         /* Machine ID byte for PC/AT,
-                                          PC/XT286, and PS/2 Models 50, 60 */
-#define PS_386            0xF8         /* Machine ID byte for PS/2 Model 80 */
-
-/* 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.
- *
- * Machine ID byte information source:
- *     _The Programmer's PC Sourcebook_ by Thom Hogan,
- *     published by Microsoft Press
- */
-
-void errmsg(char *s);
-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;
-  char date[64];
-  time_t now, rtc;
-  int i, s, mem;
-  unsigned char mach_id, cmos_state;
-  struct sysgetenv sysgetenv;
-  message m;
-  int request;
-
-
-  /* Process options. */
-  while (argc > 1) {
-       char *p = *++argv;
-
-       if (*p++ != '-') usage();
-
-       while (*p != 0) {
-               switch (*p++) {
-               case 'n':       nflag = 1;      break;
-               case '2':       y2kflag = 1;    break;
-               default:        usage();
-               }
-       }
-       argc--;
-  }
-
-#if DEAD_CODE
-  /* The hardware clock may run in a different time zone, likely GMT or
-   * winter time.  Select that time zone.
-   */
-  strcpy(clocktz, "TZ=");
-  sysgetenv.key = "TZ";
-  sysgetenv.keylen = 2+1;
-  sysgetenv.val = clocktz+3;
-  sysgetenv.vallen = sizeof(clocktz)-3;
-  if (svrctl(SYSGETENV, &sysgetenv) == 0) {
-       putenv(clocktz);
-       tzset();
-  }
-#endif
-
-  /* Read the CMOS real time clock. */
-  for (i = 0; i < MAX_RETRIES; i++) {
-
-       /* sleep, unless first iteration */
-       if (i > 0) sleep(5);
-
-       /* Open the CMOS device to read the system time. */
-       if ((fd = open(CMOS_DEV, O_RDONLY)) < 0) {
-               perror(CMOS_DEV);
-               fprintf(stderr, "Couldn't open CMOS device.\n");
-               exit(1);
-       }
-        request = (y2kflag) ? CIOCGETTIME : CIOCGETTIMEY2K;
-       if ((s=ioctl(fd, request, (void *) &time1)) < 0) {
-               perror("ioctl");
-               fprintf(stderr, "Couldn't do CMOS ioctl.\n");
-               exit(1);
-       }
-       close(fd);
-
-       now = time(NULL);
-
-       time1.tm_isdst = -1;    /* Do timezone calculations. */
-       time2 = time1;
-
-       rtc= mktime(&time1);    /* Transform to a time_t. */
-       if (rtc != -1) {
-               break;
-       }
-
-       fprintf(stderr,
-"readclock: Invalid time read from CMOS RTC: %d-%02d-%02d %02d:%02d:%02d\n",
-               time2.tm_year+1900, time2.tm_mon+1, time2.tm_mday,
-               time2.tm_hour, time2.tm_min, time2.tm_sec);
-  }
-  if (i >= MAX_RETRIES) exit(1);
-
-  /* Now set system time. */
-  if (nflag) {
-               printf("stime(%lu)\n", (unsigned long) rtc);
-  } else {
-       if (stime(&rtc) < 0) {
-               errmsg( "Not allowed to set time." );
-               exit(1);
-       }
-  }
-  tmnow = *localtime(&rtc);
-  if (strftime(date, sizeof(date),
-                       "%a %b %d %H:%M:%S %Z %Y", &tmnow) != 0) {
-       if (date[8] == '0') date[8]= ' ';
-#if 0
-       printf("%s [CMOS read via FS, see command/ibm/readclock.c]\n", date);
-#endif
-  }
-  exit(0);
-}
-
-void errmsg(char *s)
-{
-  static char *prompt = "readclock: ";
-
-  fprintf(stderr, "%s%s\n", prompt, s);
-  prompt = "";
-}
-
-
-int bcd_to_dec(int n)
-{
-  return ((n >> 4) & 0x0F) * 10 + (n & 0x0F);
-}
-
-int dec_to_bcd(int n)
-{
-  return ((n / 10) << 4) | (n % 10);
-}
-
-void usage(void)
-{
-  fprintf(stderr, "Usage: settime [-n2]\n");
-  exit(1);
-}
index 12e6d418206eba7e781c9f393dc2c86e2fd944fd..efc54729850dbdba8a56d136081696099a8ad980 100755 (executable)
@@ -19,7 +19,7 @@ case $#:$1 in
        ttypa ttypb ttypc ttypd ttype ttypf \
        ttyq0 ttyq1 ttyq2 ttyq3 ttyq4 ttyq5 ttyq6 ttyq7 ttyq8 ttyq9 \
        ttyqa ttyqb ttyqc ttyqd ttyqe ttyqf \
-       eth klog random cmos rescue
+       eth klog random rescue
     ;;
 0:|1:-\?)
     cat >&2 <<EOF
@@ -41,7 +41,6 @@ Where key is one of the following:
   audio mixer            # Make audio devices
   klog                    # Make /dev/klog
   random                  # Make /dev/random, /dev/urandom
-  cmos                    # Make /dev/cmos
   kbd                     # Make /dev/kbd
   kbdaux                  # Make /dev/kbdaux
   rescue                  # Make /dev/rescue
@@ -243,11 +242,6 @@ do
        $e mknod urandom c 16 0; $e chmod 644 urandom
        $e chgrp operator random urandom
        ;;
-    cmos)
-       # cmos device (set/get system time).
-       $e mknod cmos c 17 0
-       $e chmod 600 cmos
-       ;;
     rescue)
        # rescue device
        $e mknod rescue b 9 0
index 9fb14ec0999413e46410cbd350b11a31e631c8e8..2fee8db0c13179929b318e293caddec9ec787443 100755 (executable)
@@ -38,6 +38,7 @@ usr:  \
        /usr/bin/makewhatis \
        /usr/bin/mkdep \
        /usr/bin/mkdist \
+       /bin/readclock \
        /bin/setup \
        /usr/bin/binsizes \
        /usr/bin/rotate \
@@ -133,6 +134,9 @@ clean:
 /usr/bin/rotate:       rotate.sh
        install -m 755 -c -o bin $? $@
 
+/bin/readclock:        readclock.sh
+       install -m 755 -c -o bin $? $@
+
 /bin/setup:    setup.sh
        install -m 755 -c -o bin $? $@
 
diff --git a/commands/scripts/readclock.sh b/commands/scripts/readclock.sh
new file mode 100644 (file)
index 0000000..e6a2e78
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/sh
+if [ $# -gt 0 ]
+then   ARGS="-args $@"
+fi
+/bin/service up /sbin/readclock.drv -config /etc/drivers.conf -script /etc/rs.single $ARGS
index cb7338ff6363dc4d3e702c4d02bac29f75335db7..2315c894164229008c4e7d4d4c178101808643cc 100644 (file)
@@ -25,8 +25,8 @@ all install depend clean:
        cd ./dpeth && $(MAKE) $@
        cd ./log && $(MAKE) $@
        cd ./bios_wini && $(MAKE) $@
-       cd ./cmos && $(MAKE) $@
        cd ./random && $(MAKE) $@
+       cd ./readclock && $(MAKE) $@
        cd ./dp8390 && $(MAKE) $@
        cd ./sb16 && $(MAKE) $@
        cd ./lance && $(MAKE) $@
diff --git a/drivers/cmos/cmos.c b/drivers/cmos/cmos.c
deleted file mode 100644 (file)
index b53106e..0000000
+++ /dev/null
@@ -1,283 +0,0 @@
-/* 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.
- *
- * Machine ID byte information source:
- *     _The Programmer's PC Sourcebook_ by Thom Hogan,
- *     published by Microsoft Press
- */
-
-#include "../drivers.h"
-#include <sys/ioc_cmos.h>
-#include <time.h>
-#include <ibm/cmos.h>
-#include <ibm/bios.h>
-#include <minix/safecopies.h>
-
-extern int errno;                      /* error number for PM calls */
-
-FORWARD _PROTOTYPE( int gettime, (int who, int y2kflag, vir_bytes dst_time, int safe));
-FORWARD _PROTOTYPE( void reply, (int reply, int replyee, int proc, cp_grant_id_t, 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;
-  cp_grant_id_t susp_grant = GRANT_INVALID;
-  int s;
-
-  while(TRUE) {
-      int safe = 0;
-
-      /* 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.IO_ENDPT, GRANT_INVALID, OK);
-          break;
-
-      case DEV_PING:
-         notify(m.m_source);
-         break;
-      case DEV_IOCTL_S:                                
-         safe=1;
-         /* Fall through. */
-      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.IO_ENDPT, GRANT_INVALID, EBUSY);
-              break;
-          }
-          suspended = m.IO_ENDPT;
-         susp_grant = (cp_grant_id_t) m.IO_GRANT;
-          reply(TASK_REPLY, m.m_source, m.IO_ENDPT, susp_grant, SUSPEND);
-
-         switch(m.REQUEST) {
-         case CIOCGETTIME:                     /* get CMOS time */ 
-          case CIOCGETTIMEY2K:
-              y2kflag = (m.REQUEST == CIOCGETTIME) ? 0 : 1;
-              result = gettime(m.IO_ENDPT, y2kflag, (vir_bytes) m.ADDRESS, safe);
-              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, GRANT_INVALID, OK);
-          else 
-              reply(DEV_REVIVE, m.m_source, suspended, susp_grant, 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.IO_ENDPT, GRANT_INVALID, EINVAL);
-      }        
-  }
-}
-
-/*===========================================================================*
- *                             reply                                        *
- *===========================================================================*/
-PRIVATE void reply(int code, int replyee, int process, cp_grant_id_t grantid, int status)
-{
-  message m;
-  int s;
-
-  m.m_type = code;             /* TASK_REPLY or REVIVE */
-  m.REP_STATUS = status;       /* result of device operation */
-  m.REP_ENDPT = process;       /* which user made the request */
-  m.REP_IO_GRANT = grantid;    /* I/O grant on which to unSUSPEND */
-  if (OK != (s=send(replyee, &m)))
-      panic("CMOS", "sending reply failed", s);
-}
-
-/*===========================================================================*
- *                             gettime                                      *
- *===========================================================================*/
-PRIVATE int gettime(int who, int y2kflag, vir_bytes dst_time, int safe)
-{
-  unsigned char mach_id, cmos_state;
-  struct tm time1;
-  int i, s;
-
-  /* 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.  
-   */
-  s = sys_readbios( MACHINE_ID_ADDR, &mach_id, MACHINE_ID_SIZE);
-  if (s != 0) {
-       printf("gettime: sys_readbios failed: %d\n", s);
-       return EINVAL;
-  }
-  if (mach_id != PS_386_MACHINE && mach_id != PC_AT_MACHINE) {
-       printf("gettime: machine ID unknown. ID byte = %02x.\n", mach_id);
-       return(EFAULT);
-  }
-
-  /* Now check the CMOS' state to see if we can read a proper time from it.
-   * If the state is crappy, return an error.
-   */
-  cmos_state = read_register(CMOS_STATUS);
-  if (cmos_state & (CS_LOST_POWER | CS_BAD_CHKSUM | CS_BAD_TIME)) {
-       printf( "IS: CMOS RAM error(s) found. State = 0x%02x\n", cmos_state );
-       if (cmos_state & CS_LOST_POWER)
-           printf("IS: RTC lost power. Reset CMOS RAM with SETUP." );
-       if (cmos_state & CS_BAD_CHKSUM)
-           printf("IS: CMOS RAM checksum is bad. Run SETUP." );
-       if (cmos_state & CS_BAD_TIME)
-           printf("IS: Time invalid in CMOS RAM. Reset clock." );
-       return(EFAULT);
-  }
-
-  /* Everything seems to be OK. Read the CMOS real time clock and copy the
-   * result back to the caller.
-   */
-  if (get_cmostime(&time1, y2kflag) != 0)
-       return(EFAULT);
-
-  /* Copy result back, safely or not. */
-  if(safe) {
-    sys_safecopyto(who, dst_time, 0, (vir_bytes) &time1, 
-      sizeof(struct tm), D);
-  } else {
-    sys_datacopy(SELF, (vir_bytes) &time1, 
-       who, dst_time, sizeof(struct tm));
-  }
-
-  return(OK);
-}
-
-PRIVATE int get_cmostime(struct tm *t, int y2kflag)
-{
-/* Update the structure pointed to by time with the current time as read
- * from CMOS RAM of the RTC. If necessary, the time is converted into a
- * binary format before being stored in the structure.
- */
-  int osec, n;
-  unsigned long i;
-  clock_t t0,t1;
-
-  /* Start a timer to keep us from getting stuck on a dead clock. */
-  getuptime(&t0);
-  do {
-       osec = -1;
-       n = 0;
-       do {
-               getuptime(&t1); 
-               if (t1-t0 > 5*HZ) {
-                       printf("readclock: CMOS clock appears dead\n");
-                       return(1);
-               }
-
-               /* Clock update in progress? */
-               if (read_register(RTC_REG_A) & RTC_A_UIP) continue;
-
-               t->tm_sec = read_register(RTC_SEC);
-               if (t->tm_sec != osec) {
-                       /* Seconds changed.  First from -1, then because the
-                        * clock ticked, which is what we're waiting for to
-                        * get a precise reading.
-                        */
-                       osec = t->tm_sec;
-                       n++;
-               }
-       } while (n < 2);
-
-       /* Read the other registers. */
-       t->tm_min = read_register(RTC_MIN);
-       t->tm_hour = read_register(RTC_HOUR);
-       t->tm_mday = read_register(RTC_MDAY);
-       t->tm_mon = read_register(RTC_MONTH);
-       t->tm_year = read_register(RTC_YEAR);
-
-       /* Time stable? */
-  } while (read_register(RTC_SEC) != t->tm_sec
-       || read_register(RTC_MIN) != t->tm_min
-       || read_register(RTC_HOUR) != t->tm_hour
-       || read_register(RTC_MDAY) != t->tm_mday
-       || read_register(RTC_MONTH) != t->tm_mon
-       || read_register(RTC_YEAR) != t->tm_year);
-
-  if ((read_register(RTC_REG_B) & RTC_B_DM_BCD) == 0) {
-       /* Convert BCD to binary (default RTC mode). */
-       t->tm_year = bcd_to_dec(t->tm_year);
-       t->tm_mon = bcd_to_dec(t->tm_mon);
-       t->tm_mday = bcd_to_dec(t->tm_mday);
-       t->tm_hour = bcd_to_dec(t->tm_hour);
-       t->tm_min = bcd_to_dec(t->tm_min);
-       t->tm_sec = bcd_to_dec(t->tm_sec);
-  }
-  t->tm_mon--; /* Counts from 0. */
-
-  /* Correct the year, good until 2080. */
-  if (t->tm_year < 80) t->tm_year += 100;
-
-  if (y2kflag) {
-       /* Clock with Y2K bug, interpret 1980 as 2000, good until 2020. */
-       if (t->tm_year < 100) t->tm_year += 20;
-  }
-  return 0;
-}
-
-PRIVATE int read_register(int reg_addr)
-{
-/* Read a single CMOS register value. */
-  unsigned long r;
-  sys_outb(RTC_INDEX, reg_addr);
-  sys_inb(RTC_IO, &r);
-  return r;
-}
-
-PRIVATE int bcd_to_dec(int n)
-{
-  return ((n >> 4) & 0x0F) * 10 + (n & 0x0F);
-}
-
-PRIVATE int dec_to_bcd(int n)
-{
-  return ((n / 10) << 4) | (n % 10);
-}
-
similarity index 54%
rename from drivers/cmos/Makefile
rename to drivers/readclock/Makefile
index 8be22f40bcd77ae8bc244d4113e47b9b601acc4e..04a252a61e350b2d41ab4d9d5d3826d6e1a752d6 100644 (file)
@@ -1,25 +1,17 @@
-# Makefile for the CMOS driver 
-DRIVER = cmos
-
-# directories
-u = /usr
-i = $u/include
-s = $i/sys
-m = $i/minix
-b = $i/ibm
-d = ..
+# Makefile for readclock 'driver'
+DRIVER = readclock.drv
 
 # programs, flags, etc.
 MAKE = exec make
 CC =   exec cc
-CFLAGS = -I$i $(CPROFILE)
-LDFLAGS = -i -L../libdriver
-LIBS = -lsysutil -lsys -ldriver
+CFLAGS=-D_MINIX=1 -D_POSIX_SOURCE=1 -D_SYSTEM=1
+LDFLAGS = -i
+LIBS = -lsysutil -lsys
 
-OBJ = cmos.o 
+OBJ = readclock.o 
 
 # build local binary
-all build:     $(DRIVER) 
+all build:     $(DRIVER)
 $(DRIVER):     $(OBJ)
        $(CC) -o $@ $(LDFLAGS) $(OBJ) $(LIBS)
        install -S 8k $(DRIVER)
@@ -33,9 +25,8 @@ install:      /sbin/$(DRIVER)
 clean:
        rm -f $(DRIVER) *.o *.bak 
 
-
 depend: 
-       /usr/bin/mkdep "$(CC) -E $(CPPFLAGS)" *.c ../libdriver/*.c > .depend
+       /usr/bin/mkdep "$(CC) -E $(CPPFLAGS)" *.c > .depend
 
 # Include generated dependencies.
 include .depend
diff --git a/drivers/readclock/readclock.c b/drivers/readclock/readclock.c
new file mode 100644 (file)
index 0000000..b2cb6b2
--- /dev/null
@@ -0,0 +1,412 @@
+/* readclock - read the real time clock                Authors: T. Holm & E. Froese
+ *
+ * Changed to be user-space driver.
+ */
+
+/************************************************************************/
+/*                                                                     */
+/*   readclock.c                                                       */
+/*                                                                     */
+/*             Read the clock value from the 64 byte CMOS RAM          */
+/*             area, then set system time.                             */
+/*                                                                     */
+/*             If the machine ID byte is 0xFC or 0xF8, the device      */
+/*             /dev/mem exists and can be opened for reading,          */
+/*             and no errors in the CMOS RAM are reported by the       */
+/*             RTC, then the time is read from the clock RAM           */
+/*             area maintained by the RTC.                             */
+/*                                                                     */
+/*             The clock RAM values are decoded and fed to mktime      */
+/*             to make a time_t value, then stime(2) is called.        */
+/*                                                                     */
+/*             This fails if:                                          */
+/*                                                                     */
+/*             If the machine ID does not match 0xFC or 0xF8 (no       */
+/*             error message.)                                         */
+/*                                                                     */
+/*             If the machine ID is 0xFC or 0xF8 and /dev/mem          */
+/*             is missing, or cannot be accessed.                      */
+/*                                                                     */
+/*             If the RTC reports errors in the CMOS RAM.              */
+/*                                                                     */
+/************************************************************************/
+/*    origination          1987-Dec-29              efth                */
+/*    robustness          1990-Oct-06              C. Sylvain          */
+/* incorp. B. Evans ideas  1991-Jul-06             C. Sylvain          */
+/*    set time & calibrate 1992-Dec-17             Kees J. Bot         */
+/*    clock timezone      1993-Oct-10              Kees J. Bot         */
+/*    set CMOS clock      1994-Jun-12              Kees J. Bot         */
+/************************************************************************/
+
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+#include <signal.h>
+#include <minix/type.h>
+#include <minix/syslib.h>
+#include <minix/com.h>
+#include <minix/portio.h>
+#include <ibm/cmos.h>
+#include <sys/svrctl.h>
+
+int nflag = 0;         /* Tell what, but don't do it. */
+int wflag = 0;         /* Set the CMOS clock. */
+int Wflag = 0;         /* Also set the CMOS clock register bits. */
+int y2kflag = 0;       /* Interpret 1980 as 2000 for clock with Y2K bug. */
+
+char clocktz[128];     /* Timezone of the clock. */
+
+#define MACH_ID_ADDR   0xFFFFE         /* BIOS Machine ID at FFFF:000E */
+
+#define PC_AT             0xFC         /* Machine ID byte for PC/AT,
+                                          PC/XT286, and PS/2 Models 50, 60 */
+#define PS_386            0xF8         /* Machine ID byte for PS/2 Model 80 */
+
+/* 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.
+ *
+ * Machine ID byte information source:
+ *     _The Programmer's PC Sourcebook_ by Thom Hogan,
+ *     published by Microsoft Press
+ */
+
+void errmsg(char *s);
+void get_time(struct tm *t);
+int read_register(int reg_addr);
+void set_time(struct tm *t);
+void write_register(int reg_addr, int value);
+int bcd_to_dec(int n);
+int dec_to_bcd(int n);
+void usage(void);
+
+int main(int argc, char **argv)
+{
+  struct tm time1;
+  struct tm time2;
+  struct tm tmnow;
+  char date[64];
+  time_t now, rtc;
+  int i, s;
+  unsigned char mach_id, cmos_state;
+  struct sysgetenv sysgetenv;
+
+  if((s=sys_readbios(MACH_ID_ADDR, &mach_id, sizeof(mach_id))) != OK) {
+       printf("readclock: sys_readbios failed: %d.\n", s);
+       exit(1);
+  }
+
+  if (mach_id != PS_386 && mach_id != PC_AT) {
+       errmsg("Machine ID unknown." );
+       printf("Machine ID byte = %02x\n", mach_id );
+
+       exit(1);
+  }
+
+  cmos_state = read_register(CMOS_STATUS);
+
+  if (cmos_state & (CS_LOST_POWER | CS_BAD_CHKSUM | CS_BAD_TIME)) {
+       errmsg( "CMOS RAM error(s) found..." );
+       printf("CMOS state = 0x%02x\n", cmos_state );
+
+       if (cmos_state & CS_LOST_POWER)
+           errmsg( "RTC lost power. Reset CMOS RAM with SETUP." );
+       if (cmos_state & CS_BAD_CHKSUM)
+           errmsg( "CMOS RAM checksum is bad. Run SETUP." );
+       if (cmos_state & CS_BAD_TIME)
+           errmsg( "Time invalid in CMOS RAM. Reset clock." );
+       exit(1);
+  }
+
+  /* Process options. */
+  while (argc > 1) {
+       char *p = *++argv;
+
+       if (*p++ != '-') usage();
+
+       while (*p != 0) {
+               switch (*p++) {
+               case 'n':       nflag = 1;      break;
+               case 'w':       wflag = 1;      break;
+               case 'W':       Wflag = 1;      break;
+               case '2':       y2kflag = 1;    break;
+               default:        usage();
+               }
+       }
+       argc--;
+  }
+  if (Wflag) wflag = 1;                /* -W implies -w */
+
+#if 0
+  /* The hardware clock may run in a different time zone, likely GMT or
+   * winter time.  Select that time zone.
+   */
+  strcpy(clocktz, "TZ=");
+  sysgetenv.key = "TZ";
+  sysgetenv.keylen = 2+1;
+  sysgetenv.val = clocktz+3;
+  sysgetenv.vallen = sizeof(clocktz)-3;
+  if (svrctl(SYSGETENV, &sysgetenv) == 0) {
+       putenv(clocktz);
+       tzset();
+  }
+#endif
+
+  /* Read the CMOS real time clock. */
+  for (i = 0; i < 10; i++) {
+       get_time(&time1);
+       now = time(NULL);
+
+       time1.tm_isdst = -1;    /* Do timezone calculations. */
+       time2 = time1;
+
+       rtc= mktime(&time1);    /* Transform to a time_t. */
+       if (rtc != -1) break;
+
+       printf(
+"readclock: Invalid time read from CMOS RTC: %d-%02d-%02d %02d:%02d:%02d\n",
+               time2.tm_year+1900, time2.tm_mon+1, time2.tm_mday,
+               time2.tm_hour, time2.tm_min, time2.tm_sec);
+       sleep(5);
+  }
+  if (i == 10) exit(1);
+
+  if (!wflag) {
+       /* Set system time. */
+       if (nflag) {
+               printf("stime(%lu)\n", (unsigned long) rtc);
+       } else {
+               if (stime(&rtc) < 0) {
+                       errmsg( "Not allowed to set time." );
+                       exit(1);
+               }
+       }
+       tmnow = *localtime(&rtc);
+       if (strftime(date, sizeof(date),
+                               "%a %b %d %H:%M:%S %Z %Y", &tmnow) != 0) {
+               if (date[8] == '0') date[8]= ' ';
+               printf("%s\n", date);
+       }
+  } else {
+       /* Set the CMOS clock to the system time. */
+       tmnow = *localtime(&now);
+       if (nflag) {
+               printf("%04d-%02d-%02d %02d:%02d:%02d\n",
+                       tmnow.tm_year + 1900,
+                       tmnow.tm_mon + 1,
+                       tmnow.tm_mday,
+                       tmnow.tm_hour,
+                       tmnow.tm_min,
+                       tmnow.tm_sec);
+       } else {
+               set_time(&tmnow);
+       }
+  }
+  exit(0);
+}
+
+void errmsg(char *s)
+{
+  static char *prompt = "readclock: ";
+
+  printf("%s%s\n", prompt, s);
+  prompt = "";
+}
+
+
+/***********************************************************************/
+/*                                                                     */
+/*    get_time( time )                                                 */
+/*                                                                     */
+/*    Update the structure pointed to by time with the current time    */
+/*    as read from CMOS RAM of the RTC.                                       */
+/*    If necessary, the time is converted into a binary format before  */
+/*    being stored in the structure.                                   */
+/*                                                                     */
+/***********************************************************************/
+
+int dead;
+void timeout(int sig) { dead= 1; }
+
+void get_time(struct tm *t)
+{
+  int osec, n;
+  unsigned long i;
+  struct sigaction sa;
+
+  /* Start a timer to keep us from getting stuck on a dead clock. */
+  sigemptyset(&sa.sa_mask);
+  sa.sa_flags = 0;
+  sa.sa_handler = timeout;
+  sigaction(SIGALRM, &sa, NULL);
+  dead = 0;
+  alarm(5);
+
+  do {
+       osec = -1;
+       n = 0;
+       do {
+               if (dead) {
+                       printf("readclock: CMOS clock appears dead\n");
+                       exit(1);
+               }
+
+               /* Clock update in progress? */
+               if (read_register(RTC_REG_A) & RTC_A_UIP) continue;
+
+               t->tm_sec = read_register(RTC_SEC);
+               if (t->tm_sec != osec) {
+                       /* Seconds changed.  First from -1, then because the
+                        * clock ticked, which is what we're waiting for to
+                        * get a precise reading.
+                        */
+                       osec = t->tm_sec;
+                       n++;
+               }
+       } while (n < 2);
+
+       /* Read the other registers. */
+       t->tm_min = read_register(RTC_MIN);
+       t->tm_hour = read_register(RTC_HOUR);
+       t->tm_mday = read_register(RTC_MDAY);
+       t->tm_mon = read_register(RTC_MONTH);
+       t->tm_year = read_register(RTC_YEAR);
+
+       /* Time stable? */
+  } while (read_register(RTC_SEC) != t->tm_sec
+       || read_register(RTC_MIN) != t->tm_min
+       || read_register(RTC_HOUR) != t->tm_hour
+       || read_register(RTC_MDAY) != t->tm_mday
+       || read_register(RTC_MONTH) != t->tm_mon
+       || read_register(RTC_YEAR) != t->tm_year);
+
+  if ((read_register(RTC_REG_B) & RTC_B_DM_BCD) == 0) {
+       /* Convert BCD to binary (default RTC mode). */
+       t->tm_year = bcd_to_dec(t->tm_year);
+       t->tm_mon = bcd_to_dec(t->tm_mon);
+       t->tm_mday = bcd_to_dec(t->tm_mday);
+       t->tm_hour = bcd_to_dec(t->tm_hour);
+       t->tm_min = bcd_to_dec(t->tm_min);
+       t->tm_sec = bcd_to_dec(t->tm_sec);
+  }
+  t->tm_mon--; /* Counts from 0. */
+
+  /* Correct the year, good until 2080. */
+  if (t->tm_year < 80) t->tm_year += 100;
+
+  if (y2kflag) {
+       /* Clock with Y2K bug, interpret 1980 as 2000, good until 2020. */
+       if (t->tm_year < 100) t->tm_year += 20;
+  }
+}
+
+
+int read_register(int reg_addr)
+{
+  u32_t r;
+
+  if(sys_outb(RTC_INDEX, reg_addr) != OK) {
+       printf("cmos: outb failed of %x\n", RTC_INDEX);
+       exit(1);
+  }
+  if(sys_inb(RTC_IO, &r) != OK) {
+       printf("cmos: inb failed of %x (index %x) failed\n", RTC_IO, reg_addr);
+       exit(1);
+  }
+  return r;
+}
+
+
+
+/***********************************************************************/
+/*                                                                     */
+/*    set_time( time )                                                 */
+/*                                                                     */
+/*    Set the CMOS RTC to the time found in the structure.             */
+/*                                                                     */
+/***********************************************************************/
+
+void set_time(struct tm *t)
+{
+  int regA, regB;
+
+  if (Wflag) {
+       /* Set A and B registers to their proper values according to the AT
+        * reference manual.  (For if it gets messed up, but the BIOS doesn't
+        * repair it.)
+        */
+       write_register(RTC_REG_A, RTC_A_DV_OK | RTC_A_RS_DEF);
+       write_register(RTC_REG_B, RTC_B_24);
+  }
+
+  /* Inhibit updates. */
+  regB= read_register(RTC_REG_B);
+  write_register(RTC_REG_B, regB | RTC_B_SET);
+
+  t->tm_mon++; /* Counts from 1. */
+
+  if (y2kflag) {
+       /* Set the clock back 20 years to avoid Y2K bug, good until 2020. */
+       if (t->tm_year >= 100) t->tm_year -= 20;
+  }
+
+  if ((regB & 0x04) == 0) {
+       /* Convert binary to BCD (default RTC mode) */
+       t->tm_year = dec_to_bcd(t->tm_year % 100);
+       t->tm_mon = dec_to_bcd(t->tm_mon);
+       t->tm_mday = dec_to_bcd(t->tm_mday);
+       t->tm_hour = dec_to_bcd(t->tm_hour);
+       t->tm_min = dec_to_bcd(t->tm_min);
+       t->tm_sec = dec_to_bcd(t->tm_sec);
+  }
+  write_register(RTC_YEAR, t->tm_year);
+  write_register(RTC_MONTH, t->tm_mon);
+  write_register(RTC_MDAY, t->tm_mday);
+  write_register(RTC_HOUR, t->tm_hour);
+  write_register(RTC_MIN, t->tm_min);
+  write_register(RTC_SEC, t->tm_sec);
+
+  /* Stop the clock. */
+  regA= read_register(RTC_REG_A);
+  write_register(RTC_REG_A, regA | RTC_A_DV_STOP);
+
+  /* Allow updates and restart the clock. */
+  write_register(RTC_REG_B, regB);
+  write_register(RTC_REG_A, regA);
+}
+
+
+void write_register(int reg_addr, int value)
+{
+  if(sys_outb(RTC_INDEX, reg_addr) != OK) {
+       printf("cmos: outb failed of %x\n", RTC_INDEX);
+       exit(1);
+  }
+  if(sys_outb(RTC_IO, value) != OK) {
+       printf("cmos: outb failed of %x (index %x)\n", RTC_IO, reg_addr);
+       exit(1);
+  }
+}
+
+int bcd_to_dec(int n)
+{
+  return ((n >> 4) & 0x0F) * 10 + (n & 0x0F);
+}
+
+int dec_to_bcd(int n)
+{
+  return ((n / 10) << 4) | (n % 10);
+}
+
+void usage(void)
+{
+  printf("Usage: readclock [-nwW2]\n");
+  exit(1);
+}
index 2bbb49fe5f81b8e3c5a161e4248b1c84f20e9350..331e02d72193feb1714ff71fb9af93dc9cf34f56 100644 (file)
@@ -1,7 +1,7 @@
 
 ETC=/etc/
 USRETC=/usr/etc/
-FILES1=fstab group hostname.file inet.conf motd.install mtab passwd profile protocols rc services termcap ttytab utmp rc.cd binary_sizes binary_sizes.big binary_sizes.xxl rc.rescue syslog.conf rc.daemons.dist rs.single make.conf
+FILES1=fstab group hostname.file inet.conf motd.install mtab passwd profile protocols rc services termcap ttytab utmp rc.cd binary_sizes binary_sizes.big binary_sizes.xxl rc.rescue syslog.conf rc.daemons.dist rs.single make.conf drivers.conf
 FILES2=shadow
 FILES3=daily dhcptags.conf rc
 
index 1e5f1eede1dfb4bcf9b3766c28e8af335eea5771..978d462db3e48a9e25baa95c50a35c47a57494a7 100644 (file)
@@ -73,16 +73,18 @@ driver random
        ;
 };
 
-driver cmos
+driver readclock.drv
 {
        io      70:2;
        system
                DEVIO           # 21
                TIMES           # 25
                SAFECOPYTO      # 32
+               SAFECOPYFROM    # 32
                SETGRANT        # 34
                READBIOS        # 35
        ;
+       uid 0;
 };
 
 driver is
diff --git a/etc/rc b/etc/rc
index 5a91a19e01f4b201ae946f6741a74ac5fbda477c..2578ad5a2c47b593ed5bdb92c42d4e93360536d4 100755 (executable)
--- a/etc/rc
+++ b/etc/rc
@@ -49,7 +49,6 @@ start)
     test -f /etc/keymap && loadkeys /etc/keymap
 
     up is -period 5HZ
-    up cmos -dev /dev/cmos -period 5HZ
     echo .
 
     # Set timezone.