Removed 'system process' magic from PM and FS.

This commit is contained in:
Jorrit Herder 2005-05-13 08:57:08 +00:00
parent 2ed3e3d79a
commit 1ecc6bf3b3
33 changed files with 322 additions and 502 deletions

View file

@ -125,6 +125,7 @@ char **argv;
kill(1, SIGTERM);
/* Give everybody a chance to die peacefully. */
printf("Sending SIGTERM to all processes ...\n");
kill(-1, SIGTERM);
sleep(3);
}

View file

@ -235,7 +235,6 @@ PRIVATE struct driver w_dtab = {
w_geometry, /* tell the geometry of the disk */
nop_stop, /* no cleanup needed on shutdown */
nop_alarm, /* ignore leftover alarms */
nop_stats, /* drivers statistics */
};
@ -244,10 +243,6 @@ PRIVATE struct driver w_dtab = {
*===========================================================================*/
PUBLIC void main()
{
int s;
/* Register function key for debugging dumps. */
fkey_enable(SF8);
/* Set special disk parameters then call the generic main loop. */
init_params();
driver_task(&w_dtab);

View file

@ -65,10 +65,6 @@ FORWARD _PROTOTYPE( void init_buffer, (void) );
FORWARD _PROTOTYPE( int do_rdwt, (struct driver *dr, message *mp) );
FORWARD _PROTOTYPE( int do_vrdwt, (struct driver *dr, message *mp) );
PRIVATE unsigned long dev_read_count;
PRIVATE unsigned long dev_write_count;
PRIVATE unsigned long dev_gather_count;
PRIVATE unsigned long dev_scatter_count;
/*===========================================================================*
* driver_task *
@ -102,12 +98,10 @@ struct driver *dp; /* Device dependent entry points. */
case DEV_CLOSE: r = (*dp->dr_close)(dp, &mess); break;
case DEV_IOCTL: r = (*dp->dr_ioctl)(dp, &mess); break;
case DEV_READ: dev_read_count ++;
case DEV_WRITE: dev_write_count ++;
r = do_rdwt(dp, &mess); break;
case DEV_GATHER: dev_gather_count ++;
case DEV_SCATTER: dev_scatter_count ++;
r = do_vrdwt(dp, &mess); break;
case DEV_READ:
case DEV_WRITE: r = do_rdwt(dp, &mess); break;
case DEV_GATHER:
case DEV_SCATTER: r = do_vrdwt(dp, &mess); break;
case HARD_INT: /* leftover interrupt or expired timer. */
continue;
@ -313,20 +307,6 @@ PUBLIC void nop_cleanup()
/* Nothing to clean up. */
}
/*===========================================================================*
* nop_stats *
*===========================================================================*/
PUBLIC void nop_stats(dp, m_ptr)
struct driver *dp;
message *m_ptr;
{
/* Dump message counts. */
printf("Driver shared code statistics for %s\n", (*dp->dr_name)());
printf("DEV_READ %10u\n", dev_read_count);
printf("DEV_WRITE %10u\n", dev_write_count);
printf("DEV_GATHER %10u\n", dev_gather_count);
printf("DEV_SCATTER %10u\n", dev_scatter_count);
}
/*===========================================================================*
* nop_task *

View file

@ -66,7 +66,6 @@ _PROTOTYPE( void nop_cleanup, (void) );
_PROTOTYPE( void nop_task, (void) );
_PROTOTYPE( void nop_stop, (struct driver *dp) );
_PROTOTYPE( void nop_alarm, (struct driver *dp) );
_PROTOTYPE( void nop_stats, (struct driver *dp, message *m_ptr) );
_PROTOTYPE( int do_diocntl, (struct driver *dp, message *m_ptr) );
/* Parameters for the disk drive. */

View file

@ -69,9 +69,4 @@
#define CMOSTIME 78
#define GETSYSINFO 79 /* to MM or FS */
#if ENABLE_MESSAGE_STATS
#define MSTATS 80
#endif
#define SETCACHE 81
#define FSTATFS 82
#define FSTATFS 82

View file

@ -55,9 +55,6 @@
#define USR8139 (PRINTER + ENABLE_RTL8139) /* Realtek RTL8139 */
#define INIT_PROC_NR (USR8139 + 1) /* init -- goes multiuser */
/* Number of first user process not part of the operating system. */
#define LOW_USER INIT_PROC_NR
/* Number of processes contained in the system image. */
#define IMAGE_SIZE (NR_TASKS + \
5 + ENABLE_AT_WINI + ENABLE_FLOPPY + \
@ -353,13 +350,13 @@
/* Field names for SYS_TRACE, SYS_SVRCTL. */
#define CTL_PROC_NR m2_i1 /* process number of the caller */
#define CTL_REQUEST m2_i2 /* server control request */
#define CTL_MM_PRIV m2_i3 /* privilege as seen by MM */
#define CTL_MM_PRIV m2_i3 /* privilege as seen by PM */
#define CTL_ARG_PTR m2_p1 /* pointer to argument */
#define CTL_ADDRESS m2_l1 /* address at traced process' space */
#define CTL_DATA m2_l2 /* data field for tracing */
/* Field names for SYS_KILL, SYS_SIGCTL */
#define SIG_REQUEST m2_l2 /* MM signal control request */
#define SIG_REQUEST m2_l2 /* PM signal control request */
#define S_GETSIG 0 /* get pending kernel signal */
#define S_ENDSIG 1 /* finish a kernel signal */
#define S_SENDSIG 2 /* POSIX style signal handling */
@ -374,11 +371,11 @@
/* Field names for SYS_FORK, _EXEC, _XIT, _GETSP, _GETMAP, _NEWMAP */
#define PR_PROC_NR m1_i1 /* indicates a (child) process */
#define PR_PPROC_NR m1_i2 /* indicates a (parent) process */
#define PR_PID m1_i3 /* process id at process manager */
#define PR_STACK_PTR m1_p1 /* used for stack ptr in sys_exec, sys_getsp */
#define PR_TRACING m1_i3 /* flag to indicate tracing is on/ off */
#define PR_NAME_PTR m1_p2 /* tells where program name is for dmp */
#define PR_IP_PTR m1_p3 /* initial value for ip after exec */
#define PR_PID m1_i3 /* process id passed from MM to kernel */
#define PR_MEM_PTR m1_p1 /* tells where memory map is for sys_newmap */

View file

@ -77,7 +77,7 @@ PUBLIC void main()
for (i=0; i < IMAGE_SIZE; ++i) {
ttp = &image[i]; /* t's task attributes */
rp = proc_addr(ttp->proc_nr); /* t's process slot */
kstrncpy(rp->p_name, ttp->name, PROC_NAME_LEN); /* set name */
kstrncpy(rp->p_name, ttp->proc_name, PROC_NAME_LEN); /* set name */
rp->p_type = ttp->type; /* type of process */
rp->p_priority = ttp->priority; /* scheduling priority */
rp->p_sendmask = ttp->sendmask; /* sendmask protection */

View file

@ -1,8 +1,6 @@
/* Definition of the 'p_sendmask' bit mask used in the process table. The bit
* mask of process is checked in mini_send() to see if the caller is allowed
* to send to the destination. The bit masks accomodate bits for NR_TASKS +
* (LOW_USER+1) + 1. This means that there are bits for each task, driver, and
* server process, INIT, and one bit to represent all ordinary user processes.
* to send to the destination.
*
* PLEASE NOTE: the send masks definitions are a mess and must be updated!!!
* this will be done when dynamic driver loading is implemented
@ -19,8 +17,8 @@
/* Constants to support the bitmask operations. */
#define BIT_0 (send_mask_t) 1
#define MASK_ENTRIES NR_TASKS + (LOW_USER+1) + 1
#define USER_PROC_NR LOW_USER+1 /* used to set bit for user procs */
#define MASK_ENTRIES NR_TASKS + (INIT_PROC_NR+1) + 1
#define USER_PROC_NR INIT_PROC_NR+1 /* used to set bit for user procs */
#define ALLOW_ALL_MASK (send_mask_t) -1
#define DENY_ALL_MASK (send_mask_t) 0

View file

@ -18,7 +18,7 @@ struct system_image {
int priority; /* scheduling priority */
int stksize; /* stack size for tasks */
send_mask_t sendmask; /* send mask protection */
char name[PROC_NAME_LEN]; /* name in process table */
char proc_name[PROC_NAME_LEN]; /* name in process table */
};
struct memory {

View file

@ -159,10 +159,7 @@ int flags; /* mode bits and flags */
if (!fp->fp_sesldr || fp->fp_tty != 0) {
flags |= O_NOCTTY;
} else {
for (rfp = &fproc[LOW_USER]; rfp < &fproc[NR_PROCS]; rfp++) {
#if FUTURE_CODE /* check for all processes later */
for (rfp = &fproc[0]; rfp < &fproc[NR_PROCS]; rfp++) {
#endif
if (rfp->fp_tty == dev) flags |= O_NOCTTY;
}
}

View file

@ -47,13 +47,13 @@ PRIVATE void fproc_dmp()
static int prev_i;
printf("PROCESS TABLE (beta)\n");
printf("-pid- -tty- -umask- --uid-- --gid-- -ldr- -sus-rev-proc- -cloexec-\n");
printf("-nr- -pid- -tty- -umask- --uid-- --gid-- -ldr- -sus-rev-proc- -cloexec-\n");
for (i=prev_i; i<NR_PROCS; i++) {
fp = &fproc[i];
if (fp->fp_pid <= 0) continue;
if (++n > 22) break;
printf("%4d %2d/%d 0x%05x %2d (%d) %2d (%d) %3d %3d %3d %4d 0x%05x\n",
fp->fp_pid,
printf("%3d %4d %2d/%d 0x%05x %2d (%d) %2d (%d) %3d %3d %3d %4d 0x%05x\n",
i, fp->fp_pid,
((fp->fp_tty>>MAJOR)&BYTE), ((fp->fp_tty>>MINOR)&BYTE),
fp->fp_umask,
fp->fp_realuid, fp->fp_effuid, fp->fp_realgid, fp->fp_effgid,

View file

@ -23,6 +23,7 @@ struct super_block; /* proto.h needs to know this */
#include <minix/callnr.h>
#include <minix/com.h>
#include <minix/keymap.h>
#include <minix/const.h>
#include "buf.h"
#include "dmap.h"
#include "file.h"
@ -31,6 +32,8 @@ struct super_block; /* proto.h needs to know this */
#include "param.h"
#include "super.h"
FORWARD _PROTOTYPE( void fs_init, (void) );
FORWARD _PROTOTYPE( int igetenv, (char *var) );
FORWARD _PROTOTYPE( void get_work, (void) );
@ -168,11 +171,19 @@ int result; /* result of the call (usually OK or error #) */
PRIVATE void fs_init()
{
/* Initialize global variables, tables, etc. */
register struct inode *rip;
int key, i;
int key, s, i;
message mess;
/* Certain relations must hold for the file system to work at all. Some
* extra block_size requirements are checked at super-block-read-in time.
*/
if (OPEN_MAX > 127) panic("OPEN_MAX > 127", NO_NUM);
if (NR_BUFS < 6) panic("NR_BUFS < 6", NO_NUM);
if (V1_INODE_SIZE != 32) panic("V1 inode size != 32", NO_NUM);
if (V2_INODE_SIZE != 64) panic("V2 inode size != 64", NO_NUM);
if (OPEN_MAX > 8 * sizeof(long)) panic("Too few bits in fp_cloexec", NO_NUM);
/* The following initializations are needed to let dev_opcl succeed .*/
fp = (struct fproc *) NULL;
who = FS_PROC_NR;
@ -182,45 +193,38 @@ PRIVATE void fs_init()
load_ram(); /* init RAM disk, load if it is root */
load_super(root_dev); /* load super block for root device */
/* Initialize the 'fproc' fields for process 0 .. INIT. */
for (i = 0; i <= LOW_USER; i+= 1) {
if (i == FS_PROC_NR) continue; /* do not initialize FS */
fp = &fproc[i];
/* Initialize the process table with help of the process manager messages.
* Expect one message for each system process with its slot number and pid.
* When no more processes follow, the magic process number NONE is sent.
* Then, stop and synchronize with the PM.
*/
do {
if (OK != (s=receive(PM_PROC_NR, &mess)))
panic("FS couldn't receive from PM", s);
if (NONE == mess.PR_PROC_NR) break;
fp = &fproc[mess.PR_PROC_NR];
fp->fp_pid = mess.PR_PID;
rip = get_inode(root_dev, ROOT_INODE);
fp->fp_rootdir = rip;
dup_inode(rip);
fp->fp_rootdir = rip;
fp->fp_workdir = rip;
fp->fp_realuid = (uid_t) SYS_UID;
fp->fp_effuid = (uid_t) SYS_UID;
fp->fp_realgid = (gid_t) SYS_GID;
fp->fp_effgid = (gid_t) SYS_GID;
fp->fp_umask = ~0;
fp->fp_pid = i < LOW_USER ? PID_SERVER : 1;
}
/* Certain relations must hold for the file system to work at all.
* (Some extra block_size requirements are checked at super-block-read-in
* time.)
*/
if (OPEN_MAX > 127) panic("OPEN_MAX > 127", NO_NUM);
if (NR_BUFS < 6) panic("NR_BUFS < 6", NO_NUM);
if (V1_INODE_SIZE != 32) panic("V1 inode size != 32", NO_NUM);
if (V2_INODE_SIZE != 64) panic("V2 inode size != 64", NO_NUM);
if (OPEN_MAX > 8 * sizeof(long)) panic("Too few bits in fp_cloexec", NO_NUM);
/* Tell the memory task where my process table is for the sake of ps(1). */
mess.m_type = DEV_IOCTL;
mess.PROC_NR = FS_PROC_NR;
mess.DEVICE = RAM_DEV;
mess.REQUEST = MIOCSPSINFO;
mess.ADDRESS = (void *) fproc;
(void) sendrec(MEMORY, &mess);
} while (TRUE); /* continue until process NONE */
mess.m_type = OK; /* tell PM that we succeeded */
s=send(PM_PROC_NR, &mess); /* send synchronization message */
/* Register function keys with TTY. */
for (key=SF5; key<=SF6; key++) {
if ((i=fkey_enable(key))!=OK) {
printf("Warning: FS couldn't register Shift+F%d key: %d\n",
SF1-key+1, i);
key-SF1+1, i);
}
}
}
@ -305,10 +309,6 @@ PRIVATE void load_ram(void)
if (sendrec(MEMORY, &m_out) != OK || m_out.REP_STATUS != OK)
panic("Can't set RAM disk size", NO_NUM);
/* Tell PM the RAM disk size, and wait for it to come "on-line". */
m_out.MEM_CHUNK_SIZE = ((long) ram_size_kb * 1024) >> CLICK_SHIFT;
if (sendrec(PM_PROC_NR, &m_out) != OK)
panic("FS can't sync up with PM", NO_NUM);
#if ENABLE_CACHE2
/* The RAM disk is a second level block cache while not otherwise used. */

View file

@ -1,6 +0,0 @@
#!/bin/sh
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
echo "struct fs_sym_entry { unsigned long symoffset; char *symname; } fs_sym_entries[] = {" >$1
nm -n fs | grep -v "^fs:$" | grep ' [tT] ' | awk '{ print "{ 0x" $1 ", \"" $3 "\" }, " }' >>$1
echo "};" >>$1

View file

@ -314,7 +314,7 @@ PUBLIC int do_exit()
if (fp->fp_tty == 0) return(OK); /* no controlling tty */
dev = fp->fp_tty;
for (rfp = &fproc[LOW_USER]; rfp < &fproc[NR_PROCS]; rfp++) {
for (rfp = &fproc[0]; rfp < &fproc[NR_PROCS]; rfp++) {
if (rfp->fp_tty == dev) rfp->fp_tty = 0;
for (i = 0; i < OPEN_MAX; i++) {
@ -364,18 +364,16 @@ PUBLIC int do_set()
*===========================================================================*/
PUBLIC int do_revive()
{
/* A task, typically TTY, has now gotten the characters that were needed for a
* previous read. The process did not get a reply when it made the call.
/* A driver, typically TTY, has now gotten the characters that were needed for
* a previous read. The process did not get a reply when it made the call.
* Instead it was suspended. Now we can send the reply to wake it up. This
* business has to be done carefully, since the incoming message is from
* a task (to which no reply can be sent), and the reply must go to a process
* a driver (to which no reply can be sent), and the reply must go to a process
* that blocked earlier. The reply to the caller is inhibited by returning the
* 'SUSPEND' pseudo error, and the reply to the blocked process is done
* explicitly in revive().
*/
if (who >= LOW_USER && fp->fp_pid != PID_SERVER) return(EPERM);
revive(m_in.REP_PROC_NR, m_in.REP_STATUS);
return(SUSPEND); /* don't reply to the TTY task */
}
@ -402,9 +400,12 @@ PUBLIC int do_svrctl()
/* Try to update device mapping. */
major = (device.dev >> MAJOR) & BYTE;
r=map_driver(major, who, device.style);
return(r);
#if DEAD_CODE
if ((r=map_driver(major, who, device.style)) == OK)
fp->fp_pid = PID_SERVER;
return(r);
#endif
}
default:
return(EINVAL);

View file

@ -1,200 +0,0 @@
struct fs_sym_entry { unsigned long symoffset; char *symname; } fs_sym_entries[] = {
{ 0x00000000, "" },
{ 0x00000000, "begtext" },
{ 0x00000000, "crtso" },
{ 0x00000050, "___main" },
{ 0x00000054, "_main" },
{ 0x0000010d, "_get_wor" },
{ 0x000001dc, "_buf_poo" },
{ 0x00000282, "_reply" },
{ 0x000002ba, "_fs_init" },
{ 0x0000041a, "_igetenv" },
{ 0x0000044e, "_load_ra" },
{ 0x00000756, "_load_su" },
{ 0x000007f8, "_do_crea" },
{ 0x0000083c, "_do_open" },
{ 0x000008a7, "_common_" },
{ 0x00000b76, "_new_nod" },
{ 0x00000c6e, "_pipe_op" },
{ 0x00000cf7, "_do_mkno" },
{ 0x00000da6, "_do_mkdi" },
{ 0x00000f28, "_do_clos" },
{ 0x000010a6, "_do_lsee" },
{ 0x00001160, "_do_read" },
{ 0x0000116d, "_read_wr" },
{ 0x0000164a, "_rw_chun" },
{ 0x000017ee, "_read_ma" },
{ 0x0000194d, "_rd_indi" },
{ 0x000019d2, "_read_ah" },
{ 0x00001a36, "_rahead" },
{ 0x00001bdc, "_do_writ" },
{ 0x00001be9, "_write_m" },
{ 0x00001e0b, "_wr_indi" },
{ 0x00001e5f, "_clear_z" },
{ 0x00001f29, "_new_blo" },
{ 0x00002028, "_zero_bl" },
{ 0x0000205c, "_do_pipe" },
{ 0x000021d1, "_pipe_ch" },
{ 0x0000234d, "_suspend" },
{ 0x000023de, "_release" },
{ 0x0000244c, "_revive" },
{ 0x000024df, "_do_unpa" },
{ 0x000025f0, "_map_dri" },
{ 0x0000268d, "_map_con" },
{ 0x000027b4, "_do_fkey" },
{ 0x000027f7, "_fproc_d" },
{ 0x000028c5, "_dtab_dm" },
{ 0x000029f4, "_dev_ope" },
{ 0x00002a51, "_dev_clo" },
{ 0x00002a79, "_dev_io" },
{ 0x00002b2d, "_gen_opc" },
{ 0x00002b77, "_tty_opc" },
{ 0x00002bfa, "_ctty_op" },
{ 0x00002c16, "_do_sets" },
{ 0x00002c4a, "_do_ioct" },
{ 0x00002ccb, "_gen_io" },
{ 0x00002da1, "_ctty_io" },
{ 0x00002dfb, "_no_dev" },
{ 0x00002e05, "_clone_o" },
{ 0x00002ef8, "_eat_pat" },
{ 0x00002f3d, "_last_di" },
{ 0x00003009, "_get_nam" },
{ 0x000030a3, "_advance" },
{ 0x00003237, "_search_" },
{ 0x000035a0, "_do_moun" },
{ 0x0000394a, "_do_umou" },
{ 0x000039ab, "_unmount" },
{ 0x00003a68, "_name_to" },
{ 0x00003aec, "_do_link" },
{ 0x00003c76, "_do_unli" },
{ 0x00003d86, "_do_rena" },
{ 0x00004194, "_truncat" },
{ 0x000042f0, "_remove_" },
{ 0x000043bd, "_unlink_" },
{ 0x0000445c, "_alloc_b" },
{ 0x0000464f, "_free_bi" },
{ 0x00004782, "_get_sup" },
{ 0x000047d7, "_get_blo" },
{ 0x0000481f, "_mounted" },
{ 0x0000486f, "_read_su" },
{ 0x00004b2c, "_get_ino" },
{ 0x00004bab, "_put_ino" },
{ 0x00004c0c, "_alloc_i" },
{ 0x00004d16, "_wipe_in" },
{ 0x00004d45, "_free_in" },
{ 0x00004d7f, "_update_" },
{ 0x00004dc0, "_rw_inod" },
{ 0x00004ede, "_old_ico" },
{ 0x00005030, "_new_ico" },
{ 0x000051f2, "_dup_ino" },
{ 0x00005200, "_get_blo" },
{ 0x0000537c, "_put_blo" },
{ 0x00005454, "_alloc_z" },
{ 0x00005506, "_free_zo" },
{ 0x0000554d, "_rw_bloc" },
{ 0x0000561c, "_invalid" },
{ 0x00005650, "_flushal" },
{ 0x000056ae, "_rw_scat" },
{ 0x000058c7, "_rm_lru" },
{ 0x0000590c, "_get_fd" },
{ 0x00005989, "_get_fil" },
{ 0x000059b7, "_find_fi" },
{ 0x000059f0, "_do_chdi" },
{ 0x00005abb, "_do_chro" },
{ 0x00005af4, "_change" },
{ 0x00005b78, "_do_stat" },
{ 0x00005bd6, "_do_fsta" },
{ 0x00005c08, "_stat_in" },
{ 0x00005d00, "_do_fsta" },
{ 0x00005d54, "_do_chmo" },
{ 0x00005e41, "_do_chow" },
{ 0x00005f29, "_do_umas" },
{ 0x00005f66, "_do_acce" },
{ 0x00005fe3, "_forbidd" },
{ 0x00006149, "_read_on" },
{ 0x00006168, "_do_utim" },
{ 0x0000624e, "_do_time" },
{ 0x0000625f, "_do_stim" },
{ 0x000062bd, "_do_tims" },
{ 0x00006308, "_do_cmos" },
{ 0x00006404, "_get_cmo" },
{ 0x00006594, "_read_re" },
{ 0x000065c5, "_bcd_to_" },
{ 0x000065e2, "_dec_to_" },
{ 0x00006604, "_lock_op" },
{ 0x000069d3, "_lock_re" },
{ 0x00006a20, "_do_gets" },
{ 0x00006a27, "_do_dup" },
{ 0x00006ad0, "_do_fcnt" },
{ 0x00006c0e, "_do_sync" },
{ 0x00006c99, "_do_rebo" },
{ 0x00006d1a, "_do_fork" },
{ 0x00006dc6, "_do_exec" },
{ 0x00006e21, "_do_exit" },
{ 0x00006fc5, "_do_set" },
{ 0x0000702f, "_do_revi" },
{ 0x00007068, "_do_svrc" },
{ 0x0000710c, "_clock_t" },
{ 0x00007151, "_fetch_n" },
{ 0x000071e3, "_no_sys" },
{ 0x000071ed, "_panic" },
{ 0x0000727f, "_conv2" },
{ 0x000072a9, "_conv4" },
{ 0x000072f8, "_printf" },
{ 0x00007610, "_kputc" },
{ 0x000076bc, "_sys_abo" },
{ 0x00007708, "_sys_exi" },
{ 0x00007728, "_sys_get" },
{ 0x00007768, "_sys_in" },
{ 0x000077a4, "_sys_kil" },
{ 0x000077c8, "_sys_out" },
{ 0x000077fc, "_sys_vir" },
{ 0x0000784c, "__taskca" },
{ 0x00007878, "_clk_fla" },
{ 0x000078c0, "_clk_tim" },
{ 0x00007908, "_fkey_ct" },
{ 0x0000792c, "_server_" },
{ 0x00007968, "_atoi" },
{ 0x00007980, "__calls" },
{ 0x00007999, "_exit" },
{ 0x000079bc, "_strtol" },
{ 0x000079d7, "_strtoul" },
{ 0x000079f2, "_string2" },
{ 0x00007b8c, "__exit" },
{ 0x00007b94, "__send" },
{ 0x00007ba8, "__nb_sen" },
{ 0x00007bbc, "__receiv" },
{ 0x00007bd0, "__nb_rec" },
{ 0x00007be4, "__sendre" },
{ 0x00007bf8, "_memcpy" },
{ 0x00007c18, "_memset" },
{ 0x00007c3c, "slword" },
{ 0x00007c52, "sword" },
{ 0x00007c5b, "sbyte" },
{ 0x00007c5d, "done" },
{ 0x00007c68, "_strcmp" },
{ 0x00007c78, "_strlen" },
{ 0x00007c88, "_strncmp" },
{ 0x00007c98, "___exit" },
{ 0x00007cb8, "__memmov" },
{ 0x00007cce, "__memcpy" },
{ 0x00007ce0, "uplword" },
{ 0x00007ced, "upword" },
{ 0x00007cf4, "upbyte" },
{ 0x00007cf6, "done" },
{ 0x00007cfd, "downward" },
{ 0x00007d18, "__strncm" },
{ 0x00007d28, "compare" },
{ 0x00007d34, "done" },
{ 0x00007d48, "__strnle" },
{ 0x00007d5c, "no0" },
{ 0x00007d68, "__syscal" },
{ 0x00007dac, ".blm" },
{ 0x00007dc4, ".csa4" },
{ 0x00007df0, ".csb4" },
{ 0x00007e18, ".fat" },
{ 0x00007e24, ".stop" },
{ 0x00007e2c, ".trp" },
{ 0x00007e44, "__etext" },
{ 0x00007e44, "endtext" },
};

View file

@ -51,7 +51,6 @@ int flag; /* M3 means path may be in message */
* If 'flag' = M3 and 'len' <= M3_STRING, the path is present in 'message'.
* If it is not, go copy it from user space.
*/
register char *rpu, *rpm;
int r;
@ -87,7 +86,6 @@ int flag; /* M3 means path may be in message */
PUBLIC int no_sys()
{
/* Somebody has used an illegal system call number */
return(EINVAL);
}
@ -125,7 +123,6 @@ int norm; /* TRUE if no swap, FALSE for byte swap */
int w; /* promotion of 16-bit word to be swapped */
{
/* Possibly swap a 16-bit word between 8086 and 68000 byte order. */
if (norm) return( (unsigned) w & 0xFFFF);
return( ((w&BYTE) << 8) | ( (w>>8) & BYTE));
}
@ -139,7 +136,6 @@ int norm; /* TRUE if no swap, FALSE for byte swap */
long x; /* 32-bit long to be byte swapped */
{
/* Possibly swap a 32-bit long between 8086 and 68000 byte order. */
unsigned lo, hi;
long l;
@ -149,3 +145,4 @@ long x; /* 32-bit long to be byte swapped */
l = ( (long) lo <<16) | hi;
return(l);
}

View file

@ -229,11 +229,11 @@ PRIVATE void image_dmp()
printf("---name-- -nr- --type- -priority- ----pc- -stack- ------sendmask-------\n");
for (i=0; i<IMAGE_SIZE; i++) {
ip = &image[i];
for (j=-NR_TASKS; j<LOW_USER+2; j++)
for (j=-NR_TASKS; j<INIT_PROC_NR+2; j++)
maskstr[j+NR_TASKS] = (isallowed(ip->sendmask, j)) ? '1' : '0';
maskstr[j+NR_TASKS] = '\0';
printf("%8s %4d %7s %10s %7lu %7lu %s\n",
ip->name, ip->proc_nr, types[ip->type], priorities[ip->priority],
ip->proc_name, ip->proc_nr, types[ip->type], priorities[ip->priority],
(long)ip->initial_pc, ip->stksize, maskstr);
}
printf("\n");
@ -373,7 +373,7 @@ PRIVATE void sendmask_dmp()
printf("\n\n");
printf(" ");
for (j=proc_number(BEG_PROC_ADDR); j< LOW_USER+1; j++) {
for (j=proc_number(BEG_PROC_ADDR); j< INIT_PROC_NR+1; j++) {
printf("%3d", j);
}
printf(" *\n");
@ -393,7 +393,7 @@ PRIVATE void sendmask_dmp()
default: printf(" %3d ", proc_number(rp));
}
for (j=proc_number(BEG_PROC_ADDR); j<LOW_USER+2; j++) {
for (j=proc_number(BEG_PROC_ADDR); j<INIT_PROC_NR+2; j++) {
if (isallowed(rp->p_sendmask, j)) printf(" 1 ");
else printf(" 0 ");
}

View file

@ -13,7 +13,7 @@ CC = exec cc
CFLAGS = -I$i
LDFLAGS = -i
OBJ = main.o forkexit.o break.o exec.o procutils.o \
OBJ = main.o forkexit.o break.o exec.o dmp.o \
signal.o alloc.o utility.o table.o trace.o getset.o misc.o
# build local binary
@ -32,7 +32,7 @@ clean:
rm -f $(SERVER) *.o *.bak
# dependencies
a = mm.h $h/config.h $s/types.h $h/const.h $h/type.h \
a = pm.h $h/config.h $s/types.h $h/const.h $h/type.h \
$i/ansi.h $i/fcntl.h $i/unistd.h $h/syslib.h \
$i/limits.h $i/errno.h const.h type.h proto.h glo.h
@ -94,12 +94,7 @@ misc.o: $s/svrctl.h
misc.o: mproc.h
misc.o: param.h
procutils.o: $a
procutils.o: $i/timers.h
procutils.o: $i/string.h
procutils.o: $k/const.h
procutils.o: $k/type.h
procutils.o: $k/proc.h
dmp.o: $a
signal.o: $a
signal.o: $s/stat.h
@ -132,3 +127,9 @@ utility.o: $h/com.h
utility.o: $i/fcntl.h
utility.o: $i/signal.h
utility.o: mproc.h
utility.o: $i/timers.h
utility.o: $i/string.h
utility.o: $k/const.h
utility.o: $k/type.h
utility.o: $k/proc.h

View file

@ -3,19 +3,19 @@
* structure used is the hole table, which maintains a list of holes in memory.
* It is kept sorted in order of increasing memory address. The addresses
* it contains refers to physical memory, starting at absolute address 0
* (i.e., they are not relative to the start of MM). During system
* (i.e., they are not relative to the start of PM). During system
* initialization, that part of memory containing the interrupt vectors,
* kernel, and MM are "allocated" to mark them as not available and to
* kernel, and PM are "allocated" to mark them as not available and to
* remove them from the hole list.
*
* The entry points into this file are:
* alloc_mem: allocate a given sized chunk of memory
* free_mem: release a previously allocated chunk of memory
* mem_init: initialize the tables when MM start up
* mem_init: initialize the tables when PM start up
* max_hole: returns the largest hole currently available
*/
#include "mm.h"
#include "pm.h"
#include <minix/com.h>
#include <minix/callnr.h>
#include <signal.h>
@ -40,7 +40,7 @@ PRIVATE u32_t swap_offset; /* offset to start of swap area on swap file */
PRIVATE phys_clicks swap_base; /* memory offset chosen as swap base */
PRIVATE phys_clicks swap_maxsize;/* maximum amount of swap "memory" possible */
PRIVATE struct mproc *in_queue; /* queue of processes wanting to swap in */
PRIVATE struct mproc *outswap = &mproc[LOW_USER]; /* outswap candidate? */
PRIVATE struct mproc *outswap = &mproc[0]; /* outswap candidate? */
#else /* !SWAP */
#define swap_base ((phys_clicks) -1)
#endif /* !SWAP */
@ -219,7 +219,7 @@ phys_clicks *free; /* memory size summaries */
/* Get a copy of the physical memory chunks found at the kernel. */
if ((i=sys_getmemchunks(mem)) != OK)
panic("MM couldn't get mem chunks",i);
panic("PM couldn't get mem chunks",i);
/* Put all holes on the free list. */
for (hp = &hole[0]; hp < &hole[NR_HOLES]; hp++) hp->h_next = hp + 1;
@ -281,13 +281,13 @@ PUBLIC int swap_off()
if (swap_fd == -1) return(OK); /* can't turn off what isn't on */
/* Put all swapped out processes on the inswap queue and swap in. */
for (rmp = &mproc[LOW_USER]; rmp < &mproc[NR_PROCS]; rmp++) {
for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) {
if (rmp->mp_flags & ONSWAP) swap_inqueue(rmp);
}
swap_in();
/* All in memory? */
for (rmp = &mproc[LOW_USER]; rmp < &mproc[NR_PROCS]; rmp++) {
for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) {
if (rmp->mp_flags & ONSWAP) return(ENOMEM);
}
@ -375,7 +375,7 @@ PUBLIC void swap_in()
PRIVATE int swap_out()
{
/* Try to find a process that can be swapped out. Candidates are those blocked
* on a system call that MM handles, like wait(), pause() or sigsuspend().
* on a system call that PM handles, like wait(), pause() or sigsuspend().
*/
struct mproc *rmp;
struct hole *hp, *prev_ptr;
@ -385,13 +385,13 @@ PRIVATE int swap_out()
rmp = outswap;
do {
if (++rmp == &mproc[NR_PROCS]) rmp = &mproc[LOW_USER];
if (++rmp == &mproc[NR_PROCS]) rmp = &mproc[0];
/* A candidate? */
if (!(rmp->mp_flags & (PAUSED | WAITING | SIGSUSPENDED))) continue;
/* Already on swap or otherwise to be avoided? */
if (rmp->mp_flags & (TRACED | REPLY | ONSWAP)) continue;
if (rmp->mp_flags & (DONT_SWAP | TRACED | REPLY | ONSWAP)) continue;
/* Got one, find a swap hole and swap it out. */
proc_nr = (rmp - mproc);

View file

@ -15,7 +15,7 @@
* size_ok: see if the segment sizes are feasible
*/
#include "mm.h"
#include "pm.h"
#include <signal.h>
#include "mproc.h"
#include "param.h"
@ -49,8 +49,8 @@ PUBLIC int do_brk()
return(ENOMEM);
}
new_clicks -= rmp->mp_seg[D].mem_vir;
if ((r=p_getsp(who, &new_sp)) != OK) /* ask kernel for current sp value */
panic("MM couldn't get stack pointer", r);
if ((r=get_stack_ptr(who, &new_sp)) != OK) /* ask kernel for sp value */
panic("PM couldn't get stack pointer", r);
r = adjust(rmp, new_clicks, new_sp);
rmp->mp_reply.reply_ptr = (r == OK ? m_in.addr : (char *) -1);
return(r); /* return new address or -1 */

View file

@ -1,4 +1,4 @@
/* Constants used by the Memory Manager. */
/* Constants used by the Process Manager. */
#define NO_MEM ((phys_clicks) 0) /* returned by alloc_mem() with mem is up */

View file

@ -3,7 +3,7 @@
* - read the header and extract the sizes
* - fetch the initial args and environment from the user space
* - allocate the memory for the new process
* - copy the initial stack from MM to the process
* - copy the initial stack from PM to the process
* - read in the text and data segments and copy to the process
* - take care of setuid and setgid bits
* - fix up 'mproc' table
@ -16,7 +16,7 @@
* find_share: find a process whose text segment can be shared
*/
#include "mm.h"
#include "pm.h"
#include <sys/stat.h>
#include <minix/callnr.h>
#include <minix/com.h>
@ -49,9 +49,8 @@ PUBLIC int do_exec()
{
/* Perform the execve(name, argv, envp) call. The user library builds a
* complete stack image, including pointers, args, environ, etc. The stack
* is copied to a buffer inside MM, and then to the new core image.
* is copied to a buffer inside PM, and then to the new core image.
*/
register struct mproc *rmp;
struct mproc *sh_mp;
int m, r, fd, ft, sn;
@ -122,7 +121,7 @@ PUBLIC int do_exec()
rmp->mp_dev = s_p->st_dev;
rmp->mp_ctime = s_p->st_ctime;
/* Patch up stack and copy it from MM to new core image. */
/* Patch up stack and copy it from PM to new core image. */
vsp = (vir_bytes) rmp->mp_seg[S].mem_vir << CLICK_SHIFT;
vsp += (vir_bytes) rmp->mp_seg[S].mem_len << CLICK_SHIFT;
vsp -= stk_bytes;
@ -389,7 +388,7 @@ phys_bytes tot_bytes; /* total memory to allocate, including gap */
* patch_ptr *
*===========================================================================*/
PRIVATE void patch_ptr(stack, base)
char stack[ARG_MAX]; /* pointer to stack image within MM */
char stack[ARG_MAX]; /* pointer to stack image within PM */
vir_bytes base; /* virtual address of stack base inside user */
{
/* When doing an exec(name, argv, envp) call, the user builds up a stack
@ -422,7 +421,7 @@ vir_bytes base; /* virtual address of stack base inside user */
* insert_arg *
*===========================================================================*/
PRIVATE int insert_arg(stack, stk_bytes, arg, replace)
char stack[ARG_MAX]; /* pointer to stack image within MM */
char stack[ARG_MAX]; /* pointer to stack image within PM */
vir_bytes *stk_bytes; /* size of initial stack */
char *arg; /* argument to prepend/replace as new argv[0] */
int replace;
@ -480,7 +479,7 @@ int replace;
*===========================================================================*/
PRIVATE char *patch_stack(fd, stack, stk_bytes, script)
int fd; /* file descriptor to open script file */
char stack[ARG_MAX]; /* pointer to stack image within MM */
char stack[ARG_MAX]; /* pointer to stack image within PM */
vir_bytes *stk_bytes; /* size of initial stack */
char *script; /* name of script to interpret */
{
@ -538,10 +537,10 @@ phys_bytes seg_bytes0; /* how much is to be transferred? */
* space one at a time. This is too slow, so we do something dirty here,
* namely send the user space and virtual address to the file system in the
* upper 10 bits of the file descriptor, and pass it the user virtual address
* instead of a MM address. The file system extracts these parameters when
* gets a read or write call from the memory manager, which is the only process
* that is permitted to use this trick. The file system then copies the whole
* segment directly to/from user space, bypassing MM completely.
* instead of a PM address. The file system extracts these parameters when
* gets a read or write call from the process manager, which is the only
* process that is permitted to use this trick. The file system then copies
* the whole segment directly to/from user space, bypassing PM completely.
*
* The byte count on read is usually smaller than the segment count, because
* a segment is padded out to a click multiple, and the data segment is only
@ -557,8 +556,8 @@ phys_bytes seg_bytes0; /* how much is to be transferred? */
ubuf_ptr = (char *) ((vir_bytes) sp->mem_vir << CLICK_SHIFT);
while (seg_bytes != 0) {
#define MM_CHUNK_SIZE 8192
bytes = MIN((INT_MAX / MM_CHUNK_SIZE) * MM_CHUNK_SIZE, seg_bytes);
#define PM_CHUNK_SIZE 8192
bytes = MIN((INT_MAX / PM_CHUNK_SIZE) * PM_CHUNK_SIZE, seg_bytes);
if (rw == 0) {
r = read(new_fd, ubuf_ptr, bytes);
} else {
@ -585,8 +584,8 @@ time_t ctime;
* call is made.
*/
struct mproc *sh_mp;
for (sh_mp = &mproc[0]; sh_mp < &mproc[NR_PROCS]; sh_mp++) {
for (sh_mp = &mproc[INIT_PROC_NR]; sh_mp < &mproc[NR_PROCS]; sh_mp++) {
if (!(sh_mp->mp_flags & SEPARATE)) continue;
if (sh_mp == mp_ign) continue;
if (sh_mp->mp_ino != ino) continue;

View file

@ -14,7 +14,7 @@
*/
#include "mm.h"
#include "pm.h"
#include <sys/wait.h>
#include <minix/callnr.h>
#include <minix/com.h>
@ -25,7 +25,6 @@
#define LAST_FEW 2 /* last few slots reserved for superuser */
PRIVATE pid_t next_pid = INIT_PID+1; /* next pid to be assigned */
FORWARD _PROTOTYPE (void cleanup, (register struct mproc *child) );
@ -35,12 +34,12 @@ FORWARD _PROTOTYPE (void cleanup, (register struct mproc *child) );
PUBLIC int do_fork()
{
/* The process pointed to by 'mp' has forked. Create a child process. */
register struct mproc *rmp; /* pointer to parent */
register struct mproc *rmc; /* pointer to child */
int i, child_nr, t;
phys_clicks prog_clicks, child_base;
phys_bytes prog_bytes, parent_abs, child_abs; /* Intel only */
pid_t new_pid;
/* If tables might fill up during FORK, don't even start since recovery half
* way through is such a nuisance.
@ -49,7 +48,7 @@ PUBLIC int do_fork()
if ((procs_in_use == NR_PROCS) ||
(procs_in_use >= NR_PROCS-LAST_FEW && rmp->mp_effuid != 0))
{
printf("MM: proc table full!\n");
printf("PM: proc table full!\n");
return(EAGAIN);
}
@ -90,16 +89,8 @@ PUBLIC int do_fork()
rmc->mp_sigstatus = 0;
/* Find a free pid for the child and put it in the table. */
do {
t = 0; /* 't' = 0 means pid still free */
next_pid = (next_pid < 30000 ? next_pid + 1 : INIT_PID + 1);
for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++)
if (rmp->mp_pid == next_pid || rmp->mp_procgrp == next_pid) {
t = 1;
break;
}
rmc->mp_pid = next_pid; /* assign pid to child */
} while (t);
new_pid = get_free_pid();
rmc->mp_pid = new_pid; /* assign pid to child */
/* Tell kernel and file system about the (now successful) FORK. */
sys_fork(who, child_nr, rmc->mp_pid);
@ -110,7 +101,7 @@ PUBLIC int do_fork()
/* Reply to child to wake it up. */
setreply(child_nr, 0);
return(next_pid); /* child's pid */
return(new_pid); /* child's pid */
}
@ -122,7 +113,6 @@ PUBLIC int do_mm_exit()
/* Perform the exit(status) system call. The real work is done by mm_exit(),
* which is also called when a process is killed by a signal.
*/
mm_exit(mp, m_in.status);
return(SUSPEND); /* can't communicate from beyond the grave */
}
@ -139,7 +129,6 @@ int exit_status; /* the process' exit status (for parent) */
* parent is waiting, release the rest, else keep the process slot and
* become a zombie.
*/
register int proc_nr;
int parent_waiting, right_child;
pid_t pidarg, procgrp;
@ -203,20 +192,18 @@ int exit_status; /* the process' exit status (for parent) */
*===========================================================================*/
PUBLIC int do_waitpid()
{
/* A process wants to wait for a child to terminate. If one is already waiting,
* go clean it up and let this WAIT call terminate. Otherwise, really wait.
/* A process wants to wait for a child to terminate. If a child is already
* waiting, go clean it up and let this WAIT call terminate. Otherwise,
* really wait.
* A process calling WAIT never gets a reply in the usual way at the end
* of the main loop (unless WNOHANG is set or no qualifying child exists).
* If a child has already exited, the routine cleanup() sends the reply
* to awaken the caller.
* Both WAIT and WAITPID are handled by this code.
*/
register struct mproc *rp;
int pidarg, options, children;
/* A process calling WAIT never gets a reply in the usual way at the end
* of the main loop (unless WNOHANG is set or no qualifying child exists).
* If a child has already exited, the routine cleanup() sends the reply
* to awaken the caller.
*/
/* Set internal variables, depending on whether this is WAIT or WAITPID. */
pidarg = (call_nr == WAIT ? -1 : m_in.pid); /* 1st param of waitpid */
options = (call_nr == WAIT ? 0 : m_in.sig_nr); /* 3rd param of waitpid */
@ -272,11 +259,10 @@ register struct mproc *child; /* tells which process is exiting */
/* Finish off the exit of a process. The process has exited or been killed
* by a signal, and its parent is waiting.
*/
struct mproc *parent = &mproc[child->mp_parent];
int exitstatus;
/* Wake up the parent. */
/* Wake up the parent by sending the reply message. */
exitstatus = (child->mp_exitstatus << 8) | (child->mp_sigstatus & 0377);
parent->mp_reply.reply_res2 = exitstatus;
setreply(child->mp_parent, child->mp_pid);
@ -286,3 +272,4 @@ register struct mproc *child; /* tells which process is exiting */
child->mp_flags = 0;
procs_in_use--;
}

View file

@ -4,7 +4,7 @@
* function.
*/
#include "mm.h"
#include "pm.h"
#include <minix/callnr.h>
#include <signal.h>
#include "mproc.h"

View file

@ -1,27 +1,31 @@
/* This file contains the main program of the memory manager and some related
/* This file contains the main program of the process manager and some related
* procedures. When MINIX starts up, the kernel runs for a little while,
* initializing itself and its tasks, and then it runs MM and FS. Both MM
* initializing itself and its tasks, and then it runs PM and FS. Both PM
* and FS initialize themselves as far as they can. FS then makes a call to
* MM, because MM has to wait for FS to acquire a RAM disk. MM asks the
* PM, because PM has to wait for FS to acquire a RAM disk. PM asks the
* kernel for all free memory and starts serving requests.
*
* The entry points into this file are:
* main: starts MM running
* setreply: set the reply to be sent to process making an MM system call
* main: starts PM running
* setreply: set the reply to be sent to process making an PM system call
*/
#include "mm.h"
#include "pm.h"
#include <minix/utils.h>
#include <minix/keymap.h>
#include <minix/callnr.h>
#include <minix/com.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/ioc_memory.h>
#include <string.h>
#include "mproc.h"
#include "param.h"
#include "../../kernel/type.h"
FORWARD _PROTOTYPE( void get_work, (void) );
FORWARD _PROTOTYPE( void mm_init, (void) );
FORWARD _PROTOTYPE( void pm_init, (void) );
#define click_to_round_k(n) \
((unsigned) ((((unsigned long) (n) << CLICK_SHIFT) + 512) / 1024))
@ -31,22 +35,25 @@ FORWARD _PROTOTYPE( void mm_init, (void) );
*===========================================================================*/
PUBLIC void main()
{
/* Main routine of the memory manager. */
/* Main routine of the process manager. */
int result, proc_nr;
struct mproc *rmp;
mm_init(); /* initialize memory manager tables */
pm_init(); /* initialize process manager tables */
/* This is MM's main loop- get work and do it, forever and forever. */
/* This is PM's main loop- get work and do it, forever and forever. */
while (TRUE) {
get_work(); /* wait for an MM system call */
get_work(); /* wait for an PM system call */
/* Check for system notifications first. Special cases. */
if (call_nr == HARD_STOP) { /* MINIX is shutting down */
check_sig(-1, SIGKILL); /* kill all processes */
sys_exit(0);
/* never reached */
} else if (call_nr == FKEY_PRESSED) { /* create debug dump */
(void) do_fkey_pressed();
result = SUSPEND; /* don't reply */
} else if (call_nr == KSIG_PENDING) { /* signals pending */
(void) ksig_pending();
result = SUSPEND; /* don't reply */
@ -69,7 +76,7 @@ PUBLIC void main()
for (proc_nr=0, rmp=mproc; proc_nr < NR_PROCS; proc_nr++, rmp++) {
if ((rmp->mp_flags & (REPLY | ONSWAP)) == REPLY) {
if (send(proc_nr, &rmp->mp_reply) != OK)
panic("MM can't reply to", proc_nr);
panic("PM can't reply to", proc_nr);
rmp->mp_flags &= ~REPLY;
}
}
@ -83,12 +90,11 @@ PUBLIC void main()
PRIVATE void get_work()
{
/* Wait for the next message and extract useful information from it. */
if (receive(ANY, &m_in) != OK) panic("MM receive error", NO_NUM);
if (receive(ANY, &m_in) != OK) panic("PM receive error", NO_NUM);
who = m_in.m_source; /* who sent the message */
call_nr = m_in.m_type; /* system call number */
/* Process slot of caller. Misuse MM's own process slot if the kernel is
/* Process slot of caller. Misuse PM's own process slot if the kernel is
* calling. The can happen in case of pending kernel signals.
*/
mp = &mproc[who < 0 ? PM_PROC_NR : who];
@ -100,13 +106,12 @@ PRIVATE void get_work()
*===========================================================================*/
PUBLIC void setreply(proc_nr, result)
int proc_nr; /* process to reply to */
int result; /* result of the call (usually OK or error #)*/
int result; /* result of call (usually OK or error #) */
{
/* Fill in a reply message to be sent later to a user process. System calls
* may occasionally fill in other fields, this is only for the main return
* value, and for setting the "must send reply" flag.
*/
register struct mproc *rmp = &mproc[proc_nr];
rmp->mp_reply.reply_res = result;
@ -118,12 +123,14 @@ int result; /* result of the call (usually OK or error #)*/
/*===========================================================================*
* mm_init *
* pm_init *
*===========================================================================*/
PRIVATE void mm_init()
PRIVATE void pm_init()
{
/* Initialize the memory manager. */
int s;
/* Initialize the process manager. */
int key, i, s;
static struct system_image image[IMAGE_SIZE];
register struct system_image *ip;
static char core_sigs[] = { SIGQUIT, SIGILL, SIGTRAP, SIGABRT,
SIGEMT, SIGFPE, SIGUSR1, SIGSEGV, SIGUSR2 };
static char ign_sigs[] = { SIGCHLD };
@ -146,52 +153,73 @@ PRIVATE void mm_init()
sigaddset(&ign_sset, *sig_ptr);
/* Get the memory map of the kernel to see how much memory it uses. */
if ((s=p_getmap(SYSTASK, kernel_map)) != OK)
panic("MM couldn't get proc entry of SYSTASK",s);
if ((s=get_mem_map(SYSTASK, kernel_map)) != OK)
panic("PM couldn't get proc entry of SYSTASK",s);
minix_clicks = (kernel_map[S].mem_phys + kernel_map[S].mem_len)
- kernel_map[T].mem_phys;
/* Initialize MM's tables. Request a copy of the system image table that
/* Initialize PM's tables. Request a copy of the system image table that
* is defined at the kernel level to see which slots to fill in.
*/
for (proc_nr = 0; proc_nr <= INIT_PROC_NR; proc_nr++) {
rmp = &mproc[proc_nr];
rmp->mp_flags |= IN_USE;
if ((s=p_getmap(proc_nr, rmp->mp_seg)) != OK)
panic("MM couldn't get proc entry",s);
if (rmp->mp_seg[T].mem_len != 0) rmp->mp_flags |= SEPARATE;
minix_clicks += (rmp->mp_seg[S].mem_phys + rmp->mp_seg[S].mem_len)
- rmp->mp_seg[T].mem_phys;
if (OK != (s=sys_getimage(&image))) {
printf("PM: warning, couldn't get system image table: %d\n", s);
}
mproc[INIT_PROC_NR].mp_pid = INIT_PID;
procs_in_use = 0; /* start populating table */
for (ip = &image[0]; ip < &image[IMAGE_SIZE]; ip++) {
if (ip->proc_nr >= 0) { /* task have negative nrs */
procs_in_use += 1; /* found user process */
/* Set process details. */
rmp = &mproc[ip->proc_nr];
rmp->mp_flags |= IN_USE | DONT_SWAP;
rmp->mp_pid = (ip->proc_nr == INIT_PROC_NR) ?
INIT_PID : get_free_pid();
strncpy(rmp->mp_name, ip->proc_name, PROC_NAME_LEN);
/* Change signal handling behaviour. */
sigfillset(&rmp->mp_ignore);
sigfillset(&rmp->mp_sigmask);
sigemptyset(&rmp->mp_catch);
/* Get memory map for this process from the kernel. */
if ((s=get_mem_map(ip->proc_nr, rmp->mp_seg)) != OK)
panic("couldn't get process entry",s);
if (rmp->mp_seg[T].mem_len != 0) rmp->mp_flags |= SEPARATE;
minix_clicks += rmp->mp_seg[S].mem_phys +
rmp->mp_seg[S].mem_len - rmp->mp_seg[T].mem_phys;
/* Tell FS about this system process. */
mess.PR_PROC_NR = ip->proc_nr;
mess.PR_PID = rmp->mp_pid;
if (OK != (s=send(FS_PROC_NR, &mess)))
panic("PM can't sync up with FS", s);
}
}
/* Tell FS no more SYSTEM processes follow and synchronize. */
mess.PR_PROC_NR = NONE;
if (sendrec(FS_PROC_NR, &mess) != OK || mess.m_type != OK)
panic("PM can't sync up with FS", NO_NUM);
/* INIT process is somewhat special. */
sigemptyset(&mproc[INIT_PROC_NR].mp_ignore);
sigemptyset(&mproc[INIT_PROC_NR].mp_sigmask);
sigemptyset(&mproc[INIT_PROC_NR].mp_catch);
procs_in_use = LOW_USER + 1;
/* Wait for FS to send a message telling the RAM disk size then go "on-line".
*/
if (receive(FS_PROC_NR, &mess) != OK)
panic("MM can't obtain RAM disk size from FS", NO_NUM);
ram_clicks = mess.MEM_CHUNK_SIZE;
/* Initialize tables to all physical mem. */
/* Initialize tables to all physical memory. */
mem_init(&free_clicks);
total_clicks = minix_clicks + ram_clicks + free_clicks;
total_clicks = minix_clicks + free_clicks;
/* Print memory information. */
printf("Memory size=%uK ", click_to_round_k(total_clicks));
printf("MINIX=%uK ", click_to_round_k(minix_clicks));
printf("RAM disk=%uK ", click_to_round_k(ram_clicks));
printf("System services=%uK ", click_to_round_k(minix_clicks));
printf("Available=%uK\n\n", click_to_round_k(free_clicks));
/* Tell FS to continue. */
if (send(FS_PROC_NR, &mess) != OK)
panic("MM can't sync up with FS", NO_NUM);
/* Tell the memory task where my process table is for the sake of ps(1). */
if ((mem = open("/dev/ram", O_RDWR)) != -1) {
ioctl(mem, MIOCSPSINFO, (void *) mproc);
close(mem);
/* Register function keys with TTY for debug dumps. */
for (key=SF7; key<=SF8; key++) {
if ((i=fkey_enable(key))!=OK) {
printf("Warning: PM couldn't register Shift+F%d key: %d\n",
key-SF1+1, i);
}
}
}

View file

@ -2,11 +2,11 @@
* 31 Mar 2000
* The entry points into this file are:
* do_reboot: kill all processes, then reboot system
* do_svrctl: memory manager control
* do_getsysinfo: request copy of MM data structure
* do_svrctl: process manager control
* do_getsysinfo: request copy of PM data structure
*/
#include "mm.h"
#include "pm.h"
#include <minix/callnr.h>
#include <signal.h>
#include <sys/svrctl.h>
@ -18,7 +18,7 @@
FORWARD _PROTOTYPE( char *find_key, (const char *params, const char *key));
/* MM gets a copy of all boot monitor parameters. */
/* PM gets a copy of all boot monitor parameters. */
PRIVATE char monitor_params[128*sizeof(char *)];
/*=====================================================================*
@ -57,8 +57,8 @@ PUBLIC int do_reboot()
return(EINVAL);
}
check_sig(-1, SIGKILL); /* kill all processes except init */
tell_fs(REBOOT,0,0,0); /* tell FS to prepare for shutdown */
check_sig(-1, SIGKILL); /* kill all processes except init */
sys_abort(m_in.reboot_flag, PM_PROC_NR, monitor_code, m_in.reboot_size);
sys_exit(0);
@ -78,7 +78,7 @@ PUBLIC int do_svrctl()
/* Initialize private copy of monitor parameters on first call. */
if (! initialized) {
if ((s=sys_getmonparams(monitor_params, sizeof(monitor_params))) != OK)
printf("MM: Warning couldn't get copy of monitor params: %d\n",s);
printf("PM: Warning couldn't get copy of monitor params: %d\n",s);
else
initialized = 1;
}
@ -98,7 +98,7 @@ PUBLIC int do_svrctl()
return(sys_svrctl(who, req, mp->mp_effuid == SUPER_USER, ptr));
}
/* Control operations local to the MM. */
/* Control operations local to the PM. */
switch(req) {
case MMGETPARAM: {
struct sysgetenv sysgetenv;
@ -110,7 +110,7 @@ PUBLIC int do_svrctl()
/* Check if boot monitor parameters are in place. */
if (! initialized) return(EAGAIN);
/* Copy sysgetenv structure to MM. */
/* Copy sysgetenv structure to PM. */
if (sys_datacopy(who, ptr, SELF, (vir_bytes) &sysgetenv,
sizeof(sysgetenv)) != OK) return(EFAULT);
@ -170,7 +170,7 @@ PUBLIC int do_svrctl()
}
}
/* Become like MM and FS. */
/* Become like PM and FS. */
mp->mp_pid = mp->mp_procgrp = 0;
mp->mp_parent = 0;
return(OK); }

View file

@ -1,4 +1,4 @@
/* This table has one slot per process. It contains all the memory management
/* This table has one slot per process. It contains all the process management
* information for each process. Among other things, it defines the text, data
* and stack segments, uids and gids, and various flags. The kernel and file
* systems have tables that are also indexed by process, with the contents
@ -30,7 +30,7 @@ EXTERN struct mproc {
sigset_t mp_catch; /* 1 means catch the signal, 0 means don't */
sigset_t mp_sigmask; /* signals to be blocked */
sigset_t mp_sigmask2; /* saved copy of mp_sigmask */
sigset_t mp_sigpending; /* signals being blocked */
sigset_t mp_sigpending; /* pending signals to be handled */
struct sigaction mp_sigact[_NSIG + 1]; /* as in sigaction(2) */
vir_bytes mp_sigreturn; /* address of C library __sigreturn function */
@ -58,5 +58,6 @@ EXTERN struct mproc {
#define REPLY 0x200 /* set if a reply message is pending */
#define ONSWAP 0x400 /* set if data segment is swapped out */
#define SWAPIN 0x800 /* set if on the "swap this in" queue */
#define DONT_SWAP 0x1000 /* never swap out this process */
#define NIL_MPROC ((struct mproc *) 0)

View file

@ -29,6 +29,9 @@ _PROTOTYPE( int size_ok, (int file_type, vir_clicks tc, vir_clicks dc,
_PROTOTYPE( int do_dev_io, (void) );
_PROTOTYPE( int do_dev_io, (void) );
/* dmp.c */
_PROTOTYPE( int do_fkey_pressed, (void) );
/* exec.c */
_PROTOTYPE( int do_exec, (void) );
_PROTOTYPE( void rw_seg, (int rw, int fd, int proc, int seg,
@ -64,7 +67,6 @@ _PROTOTYPE( void setreply, (int proc_nr, int result) );
_PROTOTYPE( int do_alarm, (void) );
_PROTOTYPE( int do_kill, (void) );
_PROTOTYPE( int ksig_pending, (void) );
_PROTOTYPE( int do_ksig, (void) );
_PROTOTYPE( int do_pause, (void) );
_PROTOTYPE( int set_alarm, (int proc_nr, int sec) );
_PROTOTYPE( int check_sig, (pid_t proc_id, int signo) );
@ -81,11 +83,11 @@ _PROTOTYPE( int do_trace, (void) );
_PROTOTYPE( void stop_proc, (struct mproc *rmp, int sig_nr) );
/* utility.c */
_PROTOTYPE( pid_t get_free_pid, (void) );
_PROTOTYPE( int allowed, (char *name_buf, struct stat *s_buf, int mask) );
_PROTOTYPE( int no_sys, (void) );
_PROTOTYPE( void panic, (char *format, int num) );
_PROTOTYPE( void tell_fs, (int what, int p1, int p2, int p3) );
_PROTOTYPE( int get_stack_ptr, (int proc_nr, vir_bytes *sp) );
_PROTOTYPE( int get_mem_map, (int proc_nr, struct mem_map *mem_map) );
/* procutils.c */
_PROTOTYPE( int p_getsp, (int proc_nr, vir_bytes *sp) );
_PROTOTYPE( int p_getmap, (int proc_nr, struct mem_map *mem_map) );

View file

@ -11,7 +11,6 @@
* do_sigreturn: perform the SIGRETURN system call
* do_sigsuspend: perform the SIGSUSPEND system call
* do_kill: perform the KILL system call
* do_ksig: accept a signal originating in the kernel (e.g., SIGINT)
* do_alarm: perform the ALARM system call by calling set_alarm()
* set_alarm: tell the clock task to start or stop a timer
* do_pause: perform the PAUSE system call
@ -21,7 +20,7 @@
* check_pending: check if a pending signal can now be delivered
*/
#include "mm.h"
#include "pm.h"
#include <minix/utils.h>
#include <sys/stat.h>
#include <minix/callnr.h>
@ -189,11 +188,17 @@ PUBLIC int do_kill()
}
/*===========================================================================*
* do_ksig_pending *
* ksig_pending *
*===========================================================================*/
PUBLIC int ksig_pending()
{
/* The kernel has notified the MM about pending signals. Request pending
/* Certain signals, such as segmentation violations and DEL, originate in the
* kernel. When the kernel detects such signals, it sets bits in a bit map.
* As soon as PM is awaiting new work, the kernel sends PM a message containing
* the process slot and bit map. That message comes here. The File System
* also uses this mechanism to signal writing on broken pipes (SIGPIPE).
*
* The kernel has notified the PM about pending signals. Request pending
* signals until all signals are handled. If there are no more signals,
* NONE is returned in the process number field.
*/
@ -211,27 +216,6 @@ PUBLIC int ksig_pending()
return(SUSPEND); /* prevents sending reply */
}
/*===========================================================================*
* do_ksig *
*===========================================================================*/
PUBLIC int do_ksig()
{
/* Certain signals, such as segmentation violations and DEL, originate in the
* kernel. When the kernel detects such signals, it sets bits in a bit map.
* As soon as MM is awaiting new work, the kernel sends MM a message containing
* the process slot and bit map. That message comes here. The File System
* also uses this mechanism to signal writing on broken pipes (SIGPIPE).
*/
int proc_nr;
sigset_t sig_map;
/* Only kernel may make this call. */
if (who != HARDWARE) return(EPERM);
proc_nr = m_in.SIG_PROC;
sig_map = (sigset_t) m_in.SIG_MAP;
handle_ksig(proc_nr, sig_map);
return(SUSPEND);
}
/*===========================================================================*
* handle_ksig *
@ -247,12 +231,12 @@ sigset_t sig_map;
rmp = &mproc[proc_nr];
if ((rmp->mp_flags & (IN_USE | ZOMBIE)) != IN_USE) return;
proc_id = rmp->mp_pid;
mp = &mproc[0]; /* pretend kernel signals are from MM */
mp = &mproc[0]; /* pretend kernel signals are from PM */
mp->mp_procgrp = rmp->mp_procgrp; /* get process group right */
/* Check each bit in turn to see if a signal is to be sent. Unlike
* kill(), the kernel may collect several unrelated signals for a
* process and pass them to MM in one blow. Thus loop on the bit
* process and pass them to PM in one blow. Thus loop on the bit
* map. For SIGINT and SIGQUIT, use proc_id 0 to indicate a broadcast
* to the recipient's process group. For SIGKILL, use proc_id -1 to
* indicate a systemwide broadcast.
@ -331,7 +315,7 @@ int sec; /* how many seconds delay before the signal */
ticks = LONG_MAX; /* eternity (really TMR_NEVER) */
if ((s=sys_signalrm(proc_nr, &ticks)) != OK)
panic("MM couldn't set signal alarm", s);
panic("PM couldn't set signal alarm", s);
remaining = (int) ((ticks + (HZ-1))/HZ);
if (remaining < 0) remaining = INT_MAX; /* true value is too large */
@ -378,7 +362,7 @@ int signo; /* signal to send to process (1 to _NSIG) */
slot = (int) (rmp - mproc);
if ((rmp->mp_flags & (IN_USE | ZOMBIE)) != IN_USE) {
printf("MM: signal %d sent to %s process %d\n",
printf("PM: signal %d sent to %s process %d\n",
(rmp->mp_flags & ZOMBIE) ? "zombie" : "dead", signo, slot);
panic("", NO_NUM);
}
@ -411,8 +395,8 @@ int signo; /* signal to send to process (1 to _NSIG) */
sm.sm_signo = signo;
sm.sm_sighandler = (vir_bytes) rmp->mp_sigact[signo].sa_handler;
sm.sm_sigreturn = rmp->mp_sigreturn;
if ((s=p_getsp(slot, &new_sp)) != OK)
panic("MM couldn't get new stack pointer",s);
if ((s=get_stack_ptr(slot, &new_sp)) != OK)
panic("PM couldn't get new stack pointer",s);
sm.sm_stkptr = new_sp;
/* Make room for the sigcontext and sigframe struct. */
@ -487,7 +471,7 @@ int signo; /* signal to send to process (0 to _NSIG) */
*/
count = 0;
error_code = ESRCH;
for (rmp = &mproc[INIT_PROC_NR]; rmp < &mproc[NR_PROCS]; rmp++) {
for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) {
if (!(rmp->mp_flags & IN_USE)) continue;
if ((rmp->mp_flags & ZOMBIE) && signo != 0) continue;
@ -564,7 +548,7 @@ int pro; /* which process number */
/* A signal is to be sent to a process. If that process is hanging on a
* system call, the system call must be terminated with EINTR. Possible
* calls are PAUSE, WAIT, READ and WRITE, the latter two for pipes and ttys.
* First check if the process is hanging on an MM call. If not, tell FS,
* First check if the process is hanging on an PM call. If not, tell FS,
* so it can check for READs and WRITEs from pipes, ttys and the like.
*/
@ -579,7 +563,7 @@ int pro; /* which process number */
return;
}
/* Process is not hanging on an MM call. Ask FS to take a look. */
/* Process is not hanging on an PM call. Ask FS to take a look. */
tell_fs(UNPAUSE, pro, 0, 0);
}
@ -615,8 +599,8 @@ register struct mproc *rmp; /* whose core is to be dumped */
* the adjust() for sending a signal to fail due to safety checking.
* Maybe make SAFETY_BYTES a parameter.
*/
if ((s=p_getsp(slot, &current_sp)) != OK)
panic("MM couldn't get new stack pointer",s);
if ((s=get_stack_ptr(slot, &current_sp)) != OK)
panic("PM couldn't get new stack pointer",s);
adjust(rmp, rmp->mp_seg[D].mem_len, current_sp);
/* Write the memory map of all segments to begin the core file. */

View file

@ -4,7 +4,7 @@
#define _TABLE
#include "mm.h"
#include "pm.h"
#include <minix/callnr.h>
#include <signal.h>
#include "mproc.h"
@ -79,7 +79,7 @@ _PROTOTYPE (int (*call_vec[NCALLS]), (void) ) = {
do_getset, /* 62 = setsid */
do_getset, /* 63 = getpgrp */
do_ksig, /* 64 = KSIG: signals originating in the kernel */
no_sys, /* 64 = unused */
no_sys, /* 65 = UNPAUSE */
no_sys, /* 66 = unused */
no_sys, /* 67 = REVIVE */

View file

@ -1,4 +1,4 @@
/* This file handles the memory manager's part of debugging, using the
/* This file handles the process manager's part of debugging, using the
* ptrace system call. Most of the commands are passed on to the system
* task for completion.
*
@ -20,7 +20,7 @@
* task. The rest are handled entirely by the system task.
*/
#include "mm.h"
#include "pm.h"
#include <minix/com.h>
#include <sys/ptrace.h>
#include <signal.h>
@ -82,7 +82,7 @@ pid_t lpid;
{
register struct mproc *rmp;
for (rmp = &mproc[INIT_PROC_NR + 1]; rmp < &mproc[NR_PROCS]; rmp++)
for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++)
if (rmp->mp_flags & IN_USE && rmp->mp_pid == lpid) return(rmp);
return(NIL_MPROC);
}

View file

@ -1,4 +1,4 @@
/* If there were any type definitions local to the Memory Manager, they would
/* If there were any type definitions local to the Process Manager, they would
* be here. This file is included only for symmetry with the kernel and File
* System, which do have some local type definitions.
*/

View file

@ -1,13 +1,16 @@
/* This file contains some utility routines for MM.
/* This file contains some utility routines for PM.
*
* The entry points are:
* allowed: see if an access is permitted
* no_sys: this routine is called for invalid system call numbers
* panic: MM has run aground of a fatal error and cannot continue
* tell_fs: interface to FS
* get_free_pid: get a free process or group id
* allowed: see if an access is permitted
* no_sys: called for invalid system call numbers
* panic: PM has run aground of a fatal error
* tell_fs: interface to FS
* get_mem_map: get memory map of given process
* get_stack_ptr: get stack pointer of given process
*/
#include "mm.h"
#include "pm.h"
#include <sys/stat.h>
#include <minix/callnr.h>
#include <minix/com.h>
@ -16,6 +19,36 @@
#include "mproc.h"
#include "param.h"
#include <minix/config.h>
#include <timers.h>
#include <string.h>
#include "../../kernel/const.h"
#include "../../kernel/type.h"
#include "../../kernel/proc.h"
/*===========================================================================*
* get_free_pid *
*===========================================================================*/
PUBLIC pid_t get_free_pid()
{
static pid_t next_pid = INIT_PID + 1; /* next pid to be assigned */
register struct mproc *rmp; /* check process table */
int t; /* zero if pid still free */
/* Find a free pid for the child and put it in the table. */
do {
t = 0;
next_pid = (next_pid < 30000 ? next_pid + 1 : INIT_PID + 1);
for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++)
if (rmp->mp_pid == next_pid || rmp->mp_procgrp == next_pid) {
t = 1;
break;
}
} while (t); /* 't' = 0 means pid free */
return(next_pid);
}
/*===========================================================================*
* allowed *
*===========================================================================*/
@ -27,13 +60,12 @@ int mask; /* R_BIT, W_BIT, or X_BIT */
/* Check to see if file can be accessed. Return EACCES or ENOENT if the access
* is prohibited. If it is legal open the file and return a file descriptor.
*/
int fd;
int save_errno;
/* Use the fact that mask for access() is the same as the permissions mask.
* E.g., X_BIT in <minix/const.h> is the same as X_OK in <unistd.h> and
* S_IXOTH in <sys/stat.h>. tell_fs(DO_CHDIR, ...) has set MM's real ids
* S_IXOTH in <sys/stat.h>. tell_fs(DO_CHDIR, ...) has set PM's real ids
* to the user's effective ids, so access() works right for setuid programs.
*/
if (access(name_buf, mask) < 0) return(-errno);
@ -62,7 +94,7 @@ int mask; /* R_BIT, W_BIT, or X_BIT */
*===========================================================================*/
PUBLIC int no_sys()
{
/* A system call number not implemented by MM has been requested. */
/* A system call number not implemented by PM has been requested. */
return(EINVAL);
}
@ -75,15 +107,14 @@ PUBLIC void panic(format, num)
char *format; /* format string */
int num; /* number to go with format string */
{
/* Something awful has happened. Panics are caused when an internal
/* An unrecoverable error has occurred. Panics are caused when an internal
* inconsistency is detected, e.g., a programming error or illegal value of a
* defined constant.
* defined constant. The process manager decides to shut down. This results
* in a HARD_STOP notification to all system processes to allow local cleanup.
*/
printf("Memory manager panic: %s ", format);
if (num != NO_NUM) printf("%d",num);
printf("Process manager panic: %s", format);
if (num != NO_NUM) printf(": %d",num);
printf("\n");
tell_fs(SYNC, 0, 0, 0); /* flush the cache to the disk */
sys_abort(RBT_PANIC);
}
@ -94,7 +125,7 @@ int num; /* number to go with format string */
PUBLIC void tell_fs(what, p1, p2, p3)
int what, p1, p2, p3;
{
/* This routine is only used by MM to inform FS of certain events:
/* This routine is only used by PM to inform FS of certain events:
* tell_fs(CHDIR, slot, dir, 0)
* tell_fs(EXEC, proc, 0, 0)
* tell_fs(EXIT, proc, 0, 0)
@ -102,7 +133,6 @@ int what, p1, p2, p3;
* tell_fs(SETGID, proc, realgid, effgid)
* tell_fs(SETSID, proc, 0, 0)
* tell_fs(SETUID, proc, realuid, effuid)
* tell_fs(SYNC, 0, 0, 0)
* tell_fs(UNPAUSE, proc, signr, 0)
*/
message m;
@ -112,3 +142,37 @@ int what, p1, p2, p3;
m.tell_fs_arg3 = p3;
_taskcall(FS_PROC_NR, what, &m);
}
/*===========================================================================*
* get_mem_map *
*===========================================================================*/
PUBLIC int get_mem_map(proc_nr, mem_map)
int proc_nr; /* process to get map of */
struct mem_map *mem_map; /* put memory map here */
{
struct proc p;
int s;
if ((s=sys_getproc(&p, proc_nr)) != OK)
return(s);
memcpy(mem_map, p.p_memmap, sizeof(p.p_memmap));
return(OK);
}
/*===========================================================================*
* get_stack_ptr *
*===========================================================================*/
PUBLIC int get_stack_ptr(proc_nr, sp)
int proc_nr; /* process to get sp of */
vir_bytes *sp; /* put stack pointer here */
{
struct proc p;
int s;
if ((s=sys_getproc(&p, proc_nr)) != OK)
return(s);
*sp = p.p_reg.sp;
return(OK);
}