Check if kernel calls is allowed (from process' call mask) added. Not yet
enforced. If a call is denied, this will be kprinted. Please report any such errors, so that I can adjust the mask before returning errors instead of warnings. Wrote CMOS driver. All CMOS code from FS has been removed. Currently the driver only supports get time calls. Set time is left out as an exercise for the book readers ... startup scripts were updated because the CMOS driver is needed early on. (IS got same treatment.) Don't forget to run MAKEDEV cmos in /dev/, otherwise the driver cannot be loaded.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -1,160 +0,0 @@
|
||||
#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.
|
||||
* 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
|
||||
*/
|
||||
|
||||
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));
|
||||
|
||||
|
||||
|
||||
PUBLIC int do_cmostime(void)
|
||||
{
|
||||
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.
|
||||
*/
|
||||
sys_vircopy(SELF, BIOS_SEG, (vir_bytes) MACHINE_ID_ADDR,
|
||||
SELF, D, (vir_bytes) &mach_id, MACHINE_ID_SIZE);
|
||||
if (mach_id != PS_386_MACHINE && mach_id != PC_AT_MACHINE) {
|
||||
printf("IS: 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);
|
||||
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. */
|
||||
int r = 0;
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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) );
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 $? $@
|
||||
|
||||
|
||||
@@ -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; 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");
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user