*** empty log message ***

This commit is contained in:
Jorrit Herder 2005-04-29 15:36:43 +00:00
parent 0e869cdd44
commit 89ac678b9b
78 changed files with 1293 additions and 2858 deletions

View file

@ -247,9 +247,12 @@ PUBLIC void main()
/* Register function key for debugging dumps. */
fkey_enable(SF8);
/* Set special disk parameters then call the generic main loop. */
#if DEAD_CODE
if ((s=get_own_proc_nr(&win_tasknr)) != OK)
server_panic(w_name(),"Couldn't get own process number",s);
#endif
printf("AT wini task started.\n");
/* Set special disk parameters then call the generic main loop. */
init_params();
driver_task(&w_dtab);
}
@ -270,17 +273,17 @@ PRIVATE void init_params()
int s;
/* Get the number of drives from the BIOS data area */
if ((s=sys_vircopy(SELF, BIOS_SEG, ADR_WINI_PARAMS,
SELF, D, (vir_bytes) params, LEN_WINI_PARAMS)) != OK)
if ((s=sys_vircopy(SELF, BIOS_SEG, NR_HD_DRIVES_ADDR,
SELF, D, (vir_bytes) params, NR_HD_DRIVES_SIZE)) != OK)
server_panic(w_name(), "Couldn't read BIOS", s);
if ((nr_drives = params[0]) > 2) nr_drives = 2;
for (drive = 0, wn = wini; drive < MAX_DRIVES; drive++, wn++) {
if (drive < nr_drives) {
/* Copy the BIOS parameter vector */
vector = drive == 0 ? ADR_WINI_0_PARM_VEC:ADR_WINI_1_PARM_VEC;
size = drive == 0 ? LEN_WINI_0_PARM_VEC:LEN_WINI_1_PARM_VEC;
if ((s=sys_vircopy(SELF, BIOS_SEG, vector,
/* Copy the BIOS parameter vector */
vector = (drive == 0) ? BIOS_HD0_PARAMS_ADDR:BIOS_HD1_PARAMS_ADDR;
size = (drive == 0) ? BIOS_HD0_PARAMS_SIZE:BIOS_HD1_PARAMS_SIZE;
if ((s=sys_vircopy(SELF, BIOS_SEG, vector,
SELF, D, (vir_bytes) parv, size)) != OK)
server_panic(w_name(), "Couldn't read BIOS", s);
@ -460,7 +463,7 @@ PRIVATE int w_identify()
if (w_specify() != OK && w_specify() != OK) return(ERR);
printf("%s: user-level AT Winchester driver detected ", w_name());
printf("%s: user-space AT Winchester driver detected ", w_name());
if (wn->state & (SMART|ATAPI)) {
printf("%.40s\n", id_string);
} else {
@ -469,8 +472,12 @@ PRIVATE int w_identify()
/* Everything looks OK; register IRQ so we can stop polling. */
wn->irq = w_drive < 2 ? AT_WINI_0_IRQ : AT_WINI_1_IRQ;
#if DEAD_CODE
sys_irqsetpolicy(w_wn->irq, (IRQ_READ_PORT | IRQ_BYTE | IRQ_REENABLE), SELF,
(w_wn->base + REG_STATUS), &w_byteval, 0);
#else
sys_irqsetpolicy(w_wn->irq, IRQ_REENABLE, SELF, 0, 0, 0);
#endif
sys_irqenable(wn->irq);
return(OK);
}
@ -834,7 +841,11 @@ PRIVATE void w_intr_wait()
if (m.m_type == SYN_ALARM) { /* but check for timeout */
w_timeout(); /* a.o. set w_status */
} else if (m.m_type == HARD_INT) {
#if DEAD_CODE
w_status = w_byteval; /* read by generic handler */
#else
sys_inb((w_wn->base + REG_STATUS), &w_status);
#endif
}
}
} else {

View file

@ -118,7 +118,6 @@ struct driver *dp; /* Device dependent entry points. */
r = do_vrdwt(dp, &mess); break;
case HARD_INT: /* leftover interrupt or expired timer. */
/* printf("Driver.c: Left-over interrupt!\n"); */
continue;
case HARD_STOP: (*dp->dr_stop)(dp);
continue; /* don't reply */

View file

@ -161,9 +161,9 @@ struct part_entry *table; /* four entries */
/* Read the partition table at 'offset'. */
if (proc_nr == NONE) {
if ((s=get_proc_nr(&proc_nr,NULL)) != OK) {
if ((s=sys_getprocnr(&proc_nr,0,0)) != OK) {
printf("%s: can't get own proc nr: %d\n", (*dp->dr_name)(), s);
return 0;
return(0);
}
}
position = offset << SECTOR_SHIFT;

View file

@ -4,10 +4,14 @@
* /dev/mem - absolute memory
* /dev/kmem - kernel virtual memory
* /dev/null - null device (data sink)
* /dev/boot - boot FS loaded from boot image
* /dev/boot - boot device loaded from boot image
* /dev/random - random number generator
* /dev/zero - null byte stream generator
*
* Changes:
* Apr 09, 2005 added support for boot FS (Jorrit N. Herder)
* Apr 29, 2005 added null byte generator (Jorrit N. Herder)
* Apr 27, 2005 added random device handling (Jorrit N. Herder)
* Apr 09, 2005 added support for boot device (Jorrit N. Herder)
* Sep 03, 2004 secured code with ENABLE_USERPRIV (Jorrit N. Herder)
* Jul 26, 2004 moved RAM driver to user-space (Jorrit N. Herder)
* Apr 20, 1992 device dependent/independent split (Kees J. Bot)
@ -16,20 +20,16 @@
#include "../drivers.h"
#include "../libdriver/driver.h"
#include <sys/ioc_memory.h>
#if (CHIP == INTEL) && ENABLE_USERBIOS
#include <ibm/int86.h>
#endif
#define NR_DEVS 6 /* number of RAM-type devices */
#define NR_DEVS 7 /* number of minor devices */
PRIVATE struct device m_geom[NR_DEVS]; /* base and size of each RAM disk */
PRIVATE struct device m_geom[NR_DEVS]; /* base and size of each device */
PRIVATE int m_seg[NR_DEVS]; /* segment index of each device */
PRIVATE int m_device; /* current device */
PRIVATE struct kenviron kenv; /* need protected_mode */
PRIVATE struct kinfo kinfo; /* need kernel info */
PRIVATE struct machine machine; /* need machine info */
PRIVATE struct psinfo psinfo = { NR_TASKS, NR_PROCS, 0, 0, 0 };
#define RANDOM_BUFFER_SIZE (1024*32)
PRIVATE char random_state[RANDOM_BUFFER_SIZE];
FORWARD _PROTOTYPE( struct device *m_prepare, (int device) );
FORWARD _PROTOTYPE( int m_transfer, (int proc_nr, int opcode, off_t position,
iovec_t *iov, unsigned nr_req) );
@ -54,6 +54,14 @@ PRIVATE struct driver m_dtab = {
nop_alarm, /* ignore leftover alarms */
};
/* Buffer for the /dev/zero null byte feed. */
#define ZERO_BUF_SIZE 1024
PRIVATE char zero[ZERO_BUF_SIZE];
/* Buffer for the /dev/random number generator. */
#define RANDOM_BUF_SIZE 1024
PRIVATE char random[RANDOM_BUF_SIZE];
/*===========================================================================*
* main *
@ -101,53 +109,105 @@ off_t position; /* offset on device to read or write */
iovec_t *iov; /* pointer to read or write request vector */
unsigned nr_req; /* length of request vector */
{
/* Read or write /dev/null, /dev/mem, /dev/kmem, /dev/ram, /dev/boot,
* /dev/random, or /dev/urandom
*/
/* Read or write /dev/null, /dev/mem, /dev/kmem, /dev/ram, or /dev/boot. */
int device;
phys_bytes mem_phys, user_phys;
unsigned count;
int seg;
unsigned count, left, chunk;
vir_bytes user_vir;
struct device *dv;
unsigned long dv_size;
int s;
/* Get minor device number and check for /dev/null. */
device = m_device;
dv = &m_geom[device];
dv_size = cv64ul(dv->dv_size);
while (nr_req > 0) {
/* How much to transfer and where to / from. */
count = iov->iov_size;
user_vir = iov->iov_addr;
switch (device) {
/* No copying; ignore request. */
case NULL_DEV:
if (opcode == DEV_GATHER) return(OK); /* always at EOF */
break;
case RANDOM_DEV:
return OK;
break;
default:
/* /dev/mem, /dev/kmem, /dev/ram, /dev/boot: check for EOF */
if (position >= dv_size) return(OK);
/* Virtual copying. For boot device. */
case RAM_DEV:
case KMEM_DEV:
case BOOT_DEV:
if (position >= dv_size) return(OK); /* check for EOF */
if (position + count > dv_size) count = dv_size - position;
seg = m_seg[device];
if (opcode == DEV_GATHER) { /* copy actual data */
sys_vircopy(SELF,seg,position, proc_nr,D,user_vir, count);
} else {
sys_vircopy(proc_nr,D,user_vir, SELF,seg,position, count);
}
break;
/* Physical copying. Only used to access entire memory. */
case MEM_DEV:
if (position >= dv_size) return(OK); /* check for EOF */
if (position + count > dv_size) count = dv_size - position;
mem_phys = cv64ul(dv->dv_base) + position;
/* Copy the data. */
if (opcode == DEV_GATHER) {
sys_copy(ABS, D, mem_phys, proc_nr, D, user_vir, count);
if (opcode == DEV_GATHER) { /* copy data */
sys_physcopy(NONE, PHYS_SEG, mem_phys,
proc_nr, D, user_vir, count);
} else {
sys_copy(proc_nr, D, user_vir, ABS, D, mem_phys, count);
sys_physcopy(proc_nr, D, user_vir,
NONE, PHYS_SEG, mem_phys, count);
}
break;
/* Random number generator. Character instead of block device. */
case RANDOM_DEV:
printf("MEMORY: please note /dev/random is NOT yet random!\n");
left = count;
while (left > 0) {
chunk = (left > RANDOM_BUF_SIZE) ? RANDOM_BUF_SIZE : left;
if (opcode == DEV_GATHER) {
sys_vircopy(SELF, D, (vir_bytes) random,
proc_nr, D, user_vir, chunk);
} else if (opcode == DEV_SCATTER) {
sys_vircopy(proc_nr, D, user_vir,
SELF, D, (vir_bytes) random, chunk);
}
left -= chunk;
}
break;
/* Null byte stream generator. */
case ZERO_DEV:
if (opcode == DEV_GATHER) {
left = count;
while (left > 0) {
chunk = (left > ZERO_BUF_SIZE) ? ZERO_BUF_SIZE : left;
if (OK != (s=sys_vircopy(SELF, D, (vir_bytes) zero,
proc_nr, D, user_vir, chunk)))
printf("MEMORY: sys_vircopy failed: %d\n", s);
left -= chunk;
}
}
break;
/* Unknown (illegal) minor device. */
default:
return(EINVAL);
}
/* Book the number of bytes transferred. */
position += count;
iov->iov_addr += count;
if ((iov->iov_size -= count) == 0) { iov++; nr_req--; }
}
return(OK);
}
@ -161,7 +221,7 @@ struct driver *dp;
message *m_ptr;
{
/* Check device number on open. Give I/O privileges to a process opening
* /dev/mem or /dev/kmem. This is needed for systems with memory mapped I/O.
* /dev/mem or /dev/kmem. This may be needed in case of memory mapped I/O.
*/
if (m_prepare(m_ptr->DEVICE) == NIL_DEV) return(ENXIO);
@ -181,30 +241,51 @@ message *m_ptr;
*===========================================================================*/
PRIVATE void m_init()
{
/* Initialize this task. */
extern int end;
int s;
/* Initialize this task. All minor devices are initialized one by one. */
int i,s;
/* Print welcome message. */
printf("MEMORY: user-level memory (RAM) driver is alive");
printf("MEMORY: user-level memory (RAM, etc.) driver is alive\n");
/* Get kernel environment (protected_mode and addresses). */
if (OK != (s=sys_getkenviron(&kenv))) {
server_panic("MEM","Couldn't get kernel environment.",s);
/* Get kernel info for memory addresses of kernel and boot device. */
if (OK != (s=sys_getkinfo(&kinfo))) {
server_panic("MEM","Couldn't get kernel information.",s);
}
m_geom[KMEM_DEV].dv_base = cvul64(kenv.kmem_base);
m_geom[KMEM_DEV].dv_size = cvul64(kenv.kmem_size);
m_geom[BOOT_DEV].dv_base = cvul64(kenv.bootfs_base);
m_geom[BOOT_DEV].dv_size = cvul64(kenv.bootfs_size);
/* dv_base isn't used for the random device */
m_geom[RANDOM_DEV].dv_base = cvul64(NULL);
m_geom[RANDOM_DEV].dv_size = cvul64(RANDOM_BUFFER_SIZE);
/* Install remote segment for /dev/kmem memory. */
m_geom[KMEM_DEV].dv_base = cvul64(kinfo.kmem_base);
m_geom[KMEM_DEV].dv_size = cvul64(kinfo.kmem_size);
if (OK != (s=sys_segctl(&m_seg[KMEM_DEV], (u16_t *) &s, (vir_bytes *) &s,
kinfo.kmem_base, kinfo.kmem_size))) {
server_panic("MEM","Couldn't install remote segment.",s);
}
psinfo.proc = kenv.proc_addr;
/* Install remote segment for /dev/boot memory, if enabled. */
m_geom[BOOT_DEV].dv_base = cvul64(kinfo.bootdev_base);
m_geom[BOOT_DEV].dv_size = cvul64(kinfo.bootdev_size);
if (kinfo.bootdev_base > 0) {
if (OK != (s=sys_segctl(&m_seg[BOOT_DEV], (u16_t *) &s, (vir_bytes *) &s,
kinfo.bootdev_base, kinfo.bootdev_size))) {
server_panic("MEM","Couldn't install remote segment.",s);
}
}
psinfo.proc = kinfo.proc_addr;
/* Initialize /dev/random and /dev/zero. */
for (i=0; i<ZERO_BUF_SIZE; i++) {
zero[i] = '\0';
}
for (i=0; i<RANDOM_BUF_SIZE; i++) {
random[i] = 'a' + i % 256;
}
/* Set up memory ranges for /dev/mem. */
#if (CHIP == INTEL)
if (!kenv.protected) {
if (OK != (s=sys_getmachine(&machine))) {
server_panic("MEM","Couldn't get machine information.",s);
}
if (! machine.protected) {
m_geom[MEM_DEV].dv_size = cvul64(0x100000); /* 1M for 8086 systems */
} else {
#if _WORD_SIZE == 2
@ -239,18 +320,23 @@ message *m_ptr; /* pointer to read or write message */
switch (m_ptr->REQUEST) {
case MIOCRAMSIZE: {
/* FS wants to create a new RAM disk with the given size. */
unsigned long bytesize;
phys_bytes base;
unsigned long ramdev_size;
phys_bytes ramdev_base;
int s;
if (m_ptr->PROC_NR != FS_PROC_NR) return(EPERM);
/* Try to allocate a piece of kernel memory for the RAM disk. */
bytesize = m_ptr->POSITION;
if (OK != (s = sys_kmalloc(bytesize, &base)))
/* Try to allocate a piece of memory for the RAM disk. */
ramdev_size = m_ptr->POSITION;
if (OK != (s=sys_kmalloc(ramdev_size, &ramdev_base)))
server_panic("MEM","Couldn't allocate kernel memory", s);
dv->dv_base = cvul64(base);
dv->dv_size = cvul64(bytesize);
dv->dv_base = cvul64(ramdev_base);
dv->dv_size = cvul64(ramdev_size);
if (OK != (s=sys_segctl(&m_seg[RAM_DEV], (u16_t *) &s, (vir_bytes *) &s,
ramdev_base, ramdev_size))) {
server_panic("MEM","Couldn't install remote segment.",s);
}
break;
}
/* Perhaps it is cleaner to move all code relating to psinfo to the info
@ -261,10 +347,9 @@ message *m_ptr; /* pointer to read or write message */
/* MM or FS set the address of their process table. */
phys_bytes psinfo_phys;
if (m_ptr->PROC_NR == MM_PROC_NR) {
if (m_ptr->PROC_NR == PM_PROC_NR) {
psinfo.mproc = (vir_bytes) m_ptr->ADDRESS;
} else
if (m_ptr->PROC_NR == FS_PROC_NR) {
} else if (m_ptr->PROC_NR == FS_PROC_NR) {
psinfo.fproc = (vir_bytes) m_ptr->ADDRESS;
} else {
return(EPERM);

View file

@ -3,7 +3,7 @@
* are written to the printer without any changes at all.
*
* Changes:
* May 07, 2004 wait until printer is ready (Jorrit N. Herder)
* May 07, 2004 fix: wait until printer is ready (Jorrit N. Herder)
* May 06, 2004 printer driver moved to user-space (Jorrit N. Herder)
*
* The valid messages and their parameters are:
@ -278,11 +278,15 @@ PRIVATE void do_initialize()
if (initialized) return;
initialized = TRUE;
#if DEAD_CODE
/* Get the base port for first printer. This used to be done from the
* BIOS with phys_copy(0x408L, vir2phys(&port_base), 2L); but currently
* a magic number is put in place.
*/
port_base = 0x378;
#endif
sys_vircopy(SELF, BIOS_SEG, LPT1_IO_PORT_ADDR,
SELF, D, (vir_bytes) &port_base, LPT1_IO_PORT_SIZE);
sys_outb(port_base + 2, INIT_PRINTER);
tick_delay(1); /* easily satisfies Centronics minimum */
/* was 2 millisecs; now is ~17 millisecs */

View file

@ -56,6 +56,7 @@
#define GA_FONT_SIZE 8192
/* Global variables used by the console driver and assembly support. */
PUBLIC int vid_index; /* index of video segment in remote mem map */
PUBLIC u16_t vid_seg;
PUBLIC vir_bytes vid_off; /* video ram is found at vid_seg:vid_off */
PUBLIC unsigned vid_size; /* 0x2000 for color or 0x0800 for mono */
@ -793,19 +794,19 @@ tty_t *tp;
if (! vdu_initialized++) {
/* How about error checking? What to do on failure??? */
s=sys_vircopy(SELF, BIOS_SEG, (vir_bytes) 0x44AL,
SELF, D, (vir_bytes) &bios_columns, 2L);
s=sys_vircopy(SELF, BIOS_SEG, (vir_bytes) 0x463L,
SELF, D, (vir_bytes) &bios_crtbase, 2L);
s=sys_vircopy(SELF, BIOS_SEG, (vir_bytes) 0x484L,
SELF, D, (vir_bytes) &bios_rows, 1L);
s=sys_vircopy(SELF, BIOS_SEG, (vir_bytes) 0x485L,
SELF, D, (vir_bytes) &bios_fontlines, 2L);
s=sys_vircopy(SELF, BIOS_SEG, (vir_bytes) VDU_SCREEN_COLS_ADDR,
SELF, D, (vir_bytes) &bios_columns, VDU_SCREEN_COLS_SIZE);
s=sys_vircopy(SELF, BIOS_SEG, (vir_bytes) VDU_CRT_BASE_ADDR,
SELF, D, (vir_bytes) &bios_crtbase, VDU_CRT_BASE_SIZE);
s=sys_vircopy(SELF, BIOS_SEG, (vir_bytes) VDU_SCREEN_ROWS_ADDR,
SELF, D, (vir_bytes) &bios_rows, VDU_SCREEN_ROWS_SIZE);
s=sys_vircopy(SELF, BIOS_SEG, (vir_bytes) VDU_FONTLINES_ADDR,
SELF, D, (vir_bytes) &bios_fontlines, VDU_FONTLINES_SIZE);
vid_port = bios_crtbase;
scr_width = bios_columns;
font_lines = bios_fontlines;
scr_lines = kenv.ega ? bios_rows+1 : 25;
scr_lines = machine.vdu_ega ? bios_rows+1 : 25;
if (color) {
vid_base = COLOR_BASE;
@ -814,10 +815,10 @@ tty_t *tp;
vid_base = MONO_BASE;
vid_size = MONO_SIZE;
}
if (kenv.ega) vid_size = EGA_SIZE;
wrap = !kenv.ega;
if (machine.vdu_ega) vid_size = EGA_SIZE;
wrap = ! machine.vdu_ega;
s = sys_phys2seg(&vid_seg, &vid_off, vid_base, vid_size);
s = sys_segctl(&vid_index, &vid_seg, &vid_off, vid_base, vid_size);
vid_size >>= 1; /* word count */
vid_mask = vid_size - 1;
@ -1039,11 +1040,11 @@ message *m;
seq2[6].value= color ? 0x0E : 0x0A;
if (!kenv.ega) return(ENOTTY);
if (!machine.vdu_ega) return(ENOTTY);
result = ga_program(seq1); /* bring font memory into view */
result = sys_copy(m->PROC_NR, D, (vir_bytes) m->ADDRESS,
ABS, 0, (phys_bytes) GA_VIDEO_ADDRESS, (phys_bytes)GA_FONT_SIZE);
result = sys_physcopy(m->PROC_NR, D, (vir_bytes) m->ADDRESS,
NONE, PHYS_SEG, (phys_bytes) GA_VIDEO_ADDRESS, (phys_bytes)GA_FONT_SIZE);
result = ga_program(seq2); /* restore */

View file

@ -296,7 +296,7 @@ PRIVATE void set_leds()
{
/* Set the LEDs on the caps, num, and scroll lock keys */
int s;
if (!kenv.pc_at) return; /* PC/XT doesn't have LEDs */
if (! machine.pc_at) return; /* PC/XT doesn't have LEDs */
kb_wait(); /* wait for buffer empty */
if ((s=sys_outb(KEYBD, LED_CODE)) != OK)

View file

@ -141,7 +141,7 @@ PUBLIC tty_t tty_table[NR_CONS+NR_RS_LINES+NR_PTYS];
PUBLIC int ccurrent; /* currently active console */
PUBLIC timer_t *tty_timers; /* queue of TTY timers */
PUBLIC clock_t tty_next_timeout; /* time that the next alarm is due */
PUBLIC struct kenviron kenv; /* kernel environment variables */
PUBLIC struct machine machine; /* kernel environment variables */
/*===========================================================================*
@ -165,7 +165,7 @@ PUBLIC void main(void)
}
/* Get kernel environment (protected_mode, pc_at and ega are needed). */
if (OK != (s=sys_getkenviron(&kenv))) {
if (OK != (s=sys_getmachine(&machine))) {
server_panic("TTY","Couldn't obtain kernel environment.", s);
}

View file

@ -104,8 +104,7 @@ extern clock_t tty_next_timeout; /* next TTY timeout */
#define bufend(buf) ((buf) + buflen(buf))
/* Memory allocated in tty.c, so extern here. */
extern struct kenviron kenv; /* kernel environment (a.o.: pc_at, ega) */
extern struct machine machine; /* machine information (a.o.: pc_at, ega) */
/* Function prototypes for TTY driver. */
/* tty.c */

View file

@ -1,55 +1,129 @@
/* BIOS definitions. Each BIOS entry has an index that is to be used with the
* sys_bioscopy() system call. The raw addresses, sizes, and magic numbers
* are defined here as well. The values that are defined here were collected
* from various kernel files in MINIX 2.0.4.
*
* Author: Jorrit N. Herder
/* Definitions of several known BIOS addresses. The addresses listed here
* are found in three memory areas that have been defined in <ibm/memory.h>.
* - the BIOS interrupt vectors
* - the BIOS data area
* - the motherboard BIOS memory
*
* Created: March 2005, Jorrit N. Herder
*/
#ifndef _BIOS_H
#define _BIOS_H
/* Memory check (is stopped on reboot). */
#define BIOS_MEM_CHECK 0 /* address to stop memory check */
#define ADR_MEM_CHECK 0x472L
#define LEN_MEM_CHECK 1L
#define STOP_MEM_CHECK 0x1234 /* magic number to stop memory check */
/* Centronics printers. */
#define BIOS_PRN_PORTBASE 1 /* base of printer ports */
#define ADR_PRN_PORTBASE 0x408L
#define LEN_PRN_PORTBASE 2L
/* PART I --
* The BIOS interrupt vector table (IVT) area (1024 B as of address 0x0000).
* Although this area holds 256 interrupt vectors (with jump addresses), some
* vectors actually contain important BIOS data. Some addresses are below.
*/
#define BIOS_EQUIP_CHECK_ADDR 0x0044
#define BIOS_EQUIP_CHECK_SIZE 4L
/* Hard disk parameter vectors. */
#define BIOS_WINI_PARAMS 2 /* number of hard disk drives */
#define ADR_WINI_PARAMS 0x475L
#define LEN_WINI_PARAMS 1L
#define BIOS_WINI_0_PARM_VEC 3 /* disk 0 parameters */
#define ADR_WINI_0_PARM_VEC 0x41*4L
#define LEN_WINI_0_PARM_VEC 4L
#define BIOS_WINI_1_PARM_VEC 4 /* disk 1 parameters */
#define ADR_WINI_1_PARM_VEC 0x46*4L
#define LEN_WINI_1_PARM_VEC 4L
#define BIOS_VIDEO_PARAMS_ADDR 0x0074
#define BIOS_VIDEO_PARAMS_SIZE 4L
#define BIOS_FLOP_PARAMS_ADDR 0x0078
#define BIOS_FLOP_PARAMS_SIZE 4L
#define BIOS_HD0_PARAMS_ADDR 0x0104 /* disk 0 parameters */
#define BIOS_HD0_PARAMS_SIZE 4L
#define BIOS_HD1_PARAMS_ADDR 0x0118 /* disk 1 parameters */
#define BIOS_HD1_PARAMS_SIZE 4L
/* PART I --
* Addresses in the BIOS data area (256 B as of address 0x0400). The addresses
* listed below are the most important ones, and the ones that are currently
* used. Other addresses may be defined below when new features are added.
*/
/* Parallel ports (LPT1-LPT4). */
#define COM1_IO_PORT_ADDR 0x400 /* COM1 port address */
#define COM1_IO_PORT_SIZE 2L
#define COM2_IO_PORT_ADDR 0x402 /* COM2 port address */
#define COM2_IO_PORT_SIZE 2L
#define COM3_IO_PORT_ADDR 0x404 /* COM3 port address */
#define COM3_IO_PORT_SIZE 2L
#define COM4_IO_PORT_ADDR 0x406 /* COM4 port address */
#define COM4_IO_PORT_SIZE 2L
/* Serial ports (COM1-COM4). */
#define LPT1_IO_PORT_ADDR 0x408 /* LPT1 port address */
#define LPT1_IO_PORT_SIZE 2L
#define LPT2_IO_PORT_ADDR 0x40A /* LPT2 port address */
#define LPT2_IO_PORT_SIZE 2L
#define LPT3_IO_PORT_ADDR 0x40C /* LPT3 port address */
#define LPT3_IO_PORT_SIZE 2L
#define LPT4_IO_PORT_ADDR 0x40E /* LPT4 port (except on PS/2) */
#define LPT4_IO_PORT_SIZE 2L
/* Video controller (VDU). */
#define VDU_SCREEN_COLS_ADDR 0x44A /* VDU nr of screen columns */
#define VDU_SCREEN_COLS_SIZE 2L
/* Base I/O port address for active 6845 CRT controller. */
#define VDU_CRT_BASE_ADDR 0x463 /* 3B4h = mono, 3D4h = color */
#define VDU_CRT_BASE_SIZE 2L
/* Soft reset flags to control shutdown. */
#define SOFT_RESET_FLAG_ADDR 0x472 /* soft reset flag on Ctl-Alt-Del */
#define SOFT_RESET_FLAG_SIZE 2L
#define STOP_MEM_CHECK 0x1234 /* bypass memory tests & CRT init */
#define PRESERVE_MEMORY 0x4321 /* preserve memory */
#define SYSTEM_SUSPEND 0x5678 /* system suspend */
#define MANUFACTURER_TEST 0x9ABC /* manufacturer test */
#define CONVERTIBLE_POST 0xABCD /* convertible POST loop */
/* ... many other values are used during POST */
/* Hard disk parameters. (Also see BIOS interrupt vector table above.) */
#define NR_HD_DRIVES_ADDR 0x475 /* number of hard disk drives */
#define NR_HD_DRIVES_SIZE 1L
/* Parallel ports (LPT1-LPT4) timeout values. */
#define LPT1_TIMEOUT_ADDR 0x478 /* time-out value for LPT1 */
#define LPT1_TIMEOUT_SIZE 1L
#define LPT2_TIMEOUT_ADDR 0x479 /* time-out value for LPT2 */
#define LPT2_TIMEOUT_SIZE 1L
#define LPT3_TIMEOUT_ADDR 0x47A /* time-out value for LPT3 */
#define LPT3_TIMEOUT_SIZE 1L
#define LPT4_TIMEOUT_ADDR 0x47B /* time-out for LPT4 (except PS/2) */
#define LPT4_TIMEOUT_SIZE 1L
/* Serial ports (COM1-COM4) timeout values. */
#define COM1_TIMEOUT_ADDR 0x47C /* time-out value for COM1 */
#define COM1_TIMEOUT_SIZE 1L
#define COM2_TIMEOUT_ADDR 0x47D /* time-out value for COM2 */
#define COM2_TIMEOUT_SIZE 1L
#define COM3_TIMEOUT_ADDR 0x47E /* time-out value for COM3 */
#define COM3_TIMEOUT_SIZE 1L
#define COM4_TIMEOUT_ADDR 0x47F /* time-out value for COM4 */
#define COM4_TIMEOUT_SIZE 1L
/* Video controller (VDU). */
#define BIOS_VDU_COLUMNS 5
#define ADR_VDU_COLUMNS 0x44AL
#define LEN_VDU_COLUMNS 2L
#define BIOS_VDU_CRTBASE 6
#define ADR_VDU_CRTBASE 0x463L
#define LEN_VDU_CRTBASE 2L
#define BIOS_VDU_ROWS 7
#define ADR_VDU_ROWS 0x484L
#define LEN_VDU_ROWS 1L
#define BIOS_VDU_FONTLINES 8
#define ADR_VDU_FONTLINES 0x485L
#define LEN_VDU_FONTLINES 2L
#define VDU_SCREEN_ROWS_ADDR 0x484 /* screen rows (less 1, EGA+)*/
#define VDU_SCREEN_ROWS_SIZE 1L
#define VDU_FONTLINES_ADDR 0x485 /* point height of char matrix */
#define VDU_FONTLINES_SIZE 2L
/* Video controller (VDU). */
#define VDU_VIDEO_MODE_ADDR 0x49A /* current video mode */
#define VDU_VIDEO_MODE_SIZE 1L
/* PART III --
* The motherboard BIOS memory contains some known values that are currently
* in use. Other sections in the upper memory area (UMA) addresses vary in
* size and locus and are not further defined here. A rough map is given in
* <ibm/memory.h>.
*/
/* Machine ID (we're interested in PS/2 and AT models). */
#define MACHINE_ID_ADDR 0xFFFFE /* BIOS machine ID byte */
#define MACHINE_ID_SIZE 1L
#define PS_386_MACHINE 0xF8 /* ID byte for PS/2 modela 70/80 */
#define PC_AT_MACHINE 0xFC /* PC/AT, PC/XT286, PS/2 models 50/60 */
/* Machine ID. */
#define BIOS_MACHINE_ID 9
#define ADR_MACHINE_ID 0xFFFFEL
#define LEN_MACHINE_ID 1L
#define PS_386_MACHINE 0xF8 /* Machine ID byte for PS/2 model 80 */
#define PC_AT_MACHINE 0xFC /* PC/AT, PC/XT286, PS/2 models 50/60 */
#endif /* _BIOS_H */

174
include/ibm/memory.h Normal file
View file

@ -0,0 +1,174 @@
/* Physical memory layout on IMB compatible PCs. Only the major, fixed memory
* areas are detailed here. Known addresses of the BIOS data area are defined
* in <ibm/bios.h>. The map upper memory area (UMA) is only roughly defined
* since the UMA sections may vary in size and locus.
*
* Created: March 2005, Jorrit N. Herder
*/
/* I/O-mapped peripherals. I/O addresses are different from memory addresses
* due to the I/O signal on the ISA bus. Individual I/O ports are defined by
* the drivers that use them or looked up with help of the BIOS.
*/
#define IO_MEMORY_BEGIN 0x0000
#define IO_MEMORY_END 0xFFFF
/* Physical memory layout. Design decisions made for the earliest PCs, caused
* memory to be broken broken into the following four basic pieces:
* - Conventional or base memory: first 640 KB (incl. BIOS data, see below);
* - Upper Memory Area (UMA): upper 384 KB of the first megabyte of memory;
* - High Memory Area (HMA): ~ first 64 KB of the second megabyte of memory;
* - Extended Memory: all the memory above first megabyte of memory.
* The high memory area overlaps with the first 64 KB of extended memory, but
* is different from the rest of extended memory because it can be accessed
* when the processor is in real mode.
*/
#define BASE_MEM_BEGIN 0x000000
#define BASE_MEM_END 0x09FFFF
#define UPPER_MEM_BEGIN 0x0A0000
#define UPPER_MEM_END 0x0FFFFF
#define HIGH_MEM_BEGIN 0x100000
#define HIGH_MEM_END 0x10FFEF
#define EXTENDED_MEM_BEGIN 0x100000
#define EXTENDED_MEM_END ((unsigned) -1)
/* The logical memory map of the first 1.5 MB is as follows (hexadecimals):
*
* offset [size] (id) = memory usage
* ------------------------------------------------------------------------
* 000000 [00400] (I) = Real-Mode Interrupt Vector Table (1024 B)
* 000400 [00100] (B) = BIOS Data Area (256 B)
* 000800 [00066] (W) = 80286 Loadall workspace
* 010000 [10000] (c) = Real-Mode Compatibility Segment (64 KB)
* 020000 [70000] (.) = Program-accessible memory (free)
* 090000 [10000] (E) = BIOS Extension
* 0A0000 [10000] (G) = Graphics Mode Video RAM
* 0B0000 [08000] (M) = Monochrome Text Mode Video RAM
* 0B8000 [08000] (C) = Color Text Mode Video RAM
* 0C0000 [08000] (V) = Video ROM BIOS (would be "a" in PS/2)
* 0C8000 [18000] (a) = Adapter ROM + special-purpose RAM (free UMA space)
* 0E0000 [10000] (r) = PS/2 Motherboard ROM BIOS (free UMA in non-PS/2)
* 0F0000 [06000] (R) = Motherboard ROM BIOS
* 0F6000 [08000] (b) = IBM Cassette BASIC ROM ("R" in IBM compatibles)
* 0FD000 [02000] (R) = Motherboard ROM BIOS
* 100000 [.....] (.) = Extended memory, program-accessible (free)
* 100000 [0FFEF] (h) = High Memory Area (HMA)
*
*
* Conventional (Base) Memory:
*
* : [~~~~~16 KB~~~~][~~~~~16 KB~~~~][~~~~~16 KB~~~~][~~~~~16 KB~~~~]
* : 0---1---2---3---4---5---6---7---8---9---A---B---C---D---E---F---
* 000000: IBW.............................................................
* 010000: cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
* 020000: ................................................................
* 030000: ................................................................
* 040000: ................................................................
* 050000: ................................................................
* 060000: ................................................................
* 070000: ................................................................
* 080000: ................................................................
* 090000: EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
*
* Upper Memory Area (UMA):
*
* : 0---1---2---3---4---5---6---7---8---9---A---B---C---D---E---F---
* 0A0000: GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
* 0B0000: MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
* 0C0000: VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
* 0D0000: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
* 0E0000: rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
* 0F0000: RRRRRRRRRRRRRRRRRRRRRRRRbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbRRRRRRRR
*
* Extended Memory:
*
* : 0---1---2---3---4---5---6---7---8---9---A---B---C---D---E---F---
* 100000: hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh.
* 110000: ................................................................
* 120000: ................................................................
* 130000: ................................................................
* 140000: ................................................................
* 150000: ................................................................
* 160000: ................................................................
* 170000: ................................................................
*
* Source: The logical memory map was partly taken from the book "Upgrading
* & Repairing PCs Eight Edition", Macmillan Computer Publishing.
*/
/* The bottom part of conventional or base memory is occupied by BIOS data.
* The BIOS memory can be distinguished in two parts:
* o The first the first 1024 bytes of addressable memory contains the BIOS
* real-mode interrupt vector table (IVT). The table is used to access BIOS
* hardware services in real-mode by loading a interrupt vector and issuing
* an INT instruction. Some vectors contain BIOS data that can be retrieved
* directly and are useful in protected-mode as well.
* o The BIOS data area is located directly above the interrupt vectors. It
* comprises 256 bytes of memory. These data are used by the device drivers
* to retrieve hardware details, such as I/O ports to be used.
*/
#define BIOS_MEM_BEGIN 0x00000 /* all BIOS memory */
#define BIOS_MEM_END 0x004FF
#define BIOS_IVT_BEGIN 0x00000 /* BIOS interrupt vectors */
#define BIOS_IVT_END 0x003FF
#define BIOS_DATA_BEGIN 0x00400 /* BIOS data area */
#define BIOS_DATA_END 0x004FF
/* The base memory is followed by 384 KB reserved memory located at the top of
* the first MB of physical memory. This memory is known as the upper memory
* area (UMA). It is used for memory-mapped peripherals, such as video RAM,
* adapter BIOS (adapter ROM and special purpose RAM), and the motherboard
* BIOS (I/O system, Power-On Self Test, bootstrap loader). The upper memory
* can roughly be distinguished in three parts:
*
* o The first 128K of the upper memory area (A0000-BFFFF) is reserved for use
* by memory-mapped video adapters. Hence, it is also called Video RAM. The
* display driver can directly write to this memory and request the hardware
* to show the data on the screen.
*/
#define UMA_VIDEO_RAM_BEGIN 0xA0000 /* video RAM */
#define UMA_VIDEO_RAM_END 0xBFFFF
#define UMA_GRAPHICS_RAM_BEGIN 0xA0000 /* graphics RAM */
#define UMA_GRAPHICS_RAM_END 0xAFFFF
#define UMA_MONO_TEXT_BEGIN 0xB0000 /* monochrome text */
#define UMA_MONO_TEXT_END 0xB7FFF
#define UMA_COLOR_TEXT_BEGIN 0xB8000 /* color text */
#define UMA_COLOR_TEXT_END 0xBFFFF
/* o The next 128K (the memory range C0000-DFFFF) is reserved for the adapter
* BIOS that resides in the ROM on some adapter boards. Most VGA-compatible
* video adapters use the first 32 KB of this area for their on-board BIOS.
* The rest can be used by any other adapters. The IDE controller often
* occupies the second 32 KB.
*/
#define UMA_ADAPTER_BIOS_BEGIN 0xC0000 /* adapter BIOS */
#define UMA_ADAPTER_BIOS_END 0xDFFFF
#define UMA_VIDEO_BIOS_BEGIN 0xC0000 /* video adapter */
#define UMA_VIDEO_BIOS_END 0xC7FFF
#define UMA_IDE_HD_BIOS_BEGIN 0xC8000 /* IDE hard disk */
#define UMA_IDE_HD_BIOS_END 0xCBFFF
/* o The last 128K of the upper memory area (E0000-FFFFF) is reserved for
* motherboard BIOS (Basic I/O System). The POST (Power-On Self Test) and
* bootstrap loader also reside in this space. The memory falls apart in
* two areas: Plug & Play BIOS data and the system BIOS data.
*/
#define UMA_MB_BIOS_BEGIN 0xE0000 /* motherboard BIOS */
#define UMA_MB_BIOS_END 0xFFFFF
#define UMA_PNP_ESCD_BIOS_BEGIN 0xE0000 /* PnP extended data */
#define UMA_PNP_ESCD_BIOS_END 0xEFFFF
#define UMA_SYSTEM_BIOS_BEGIN 0xF0000 /* system BIOS */
#define UMA_SYSTEM_BIOS_END 0xFFFFF

View file

@ -45,7 +45,7 @@
#define CTRLR(n) (NONE + (n))
/* User-level processes, that is, device drivers, servers, and INIT. */
#define MM_PROC_NR 0 /* memory manager */
#define PM_PROC_NR 0 /* process manager */
#define FS_PROC_NR 1 /* file system */
#define IS_PROC_NR 5 /* information server */
#define TTY 6 /* terminal (TTY) driver */
@ -130,12 +130,11 @@
# define NULL_DEV 3 /* minor device for /dev/null */
# define BOOT_DEV 4 /* minor device for /dev/boot */
# define RANDOM_DEV 5 /* minor device for /dev/random */
# define URANDOM_DEV 6 /* minor device for /dev/urandom */
# define ZERO_DEV 6 /* minor device for /dev/zero */
/* Full device numbers that are special to the boot monitor and FS. */
# define DEV_RAM 0x0100 /* device number of /dev/ram */
# define DEV_BOOT 0x0104 /* device number of /dev/boot */
# define DEV_RANDOM 0x0105 /* device number of /dev/random */
# define DEV_URANDOM 0x0106 /* device number of /dev/urandom */
/*===========================================================================*
@ -204,40 +203,40 @@
* modifying the system call numbers. The numbers here determine which call
* is made from the call vector.
*/
#define NR_SYS_CALLS 32 /* number of system calls */
#define NR_SYS_CALLS 33 /* number of system calls */
# define SYS_TIMES 0 /* sys_times(proc_nr, bufptr) */
# define SYS_XIT 1 /* sys_xit(parent, proc) */
# define SYS_GETSIG 2 /* sys_getsig(proc_nr, sig_map) */
# define SYS_SIGCTL 3 /* sys_sigctl(req,pnr,sig,ctxt,flag,pnr,map) */
# define SYS_FORK 4 /* sys_fork(parent, child, pid) */
# define SYS_NEWMAP 5 /* sys_newmap(proc_nr, map_ptr) */
# define SYS_COPY 6 /* sys_copy(ptr) */
# define SYS_ENDSIG 6 /* sys_endsig(proc_nr) */
# define SYS_EXEC 7 /* sys_exec(proc_nr, new_sp) */
# define SYS_SIGSEND 8 /* sys_sigsend(proc_nr, ctxt_ptr) */
# define SYS_ABORT 9 /* sys_abort() */
# define SYS_KILL 10 /* sys_kill(proc_nr, sig) */
# define SYS_UMAP 11 /* sys_umap(proc_nr, etc) */
# define SYS_RANDOM 12 /* sys_random(...) */
# define SYS_TRACE 13 /* sys_trace(req,pid,addr,data) */
# define SYS_VCOPY 14 /* sys_vcopy(src_p, dst_p, vcpy_s, vcpy_ptr) */
# define SYS_SIGNALRM 15 /* sys_signalrm(proc_nr, ticks) */
# define SYS_SYNCALRM 16 /* sys_syncalrm(proc_nr,exp_time,abs_time) */
# define SYS_FLAGALRM 17 /* sys_flagalrm(ticks, flag_ptr) */
# define SYS_SVRCTL 19 /* sys_svrctl(proc_nr, req, argp) */
# define SYS_SDEVIO 20 /* sys_sdevio(port, proc_nr, buf, count) */
# define SYS_SIGRETURN 21 /* sys_sigreturn(proc_nr, ctxt_ptr, flags) */
# define SYS_GETINFO 22 /* sys_getinfo(what, whereto) */
# define SYS_DEVIO 23 /* sys_devio(port, value) */
# define SYS_VDEVIO 24 /* sys_vdevio(buf_ptr, nr_ports) */
# define SYS_IRQCTL 25 /* sys_irqctl() */
# define SYS_KMALLOC 26 /* sys_kmalloc(size, phys_base) */
# define SYS_IOPENABLE 27 /* sys_enable_iop() */
# define SYS_PHYS2SEG 28 /* sys_phys2seg(*seg, *off, phys) */
# define SYS_SEGCTL 28 /* sys_segctl(*idx, *seg, *off, phys, size) */
# define SYS_EXIT 29 /* sys_exit(status) */
# define SYS_VIRCOPY 30 /* sys_vircopy(src,seg,addr,dst,seg,addr,cnt) */
# define SYS_PHYSCOPY 31 /* sys_physcopy(src_addr,dst_addr,count) */
# define SYS_MSTATS 32
# define SYS_VIRVCOPY 32 /* sys_virvcopy(vec_ptr, vec_size) */
/* Field names for SYS_MEM, SYS_KMALLOC. */
#define MEM_CHUNK_BASE m4_l1 /* physical base address */
@ -289,11 +288,12 @@
/* Names of message field and paramaters for SYS_EXIT request. */
#define EXIT_STATUS m2_i1 /* zero for normal exit, non-zero else */
/* Field names for SYS_PHYS2SEG. */
/* Field names for SYS_SEGCTL. */
#define SEG_SELECT m4_l1 /* segment selector returned */
#define SEG_OFFSET m4_l2 /* offset in segment returned */
#define SEG_PHYS m4_l3 /* physical address of segment */
#define SEG_SIZE m4_l4 /* segment size */
#define SEG_INDEX m4_l5 /* segment index in remote map */
/* Field names for SYS_VIDCOPY. */
#define VID_REQUEST m4_l1 /* what to do? */
@ -310,7 +310,7 @@
#define ABRT_MON_LEN m1_i3 /* length of monitor params */
#define ABRT_MON_ADDR m1_p1 /* virtual address of monitor params */
/* Field names for SYS_COPY, _UMAP, _VIRCOPY, _PHYSCOPY. */
/* Field names for _UMAP, _VIRCOPY, _PHYSCOPY. */
#define CP_SRC_SPACE m5_c1 /* T or D space (stack is also D) */
#define CP_SRC_PROC_NR m5_i1 /* process to copy from */
#define CP_SRC_ADDR m5_l1 /* address where data come from */
@ -327,7 +327,7 @@
/* Field names for SYS_GETINFO. */
#define I_REQUEST m7_i3 /* what info to get */
# define GET_KENVIRON 0 /* get kernel environment variables */
# define GET_KINFO 0 /* get kernel information structure */
# define GET_IMAGE 1 /* get system image table */
# define GET_PROCTAB 2 /* get (kernel) process table */
# define GET_PROCNR 3 /* find nr of process with name */
@ -339,6 +339,7 @@
# define GET_KADDRESSES 9 /* get various kernel addresses */
# define GET_SCHEDINFO 10 /* get scheduling queues */
# define GET_PROC 11 /* get process slot if given process */
# define GET_MACHINE 12 /* get machine information */
#define I_PROC_NR m7_i4 /* calling process */
#define I_VAL_PTR m7_p1 /* virtual address at caller */
#define I_VAL_LEN m7_i1 /* max length of value */

View file

@ -38,7 +38,7 @@
#endif
#if (MACHINE == IBM_PC && _WORD_SIZE == 4)
#define NR_BUFS 128 /* # blocks in the buffer cache */
#define NR_BUFS 1024 /* # blocks in the buffer cache */
#define NR_BUF_HASH 1024 /* size of buf hash table; MUST BE POWER OF 2*/
#endif
@ -52,7 +52,7 @@
#define LINEWRAP 1 /* console.c - wrap lines at column 80 */
#define ALLOW_GAP_MESSAGES 1 /* proc.c - allow messages in the gap between
* the end of bss and lowest stack address */
#define KMESS_BUF_SIZE 512 /* size in B for kernel messages */
#define KMESS_BUF_SIZE 512 /* size in bytes for kernel messages */
/* Number of controller tasks (/dev/cN device classes). */
#define NR_CTRLRS 2
@ -65,7 +65,10 @@
/* Enable or disable kernel calls (allows for minimal kernel). */
#define ENABLE_K_TRACING 1 /* process tracing can be disabled */
#define ENABLE_K_DEBUGGING 1 /* kernel debugging calls */
#define ENABLE_K_DEBUGGING 0 /* kernel debugging calls */
/* Include or exclude an image of /dev/boot in the boot image. */
#define ENABLE_BOOTDEV 1
/* Include or exclude device drivers. Set to 1 to include, 0 to exclude. */
#define ENABLE_BIOS_WINI 0 /* enable BIOS winchester driver */
@ -110,8 +113,7 @@
* ENABLE_USERPRIV must be set to 1 to allow the features anyway.
*/
#define ENABLE_USERBIOS 0 /* enable user mode BIOS calls */
#define ENABLE_LOOSELDT 0 /* allow imprecise, page based LDT entries */
#define ENABLE_USERIOPL 1 /* enable CPU's IOPL bits for /dev/(k)mem */
#define ENABLE_USERIOPL 0 /* enable CPU's IOPL bits for /dev/(k)mem */
/* NR_CONS, NR_RS_LINES, and NR_PTYS determine the number of terminals the
* system can handle.

View file

@ -42,6 +42,8 @@
#define BIOS_SEG 0x0200 /* flags indicating BIOS memory segment */
#define NR_BIOS_SEGS 3 /* # BIOS memory regions (variable) */
#define PHYS_SEG 0x0300 /* flag indicating entire physical memory */
/* Labels used to disable code sections for different reasons. */
#define DEAD_CODE 0 /* unused code in normal configuration */
#define FUTURE_CODE 0 /* new code to be activated + tested later */

View file

@ -11,7 +11,7 @@
* Sep 02, 2004 added sys_exit (Jorrit N. Herder)
* Aug 15, 2004 added sys_getinfo (Jorrit N. Herder)
* Jul 23, 2004 added sys_umap (Jorrit N. Herder)
* Jul 13, 2004 added sys_enable_iop, sys_phys2seg (Jorrit N. Herder)
* Jul 13, 2004 added sys_enable_iop, sys_segctl (Jorrit N. Herder)
* Mar 20, 2004 added sys_devio, sys_vdevio (Jorrit N. Herder)
*/
@ -41,8 +41,6 @@ _PROTOTYPE( int _taskcall, (int who, int syscallnr, message *msgptr) );
_PROTOTYPE( int sys_abort, (int how, ...) );
_PROTOTYPE( int sys_adjmap, (int proc, struct mem_map *ptr,
vir_clicks data_clicks, vir_clicks sp) );
_PROTOTYPE( int sys_copy, (int src_proc, int src_seg, phys_bytes src_vir,
int dst_proc, int dst_seg, phys_bytes dst_vir, phys_bytes bytes));
_PROTOTYPE( int sys_exec, (int proc, char *ptr, int traced,
char *aout, vir_bytes initpc) );
_PROTOTYPE( int sys_execmap, (int proc, struct mem_map *ptr) );
@ -54,14 +52,9 @@ _PROTOTYPE( int sys_times, (int proc_nr, clock_t *ptr) );
_PROTOTYPE( int sys_getuptime, (clock_t *ticks) );
_PROTOTYPE( int sys_trace, (int req, int proc, long addr, long *data_p) );
_PROTOTYPE( int sys_xit, (int parent, int proc) );
_PROTOTYPE( int sys_kill, (int proc, int sig) );
_PROTOTYPE( int sys_svrctl, (int proc, int req, int priv,vir_bytes argp));
/*==========================================================================*
* New prototypes since MINIX release 2 (Jorrit N. Herder) *
*==========================================================================*/
/* Shorthands for sys_sdevio() system call. */
#define sys_insb(port, proc_nr, buffer, count) \
sys_sdevio(DIO_INPUT, port, DIO_BYTE, proc_nr, buffer, count)
@ -89,7 +82,7 @@ _PROTOTYPE(int sys_syncalrm, (int proc_nr, clock_t exp_time, int abs_time) );
_PROTOTYPE ( int sys_irqctl, (int request, int irq_vec, int policy,
int proc_nr, long port, void *val_ptr, long mask_val) );
/* Shorthands for sys_vircopy() system call. */
/* Shorthands for sys_vircopy() and sys_physcopy() system calls. */
#define sys_biosin(bios_vir, dst_vir, bytes) \
sys_vircopy(SELF, BIOS_SEG, bios_vir, SELF, D, dst_vir, bytes)
#define sys_biosout(src_vir, bios_vir, bytes) \
@ -103,17 +96,22 @@ _PROTOTYPE ( int sys_irqctl, (int request, int irq_vec, int policy,
_PROTOTYPE(int sys_vircopy, (int src_proc, int src_seg, vir_bytes src_vir,
int dst_proc, int dst_seg, vir_bytes dst_vir, phys_bytes bytes) );
_PROTOTYPE(int sys_physcopy, (phys_bytes src_phys, phys_bytes dst_phys,
phys_bytes bytes) );
#define sys_abscopy(src_phys, dst_phys, bytes) \
sys_physcopy(NONE, PHYS_SEG, src_phys, NONE, PHYS_SEG, dst_phys, bytes)
_PROTOTYPE(int sys_physcopy, (int src_proc, int src_seg, vir_bytes src_vir,
int dst_proc, int dst_seg, vir_bytes dst_vir, phys_bytes bytes) );
_PROTOTYPE(int sys_umap, (int proc_nr, int seg, vir_bytes vir_addr,
vir_bytes bytes, phys_bytes *phys_addr) );
_PROTOTYPE(int sys_phys2seg, (u16_t *seg,vir_bytes *off,phys_bytes phys, vir_bytes size));
_PROTOTYPE(int sys_segctl, (int *index, u16_t *seg, vir_bytes *off,
phys_bytes phys, vir_bytes size));
_PROTOTYPE(int sys_enable_iop, (int proc_nr) );
_PROTOTYPE(int sys_kmalloc, (size_t size, phys_bytes *phys_base) );
/* Shorthands for sys_getinfo() system call. */
#define sys_getkmessages(dst) sys_getinfo(GET_KMESSAGES, dst, 0,0,0)
#define sys_getkenviron(dst) sys_getinfo(GET_KENVIRON, dst, 0,0,0)
#define sys_getkinfo(dst) sys_getinfo(GET_KINFO, dst, 0,0,0)
#define sys_getmachine(dst) sys_getinfo(GET_MACHINE, dst, 0,0,0)
#define sys_getproctab(dst) sys_getinfo(GET_PROCTAB, dst, 0,0,0)
#define sys_getproc(dst,nr) sys_getinfo(GET_PROC, dst, 0,0, nr)
#define sys_getprocnr(dst,k,kl) sys_getinfo(GET_PROCNR, dst, 0,k,kl)
@ -129,17 +127,12 @@ _PROTOTYPE(int sys_getinfo, (int request, void *val_ptr, int val_len,
_PROTOTYPE(int sys_exit, (int status) );
/* Shorthands for sys_sigctl() system call. */
#define sys_getsig(proc_nr, sig_map) \
sys_sigctl(S_GETSIG, 0,0,0, proc_nr, sig_map)
#define sys_endsig(proc_nr) \
sys_sigctl(S_ENDSIG, proc_nr, 0,0,0,0)
#define sys_sendsig(proc_nr, sig_ctxt) \
sys_sigctl(S_SENDSIG, proc_nr, sig_ctxt, 0,0,0)
#define sys_sigreturn(proc_nr, sig_ctxt, flags) \
sys_sigctl(S_SIGRETURN, proc_nr, sig_ctxt, flags, 0,0)
_PROTOTYPE(int sys_sigctl, (int request, int proc_nr, struct sigmsg *sig_ctxt,
int flags, int *k_proc_nr, sigset_t *k_sig_map) );
/* Signal control. */
_PROTOTYPE(int sys_kill, (int proc, int sig) );
_PROTOTYPE(int sys_sigsend, (int proc_nr, struct sigmsg *sig_ctxt) );
_PROTOTYPE(int sys_sigreturn, (int proc_nr, struct sigmsg *sig_ctxt, int flags) );
_PROTOTYPE(int sys_getsig, (int *k_proc_nr, sigset_t *k_sig_map) );
_PROTOTYPE(int sys_endsig, (int proc_nr) );
/* NOTE: two different approaches were used to distinguish the device I/O
* types 'byte', 'word', 'long': the latter uses #define and results in a

View file

@ -22,17 +22,33 @@ typedef unsigned long vir_bytes;/* virtual addresses and lengths in bytes */
typedef unsigned long vir_bytes;/* virtual addresses and lengths in bytes */
#endif
/* Memory map for local text, stack, data segments. */
struct mem_map {
vir_clicks mem_vir; /* virtual address */
phys_clicks mem_phys; /* physical address */
vir_clicks mem_len; /* length */
};
/* Memory map for remote memory areas, e.g., for the RAM disk. */
struct far_mem {
int in_use; /* entry in use, unless zero */
phys_clicks mem_phys; /* physical address */
vir_clicks mem_len; /* length */
};
/* Structure for virtual copying by means of a vector with requests. */
struct vir_addr {
int proc_nr;
int segment;
vir_bytes offset;
};
struct vir_cp_req {
struct vir_addr src;
struct vir_addr dst;
phys_bytes count;
};
typedef struct {
vir_bytes iov_addr; /* address of an I/O buffer */
vir_bytes iov_size; /* sizeof an I/O buffer */
@ -74,20 +90,28 @@ struct psinfo { /* information for the ps(1) program */
};
/* This is used to obtain system information through SYS_GETINFO. */
struct kenviron {
struct kinfo {
phys_bytes code_base; /* base of kernel code */
phys_bytes code_size;
phys_bytes data_base; /* base of kernel data */
phys_bytes data_size;
vir_bytes proc_addr; /* virtual address of process table */
phys_bytes kmem_base; /* kernel memory layout (/dev/kmem) */
phys_bytes kmem_size;
phys_bytes bootdev_base; /* boot device from boot image (/dev/boot) */
phys_bytes bootdev_size;
phys_bytes params_base; /* parameters passed by boot monitor */
phys_bytes params_size;
char version[8]; /* kernel version number */
};
struct machine {
int pc_at;
int ps_mca;
int processor;
int protected;
int ega;
int vga;
vir_bytes proc_addr; /* virtual address of process table */
phys_bytes kmem_base; /* kernel memory layout (/dev/kmem) */
phys_bytes kmem_size;
phys_bytes bootfs_base; /* FS image from boot image (/dev/boot) */
phys_bytes bootfs_size;
phys_bytes params_base; /* parameters passed by boot monitor */
phys_bytes params_size;
int vdu_ega;
int vdu_vga;
};
/* The kernel outputs messages in a local buffer, which can be requested and

View file

@ -21,7 +21,7 @@ LIBS = -lsys -lutils -ltimers
HEAD = mpx.o
OBJS = start.o protect.o klibc.o klib.o table.o main.o proc.o \
i8259.o exception.o system.o clock.o memory.o misc.o \
i8259.o exception.o system.o clock.o misc.o \
dummy.o \
rtl8139.o pci.o pci_table.o
@ -91,10 +91,6 @@ main.o: $h/com.h
main.o: proc.h
main.o: sendmask.h
memory.o: $a
memory.o: proc.h
memory.o: protect.h
misc.o: $a
misc.o: $i/stdlib.h
misc.o: $h/com.h
@ -175,9 +171,7 @@ system/system.a: system/irqctl.c
system/system.a: system/misc.c
system/system.a: system/proctl.c
system/system.a: system/sigctl.c
system/system.a: system/srvrctl.c
system/system.a: system/sysctl.c
system/system.a: system/tracing.c
system/system.a: system/debugging.c
system/system.a: system/do_copy.c
system/system.a: system/do_vcopy.c

View file

@ -222,7 +222,7 @@ irq_hook_t *hook;
clock_t now;
/* Acknowledge the PS/2 clock interrupt. */
if (ps_mca) outb(PORT_B, inb(PORT_B) | CLOCK_ACK_BIT);
if (machine.ps_mca) outb(PORT_B, inb(PORT_B) | CLOCK_ACK_BIT);
/* Update user and system accounting times. Charge the current process for
* user time. If the current process is not billable, that is, if a non-user

View file

@ -9,7 +9,7 @@
/* To translate an address in kernel space to a physical address. This is
* the same as umap_local(proc_ptr, D, vir, sizeof(*vir)), but less costly.
*/
#define vir2phys(vir) (data_base + (vir_bytes) (vir))
#define vir2phys(vir) (kinfo.data_base + (vir_bytes) (vir))
/* Constants used in virtual_copy(). Values must be 0 and 1, respectively! */
#define _SRC_ 0
@ -27,6 +27,9 @@
/* How many bytes for (port,value)-pairs vector to copy in. */
#define VDEVIO_BUF_SIZE 128
/* How many elements in vector of virtual copy requests. */
#define VCOPY_VEC_SIZE 16
/* Program stack words and masks. */
#define INIT_PSW 0x0200 /* initial psw */
#define INIT_TASK_PSW 0x1200 /* initial psw for tasks (with IOPL 1) */

View file

@ -62,7 +62,7 @@ unsigned vec_nr;
}
/* Exception in system code. This is not supposed to happen. */
if (ep->msg == NIL_PTR || processor < ep->minprocessor)
if (ep->msg == NIL_PTR || machine.processor < ep->minprocessor)
kprintf("\nIntel-reserved exception %d\n", vec_nr);
else
kprintf("\n%s\n", karg(ep->msg));

View file

@ -16,10 +16,12 @@ EXTERN int shutting_down; /* TRUE if the system is shutting down */
EXTERN struct proc *shutdown_process; /* process awaiting shutdown of */
EXTERN timer_t shutdown_timer; /* watchdog function called after timeout */
/* Kernel memory. */
EXTERN phys_bytes code_base; /* base of kernel code */
EXTERN phys_bytes data_base; /* base of kernel data */
/* Kernel information structures. This groups vital kernel information. */
EXTERN phys_bytes aout; /* address of a.out headers */
EXTERN struct kinfo kinfo; /* kernel information for users */
EXTERN struct machine machine; /* machine information for users */
EXTERN struct kmessages kmess; /* diagnostic messages in kernel */
EXTERN struct memory mem[NR_MEMS]; /* base and size of chunks of memory */
/* Low level notifications may be put on the 'held' queue to prevent races. */
EXTERN struct proc *held_head; /* head of queue of held-up interrupts */
@ -29,29 +31,11 @@ EXTERN unsigned char k_reenter; /* kernel reentry count (entry count less 1)*/
/* Process table. Here to stop too many things having to include proc.h. */
EXTERN struct proc *proc_ptr; /* pointer to currently running process */
/* Memory sizes. */
EXTERN struct memory mem[NR_MEMS]; /* base and size of chunks of memory */
EXTERN phys_clicks tot_mem_size; /* total system memory size */
/* Miscellaneous. */
EXTERN unsigned lost_ticks; /* clock ticks counted outside the clock task */
#if (CHIP == INTEL)
/* Machine type. */
EXTERN int pc_at; /* PC-AT compatible hardware interface */
EXTERN int ps_mca; /* PS/2 with Micro Channel */
EXTERN unsigned int processor; /* 86, 186, 286, 386, ... */
#if _WORD_SIZE == 2
EXTERN int protected_mode; /* nonzero if running in Intel protected mode*/
#else
#define protected_mode 1 /* 386 mode implies protected mode */
#endif
/* Video card types. */
EXTERN int ega; /* nonzero if console is EGA */
EXTERN int vga; /* nonzero if console is VGA */
/* Interrupt related variables. */
EXTERN struct irqtab irqtab[NR_IRQ_VECTORS]; /* table with IRQ policies */
EXTERN irq_hook_t *irq_hooks[NR_IRQ_VECTORS]; /* list of IRQ handlers */
@ -59,11 +43,8 @@ EXTERN int irq_actids[NR_IRQ_VECTORS]; /* IRQ ID bits active */
EXTERN int irq_use; /* bit map of all in-use irq's */
/* Miscellaneous. */
EXTERN struct kmessages kmess; /* diagnostic messages in kernel */
EXTERN reg_t mon_ss, mon_sp; /* monitor stack */
EXTERN int mon_return; /* true if return to the monitor possible */
EXTERN phys_bytes mon_params; /* boot parameter block passed in/out */
EXTERN size_t mon_parmsize; /* boot parameter block size */
/* Variables that are initialized elsewhere are just extern here. */
extern struct system_image image[]; /* system image processes (table.c) */

View file

@ -45,18 +45,18 @@ int mine;
int i;
lock();
if (protected_mode) {
if (machine.protected) {
/* The AT and newer PS/2 have two interrupt controllers, one master,
* one slaved at IRQ 2. (We don't have to deal with the PC that
* has just one controller, because it must run in real mode.)
*/
outb(INT_CTL, ps_mca ? ICW1_PS : ICW1_AT);
outb(INT_CTL, machine.ps_mca ? ICW1_PS : ICW1_AT);
outb(INT_CTLMASK, mine ? IRQ0_VECTOR : BIOS_IRQ0_VEC);
/* ICW2 for master */
outb(INT_CTLMASK, (1 << CASCADE_IRQ)); /* ICW3 tells slaves */
outb(INT_CTLMASK, ICW4_AT);
outb(INT_CTLMASK, ~(1 << CASCADE_IRQ)); /* IRQ 0-7 mask */
outb(INT2_CTL, ps_mca ? ICW1_PS : ICW1_AT);
outb(INT2_CTL, machine.ps_mca ? ICW1_PS : ICW1_AT);
outb(INT2_CTLMASK, mine ? IRQ8_VECTOR : BIOS_IRQ8_VEC);
/* ICW2 for slave */
outb(INT2_CTLMASK, CASCADE_IRQ); /* ICW3 is slave nr */

View file

@ -30,6 +30,7 @@
.define _reset ! reset the system
.define _idle_task ! task executed when there is no work
.define _level0 ! call a function at level 0
.define _read_tsc ! read the cycle counter (Pentium and up)
! The routines only guarantee to preserve the registers the C compiler
! expects to be preserved (ebx, esi, edi, ebp, esp, segment registers, and
@ -495,3 +496,22 @@ _level0:
mov (_level0_func), eax
int LEVEL0_VECTOR
ret
!*===========================================================================*
!* read_tsc *
!*===========================================================================*
! PUBLIC void read_tsc(unsigned long *low, unsigned long *high);
! Read the cycle counter of the CPU. Pentium and up.
.align 16
_read_tsc:
.data1 0x0f ! this is the RDTSC instruction
.data1 0x31 ! it places the TSC in EDX:EAX
push ebp
mov ebp, 8(esp)
mov (ebp), edx
mov ebp, 12(esp)
mov (ebp), eax
pop ebp
ret

File diff suppressed because it is too large Load diff

View file

@ -14,7 +14,6 @@
* Changes:
* Nov 24, 2004 simplified main() with system image (Jorrit N. Herder)
* Oct 21, 2004 moved copyright to announce() (Jorrit N. Herder)
* Sep 30, 2004 moved mem_init() to this file (Jorrit N. Herder)
* Sep 04, 2004 created stop_sequence() to cleanup (Jorrit N. Herder)
* Aug 20, 2004 split wreboot() and shutdown() (Jorrit N. Herder)
* Jun 15, 2004 moved wreboot() to this file (Jorrit N. Herder)
@ -42,8 +41,8 @@ PUBLIC void main()
register struct proc *rp;
register int i;
int hdrindex; /* index to array of a.out headers */
phys_clicks text_base;
vir_clicks text_clicks;
phys_clicks text_base, bootdev_base;
vir_clicks text_clicks, bootdev_clicks;
vir_clicks data_clicks;
reg_t ktsb; /* kernel task stack base */
struct memory *memp;
@ -53,9 +52,6 @@ PUBLIC void main()
/* Initialize the interrupt controller. */
intr_init(1);
/* Make free memory list from memory sizes passed by boot monitor. */
mem_init();
/* Clear the process table. Anounce each slot as empty and
* set up mappings for proc_addr() and proc_number() macros.
*/
@ -90,7 +86,7 @@ PUBLIC void main()
}
ktsb += ttp->stksize; /* point to high end of stack */
rp->p_reg.sp = ktsb; /* this task's initial stack ptr */
text_base = code_base >> CLICK_SHIFT;
text_base = kinfo.code_base >> CLICK_SHIFT;
/* processes that are in the kernel */
hdrindex = 0; /* all use the first a.out header */
} else {
@ -150,44 +146,37 @@ PUBLIC void main()
/* Code and data segments must be allocated in protected mode. */
alloc_segments(rp);
}
bill_ptr = proc_addr(IDLE); /* it has to point somewhere */
/* This actually is not needed, because ready() already set 'proc_ptr' to
* first task that was announced ready.
*/
lock_pick_proc();
/* Expect an image of the root FS to be loaded into memory as well. The
* root FS image is located directly after the programs.
#if ENABLE_BOOTDEV
/* Expect an image of the boot device to be loaded into memory as well.
* The boot device is the last module that is loaded into memory, and,
* for example, can contain the root FS (useful for embedded systems).
*/
hdrindex ++;
phys_copy(aout+hdrindex * A_MINHDR, vir2phys(&e_hdr), (phys_bytes) A_MINHDR);
kprintf("Root FS image found: %s\n", (e_hdr.a_flags&A_IMG)? "yes" : "no");
phys_copy(aout + hdrindex * A_MINHDR,vir2phys(&e_hdr),(phys_bytes) A_MINHDR);
if (e_hdr.a_flags & A_IMG) {
kprintf("Size of root FS: %u, ", e_hdr.a_data);
kprintf("base : %u, ", e_hdr.a_syms);
kprintf("header size : %u, ", e_hdr.a_hdrlen);
rp = proc_addr(MEMORY);
rp->p_farmem[0].mem_phys = e_hdr.a_syms;
rp->p_farmem[0].mem_len = e_hdr.a_data;
kinfo.bootdev_base = e_hdr.a_syms;
kinfo.bootdev_size = e_hdr.a_data;
/* Remove from free list, to prevent being overwritten. */
text_base = e_hdr.a_syms >> CLICK_SHIFT;
text_clicks = (e_hdr.a_text + CLICK_SIZE-1) >> CLICK_SHIFT;
if (!(e_hdr.a_flags & A_SEP)) text_clicks = 0; /* Common I&D */
data_clicks = (e_hdr.a_total + CLICK_SIZE-1) >> CLICK_SHIFT;
bootdev_base = e_hdr.a_syms >> CLICK_SHIFT;
bootdev_clicks = (e_hdr.a_total + CLICK_SIZE-1) >> CLICK_SHIFT;
for (memp = mem; memp < &mem[NR_MEMS]; memp++) {
if (memp->base == text_base) {
kprintf("Memory removed from free list.\n", NO_ARG);
memp->base += text_clicks + data_clicks;
memp->size -= text_clicks + data_clicks;
if (memp->base == bootdev_base) {
memp->base += bootdev_clicks;
memp->size -= bootdev_clicks;
}
}
}
#endif
/* MINIX and all system services have been loaded. Announce to the user.
* Then go to the assembly code to start running the current process.
/* This actually is not needed, because ready() already set 'proc_ptr.' */
lock_pick_proc();
bill_ptr = proc_addr(IDLE); /* it has to point somewhere */
/* MINIX is now ready. Display the startup banner to the user and return
* to the assembly code to start running the current process.
*/
announce();
restart();
@ -201,14 +190,18 @@ PUBLIC void main()
PRIVATE void announce(void)
{
/* Display the MINIX startup banner. */
kprintf("MINIX %s Copyright 2001 Prentice-Hall, Inc.\n",
karg(OS_RELEASE "." OS_VERSION));
kprintf("MINIX %s. Copyright 2001 Prentice-Hall, Inc.\n",
karg(kinfo.version));
#if (CHIP == INTEL)
/* Real mode, or 16/32-bit protected mode? */
kprintf("Executing in %s mode\n\n",
protected_mode ? karg("32-bit protected") : karg("real"));
machine.protected ? karg("32-bit protected") : karg("real"));
#endif
/* Check if boot device was loaded with the kernel. */
if (kinfo.bootdev_base > 0)
kprintf("Image of /dev/boot loaded. Size: %u KB.\n", kinfo.bootdev_size);
}
@ -274,7 +267,7 @@ timer_t *tp;
/* See if the last process' shutdown was successfull. Else, force exit. */
if (p != NIL_PROC) {
kprintf("[%s]\n", isalivep(p) ? "FAILED" : "OK");
kprintf("[%s]\n", isalivep(p) ? karg("FAILED") : karg("OK"));
if (isalivep(p))
clear_proc(p->p_nr); /* now force process to exit */
}
@ -289,8 +282,8 @@ timer_t *tp;
if (p == NIL_PROC) p = BEG_PROC_ADDR;
while (TRUE) {
if (isalivep(p) && p->p_type == level) { /* found a process */
kprintf("- Stopping %s ", p->p_name);
kprintf("%s ... ", types[p->p_type]);
kprintf("- Stopping %s ", karg(p->p_name));
kprintf("%s ... ", karg(types[p->p_type]));
shutdown_process = p; /* directly continue if exited */
notify(proc_number(p), HARD_STOP);
set_timer(tp, get_uptime()+STOP_TICKS, stop_sequence);
@ -336,15 +329,15 @@ timer_t *tp;
* For RBT_MONITOR, the MM has provided the program.
*/
if (how == RBT_HALT) {
phys_copy(vir2phys(" "), mon_params, 2);
phys_copy(vir2phys("delay;"), kinfo.params_base, 7);
} else if (how == RBT_REBOOT) {
phys_copy(vir2phys("delay;boot"), mon_params, 11);
phys_copy(vir2phys("delay;boot"), kinfo.params_base, 11);
}
level0(monitor);
}
/* Stop BIOS memory test. */
phys_copy(vir2phys(&magic), (phys_bytes) ADR_MEM_CHECK, LEN_MEM_CHECK);
phys_copy(vir2phys(&magic), SOFT_RESET_FLAG_ADDR, SOFT_RESET_FLAG_SIZE);
/* Reset the system by jumping to the reset address (real mode), or by
* forcing a processor shutdown (protected mode).

View file

@ -1,120 +0,0 @@
/* Entry points into this file:
* mem_init: create a list a free memory
* alloc_segments: allocate segments for 8088 or higher processor
*/
#include "kernel.h"
#include "protect.h"
#include "proc.h"
#if (CHIP == INTEL)
/* In real mode only 1M can be addressed, and in 16-bit protected we can go
* no further than we can count in clicks. (The 286 is further limited by
* its 24 bit address bus, but we can assume in that case that no more than
* 16M memory is reported by the BIOS.)
*/
#define MAX_REAL 0x00100000L
#define MAX_16BIT (0xFFF0L << CLICK_SHIFT)
/*=========================================================================*
* mem_init *
*=========================================================================*/
PUBLIC void mem_init()
{
/* Initialize the free memory list from the 'memory' boot variable. Translate
* the byte offsets and sizes in this list to clicks, properly truncated. Also
* make sure that we don't exceed the maximum address space of the 286 or the
* 8086, i.e. when running in 16-bit protected mode or real mode.
*/
long base, size, limit;
char *s, *end; /* use to parse boot variable */
int i;
struct memory *memp;
#if _WORD_SIZE == 2
unsigned long max_address;
#endif
/* The available memory is determined by MINIX' boot loader as a list of
* (base:size)-pairs in boothead.s. The 'memory' boot variable is set in
* in boot.s. The format is "b0:s0,b1:s1,b2:s2", where b0:s0 is low mem,
* b1:s1 is mem between 1M and 16M, b2:s2 is mem above 16M. Pairs b1:s1
* and b2:s2 are combined if the memory is adjacent.
*/
s = getkenv("memory"); /* get memory boot variable */
tot_mem_size = 0;
for (i = 0; i < NR_MEMS; i++) {
memp = &mem[i]; /* result is stored here */
base = size = 0;
if (*s != 0) { /* end of boot variable */
/* Expect base to be read (end != s) and ':' as next char. */
base = kstrtoul(s, &end, 0x10); /* get number */
if (end != s && *end == ':') s = ++end; /* skip ':' */
else *s=0; /* fake end for next; should not happen */
/* Expect size to be read and skip ',', unless at end. */
size = kstrtoul(s, &end, 0x10); /* get number */
if (end != s && *end == ',') s = ++end; /* skip ',' */
else if (end != s && *end == 0) s = end; /* end found */
else *s=0; /* fake end for next; should not happen */
}
limit = base + size;
#if _WORD_SIZE == 2
max_address = protected_mode ? MAX_16BIT : MAX_REAL;
if (limit > max_address) limit = max_address;
#endif
base = (base + CLICK_SIZE-1) & ~(long)(CLICK_SIZE-1);
limit &= ~(long)(CLICK_SIZE-1);
if (limit <= base) continue;
memp->base = base >> CLICK_SHIFT;
memp->size = (limit - base) >> CLICK_SHIFT;
tot_mem_size += memp->size;
}
}
/*==========================================================================*
* alloc_segments *
*==========================================================================*/
PUBLIC void alloc_segments(rp)
register struct proc *rp;
{
/* This is called at system initialization from main() and by do_newmap().
* The code has a separate function because of all hardware-dependencies.
* Note that IDLE is part of the kernel and gets TASK_PRIVILEGE here.
*/
phys_bytes code_bytes;
phys_bytes data_bytes;
int privilege;
if (protected_mode) {
data_bytes = (phys_bytes) (rp->p_memmap[S].mem_vir +
rp->p_memmap[S].mem_len) << CLICK_SHIFT;
if (rp->p_memmap[T].mem_len == 0)
code_bytes = data_bytes; /* common I&D, poor protect */
else
code_bytes = (phys_bytes) rp->p_memmap[T].mem_len << CLICK_SHIFT;
privilege = (isidlep(rp) || istaskp(rp)) ?
TASK_PRIVILEGE : USER_PRIVILEGE;
init_codeseg(&rp->p_ldt[CS_LDT_INDEX],
(phys_bytes) rp->p_memmap[T].mem_phys << CLICK_SHIFT,
code_bytes, privilege);
init_dataseg(&rp->p_ldt[DS_LDT_INDEX],
(phys_bytes) rp->p_memmap[D].mem_phys << CLICK_SHIFT,
data_bytes, privilege);
rp->p_reg.cs = (CS_LDT_INDEX * DESC_SIZE) | TI | privilege;
#if _WORD_SIZE == 4
rp->p_reg.gs =
rp->p_reg.fs =
#endif
rp->p_reg.ss =
rp->p_reg.es =
rp->p_reg.ds = (DS_LDT_INDEX*DESC_SIZE) | TI | privilege;
} else {
rp->p_reg.cs = click_to_hclick(rp->p_memmap[T].mem_phys);
rp->p_reg.ss =
rp->p_reg.es =
rp->p_reg.ds = click_to_hclick(rp->p_memmap[D].mem_phys);
}
}
#endif /* (CHIP == INTEL) */

View file

@ -1,762 +0,0 @@
#
! This file, mpx88.s, is included by mpx.s when Minix is compiled for
! 16-bit Intel CPUs. The alternative mpx386.s is compiled for 32-bit CPUs.
!
! This file contains the assembler startup code for Minix and the 16-bit
! interrupt handlers. It cooperates with cstart.c to set up a good
! environment for main().
! This file is part of the lowest layer of the MINIX kernel. The other part
! is "proc.c". The lowest layer does process switching and message handling.
! Every transition to the kernel goes through this file. Transitions are
! caused by sending/receiving messages and by most interrupts. (RS232
! interrupts may be handled in the file "rs2.s" and then they rarely enter
! the kernel.)
! Transitions to the kernel may be nested. The initial entry may be with a
! system call, exception or hardware interrupt; reentries may only be made
! by hardware interrupts. The count of reentries is kept in "k_reenter".
! It is important for deciding whether to switch to the kernel stack and
! for protecting the message passing code in "proc.c".
! For the message passing trap, most of the machine state is saved in the
! proc table. (Some of the registers need not be saved.) Then the stack is
! switched to "k_stack", and interrupts are reenabled. Finally, the system
! call handler (in C) is called. When it returns, interrupts are disabled
! again and the code falls into the restart routine, to finish off held-up
! interrupts and run the process or task whose pointer is in "proc_ptr".
! Hardware interrupt handlers do the same, except (1) The entire state must
! be saved. (2) There are too many handlers to do this inline, so the save
! routine is called. A few cycles are saved by pushing the address of the
! appropiate restart routine for a return later. (3) A stack switch is
! avoided when the stack is already switched. (4) The (master) 8259 interrupt
! controller is reenabled centrally in save(). (5) Each interrupt handler
! masks its interrupt line using the 8259 before enabling (other unmasked)
! interrupts, and unmasks it after servicing the interrupt. This limits the
! nest level to the number of lines and protects the handler from itself.
! For communication with the boot monitor at startup time some constant
! data are compiled into the beginning of the text segment. This facilitates
! reading the data at the start of the boot process, since only the first
! sector of the file needs to be read.
! Some data storage is also allocated at the end of this file. This data
! will be at the start of the data segment of the kernel and will be read
! and modified by the boot monitor before the kernel starts.
#include <minix/config.h>
#include <minix/const.h>
#include <minix/com.h>
#include "const.h"
#include "sconst.h"
#include "protect.h"
! The external entry points into this file are:
! Note: in assembly language the .define statement applied to a function name
! is loosely equivalent to a prototype in C code -- it makes it possible to
! link to an entity declared in the assembly code but does not create
! the entity.
.define _int00 ! handlers for traps and exceptions
.define _int01
.define _int02
.define _int03
.define _int04
.define _int05
.define _int06
.define _int07
.define _hwint00 ! handlers for hardware interrupts
.define _hwint01
.define _hwint02
.define _hwint03
.define _hwint04
.define _hwint05
.define _hwint06
.define _hwint07
.define _hwint08
.define _hwint09
.define _hwint10
.define _hwint11
.define _hwint12
.define _hwint13
.define _hwint14
.define _hwint15
.define _restart ! start running a task or process
.define save ! save the machine state in the proc table
.define _s_call ! process or task wants to send or receive a message
! Exported variables.
.define kernel_ds
.define begbss
.define begdata
.text
!*===========================================================================*
!* MINIX *
!*===========================================================================*
MINIX: ! this is the entry point for the MINIX kernel
jmp over_kernel_ds ! skip over the next few bytes
.data2 CLICK_SHIFT ! for the monitor: memory granularity
kernel_ds:
.data2 0x01B4 ! boot monitor flags: (later kernel DS)
! call in 8086 mode, make bss, make stack,
! load low, don`t patch, will return,
! (has own INT calls), memory vector,
! new boot code return
over_kernel_ds:
! Set up a C stack frame on the monitor stack. (The monitor sets cs and ds
! right. The ss register still references the monitor data segment.)
push bp
mov bp, sp
push si
push di
cmp 4(bp), #0 ! monitor code segment is
jz noret ! nonzero if return possible
inc _mon_return
noret: mov _mon_ss, ss ! save stack location for later return
mov _mon_sp, sp
! Locate boot parameters, set up kernel segment registers and stack.
mov bx, 6(bp) ! boot parameters offset
mov dx, 8(bp) ! boot parameters length
mov ax, 10(bp) ! address of a.out headers
mov _aout+0, ax
mov ax, 12(bp)
mov _aout+2, ax
mov ax, ds ! kernel data
mov es, ax
mov ss, ax
mov sp, #k_stktop ! set sp to point to the top of kernel stack
! Real mode needs to get kernel DS from the code segment. Protected mode
! needs CS in the jump back to real mode.
cseg mov kernel_cs, cs
cseg mov kernel_ds, ds
! Call C startup code to set up a proper environment to run main().
push dx
push bx
push _mon_ss
push ds
push cs
call _cstart ! cstart(cs, ds, mds, parmoff, parmlen)
add sp, #5*2
cmp _protected_mode, #0
jz nosw ! ok to switch to protected mode?
call klib_init_prot ! initialize klib functions for protected mode
call real2prot ! switch to protected mode
push #0 ! set flags to known good state
popf ! especially, clear nested task and int enable
nosw:
jmp _main ! main()
!*===========================================================================*
!* interrupt handlers *
!*===========================================================================*
!*===========================================================================*
!* hwint00 - 07 *
!*===========================================================================*
! Note that the first few lines are a macro
#define hwint_master(irq) \
call save /* save interrupted process state */;\
mov si, *[2*irq] /* load array index offset */;\
mov di, *[1<<irq] /* irq mask bit */;\
jmp hwint_master /* continue with common code */
hwint_master:
inb INT_CTLMASK
or ax, di ! al |= (1 << irq)
outb INT_CTLMASK ! disable the irq
movb al, *ENABLE
outb INT_CTL ! reenable master 8259
mov cx, _irq_hooks(si) ! irq_hooks[irq]
push cx
sti ! enable interrupts
call _intr_handle ! intr_handle(irq_hooks[irq])
cli ! disable interrupts
pop cx
cmp _irq_actids(si), *0 ! interrupt still active?
jnz 0f
inb INT_CTLMASK
not di
and ax, di ! al &= ~(1 << irq)
outb INT_CTLMASK ! enable the irq
0: ret ! restart (another) process
! Each of these entry points is an expansion of the hwint_master macro
_hwint00: ! Interrupt routine for irq 0 (the clock).
hwint_master(0)
_hwint01: ! Interrupt routine for irq 1 (keyboard)
hwint_master(1)
_hwint02: ! Interrupt routine for irq 2 (cascade!)
hwint_master(2)
_hwint03: ! Interrupt routine for irq 3 (second serial)
hwint_master(3)
_hwint04: ! Interrupt routine for irq 4 (first serial)
hwint_master(4)
_hwint05: ! Interrupt routine for irq 5 (XT winchester)
hwint_master(5)
_hwint06: ! Interrupt routine for irq 6 (floppy)
hwint_master(6)
_hwint07: ! Interrupt routine for irq 7 (printer)
hwint_master(7)
!*===========================================================================*
!* hwint08 - 15 *
!*===========================================================================*
! Note that the first few lines are a macro
#define hwint_slave(irq) \
call save /* save interrupted process state */;\
mov si, *[2*irq] /* load array index offset */;\
mov di, *[1<<[irq-8]] /* irq mask bit */;\
jmp hwint_slave /* continue with common code */
hwint_slave:
inb INT2_CTLMASK
or ax, di ! al |= (1 << (irq-8))
outb INT2_CTLMASK ! disable the irq
movb al, *ENABLE
outb INT_CTL ! reenable master 8259
mov cx, _irq_hooks(si) ! irq_hooks[irq]
outb INT2_CTL ! reenable slave 8259
push cx
sti ! enable interrupts
call _intr_handle ! intr_handle(irq_hooks[irq])
cli ! disable interrupts
pop cx
cmp _irq_actids(si), *0 ! interrupt still active?
jnz 0f
inb INT2_CTLMASK
not di
and ax, di ! al &= ~(1 << (irq-8))
outb INT2_CTLMASK ! enable the irq
0: ret ! restart (another) process
! Each of these entry points is an expansion of the hwint_slave macro
_hwint08: ! Interrupt routine for irq 8 (realtime clock)
hwint_slave(8)
_hwint09: ! Interrupt routine for irq 9 (irq 2 redirected)
hwint_slave(9)
_hwint10: ! Interrupt routine for irq 10
hwint_slave(10)
_hwint11: ! Interrupt routine for irq 11
hwint_slave(11)
_hwint12: ! Interrupt routine for irq 12
hwint_slave(12)
_hwint13: ! Interrupt routine for irq 13 (FPU exception)
hwint_slave(13)
_hwint14: ! Interrupt routine for irq 14 (AT winchester)
hwint_slave(14)
_hwint15: ! Interrupt routine for irq 15
hwint_slave(15)
!*===========================================================================*
!* save *
!*===========================================================================*
save: ! save the machine state in the proc table.
! In protected mode a jump to p_save is patched over the following
! code during initialization.
cld ! set direction flag to a known value
push ds
push si
cseg mov ds,kernel_ds
incb _k_reenter ! from -1 if not reentering
jnz push_current_stack ! stack is already kernel stack
mov si,_proc_ptr
mov AXREG(si),ax
mov BXREG(si),bx
mov CXREG(si),cx
mov DXREG(si),dx
pop SIREG(si)
mov DIREG(si),di
mov BPREG(si),bp
mov ESREG(si),es
pop DSREG(si)
pop bx ! return adr
pop PCREG(si)
pop CSREG(si)
pop PSWREG(si)
mov SPREG(si),sp
mov SSREG(si),ss
mov dx,ds
mov ss,dx
mov sp,#k_stktop
mov ax,#_restart ! build return address for interrupt handler
push ax
stack_switched:
mov es,dx
jmp (bx)
push_current_stack:
push es
push bp
push di
push dx
push cx
push bx
push ax
mov bp,sp
mov bx,18(bp) ! get the return adr; it becomes junk on stack
mov ax,#restart1
push ax
mov dx,ss
mov ds,dx
jmp stack_switched
!*===========================================================================*
!* s_call *
!*===========================================================================*
! This is real mode version. Alternate (_p_s_call) will be used in
! protected mode
_s_call: ! System calls are vectored here.
! Do save routine inline for speed,
! but do not save ax, bx, cx, dx,
! since C does not require preservation,
! and ax returns the result code anyway.
! Regs bp, si, di get saved by sys_call as
! well, but it is impractical not to preserve
! them here, in case context gets switched.
! Some special-case code in pick_proc()
! could avoid this.
cld ! set direction flag to a known value
push ds
push si
cseg mov ds,kernel_ds
incb _k_reenter
mov si,_proc_ptr
pop SIREG(si)
mov DIREG(si),di
mov BPREG(si),bp
mov ESREG(si),es
pop DSREG(si)
pop PCREG(si)
pop CSREG(si)
pop PSWREG(si)
mov SPREG(si),sp
mov SSREG(si),ss
mov dx,ds
mov es,dx
mov ss,dx ! interrupt handlers may not make system calls
mov sp,#k_stktop ! so stack is not already switched
! end of inline save
! now set up parameters for C routine sys_call
push bx ! pointer to user message
push ax ! src/dest
push cx ! SEND/RECEIVE/BOTH
sti ! allow SWITCHER to be interrupted
call _sys_call ! sys_call(function, src_dest, m_ptr)
! caller is now explicitly in proc_ptr
mov AXREG(si),ax ! sys_call MUST PRESERVE si
cli
! Fall into code to restart proc/task running.
!*===========================================================================*
!* restart *
!*===========================================================================*
_restart:
! Flush any held-up interrupts.
! This reenables interrupts, so the current interrupt handler may reenter.
! This does not matter, because the current handler is about to exit and no
! other handlers can reenter since flushing is only done when k_reenter == 0.
! In protected mode a jump to p_restart is patched over the following
! code during initialization.
cmp _held_head,#0 ! do fast test to usually avoid function call
jz over_call_unhold
call _unhold ! this is rare so overhead is acceptable
over_call_unhold:
mov si,_proc_ptr
decb _k_reenter
mov ax,AXREG(si) ! start restoring registers from proc table
! could make AXREG == 0 to use lodw here
mov bx,BXREG(si)
mov cx,CXREG(si)
mov dx,DXREG(si)
mov di,DIREG(si)
mov bp,BPREG(si)
mov es,ESREG(si)
mov ss,SSREG(si)
mov sp,SPREG(si)
push PSWREG(si) ! fake interrupt stack frame
push CSREG(si)
push PCREG(si)
! could put si:ds together to use
! lds si,SIREG(si)
push DSREG(si)
mov si,SIREG(si)
pop ds
iret
restart1:
decb _k_reenter
pop ax
pop bx
pop cx
pop dx
pop di
pop bp
pop es
pop si
pop ds
add sp,#2 ! skip return adr
iret
!*===========================================================================*
!* int00-07 *
!*===========================================================================*
! These are entry points for exceptions (processor generated interrupts,
! usually caused by error conditions such as an attempt to divide by zero)
_int00: ! interrupt through vector 0
push ax
movb al,#0
jmp exception
_int01: ! interrupt through vector 1, etc
push ax
movb al,#1
jmp exception
_int02:
push ax
movb al,#2
jmp exception
_int03:
push ax
movb al,#3
jmp exception
_int04:
push ax
movb al,#4
jmp exception
_int05:
push ax
movb al,#5
jmp exception
_int06:
push ax
movb al,#6
jmp exception
_int07:
push ax
movb al,#7
!jmp exception
exception:
cseg movb ex_number,al ! it is cumbersome to get this into dseg
pop ax
call save
cseg push ex_number ! high byte is constant 0
call _exception ! do whatever is necessary (sti only if safe)
add sp,#2
cli
ret
!*===========================================================================*
!* level0_call *
!*===========================================================================*
_level0_call:
call save
jmp @_level0_func
!*===========================================================================*
!* data *
!*===========================================================================*
! NB some variables are stored in code segment.
ex_number: ! exception number
.space 2
!*===========================================================================*
!* variants for 286 protected mode *
!*===========================================================================*
! Most routines are different in 286 protected mode.
! The only essential difference is that an interrupt in protected mode
! (usually) switches the stack, so there is less to do in software.
! These functions are reached along jumps patched in by klib_init_prot():
.define p_restart ! replaces _restart
.define p_save ! replaces save
! These exception and software-interrupt handlers are enabled by the new
! interrupt vector table set up in protect.c:
.define _divide_error ! _int00
.define _single_step_exception ! _int01
.define _nmi ! _int02
.define _breakpoint_exception ! _int03
.define _overflow ! _int04
.define _bounds_check ! _int05
.define _inval_opcode ! _int06
.define _copr_not_available ! _int07
.define _double_fault ! (286 trap)
.define _copr_seg_overrun ! (etc)
.define _inval_tss
.define _segment_not_present
.define _stack_exception
.define _general_protection
.define _p_s_call ! _s_call
.define _level0_call
! The hardware interrupt handlers need not be altered apart from putting
! them in the new table (save() handles the differences).
! Some of the intxx handlers (those for exceptions which do not push an
! error code) need not have been replaced, but the names here are better.
#include "protect.h"
/* Selected 286 tss offsets. */
#define TSS2_S_SP0 2
! imported variables
.extern _tss
.extern _level0_func
!*===========================================================================*
!* p_save *
!*===========================================================================*
! Save for 286 protected mode.
! This is much simpler than for 8086 mode, because the stack already points
! into process table, or has already been switched to the kernel stack.
p_save:
cld ! set direction flag to a known value
pusha ! save "general" registers
push ds ! save ds
push es ! save es
mov dx,ss ! ss is kernel data segment
mov ds,dx ! load rest of kernel segments
mov es,dx
mov bp,sp ! prepare to return
incb _k_reenter ! from -1 if not reentering
jnz set_p1_restart ! stack is already kernel stack
mov sp,#k_stktop
push #p_restart ! build return address for interrupt handler
jmp @RETADR-P_STACKBASE(bp)
set_p1_restart:
push #p1_restart
jmp @RETADR-P_STACKBASE(bp)
!*===========================================================================*
!* p_s_call *
!*===========================================================================*
_p_s_call:
cld ! set direction flag to a known value
sub sp,#6*2 ! skip RETADR, ax, cx, dx, bx, st
push bp ! stack already points into process table
push si
push di
push ds
push es
mov dx,ss
mov ds,dx
mov es,dx
incb _k_reenter
mov si,sp ! assumes P_STACKBASE == 0
mov sp,#k_stktop
! end of inline save
sti ! allow SWITCHER to be interrupted
! now set up parameters for C routine sys_call
push bx ! pointer to user message
push ax ! src/dest
push cx ! SEND/RECEIVE/BOTH
call _sys_call ! sys_call(function, src_dest, m_ptr)
! caller is now explicitly in proc_ptr
mov AXREG(si),ax ! sys_call MUST PRESERVE si
cli
! Fall into code to restart proc/task running.
p_restart:
! Flush any held-up interrupts.
! This reenables interrupts, so the current interrupt handler may reenter.
! This does not matter, because the current handler is about to exit and no
! other handlers can reenter since flushing is only done when k_reenter == 0.
cmp _held_head,#0 ! do fast test to usually avoid function call
jz p_over_call_unhold
call _unhold ! this is rare so overhead is acceptable
p_over_call_unhold:
mov si,_proc_ptr
lldt P_LDT_SEL(si) ! enable segment descriptors for task
lea ax,P_STACKTOP(si) ! arrange for next interrupt
mov _tss+TSS2_S_SP0,ax ! to save state in process table
mov sp,si ! assumes P_STACKBASE == 0
p1_restart:
decb _k_reenter
pop es
pop ds
popa
add sp,#2 ! skip return adr
iret ! continue process
!*===========================================================================*
!* exception handlers *
!*===========================================================================*
_divide_error:
push #DIVIDE_VECTOR
jmp p_exception
_single_step_exception:
push #DEBUG_VECTOR
jmp p_exception
_nmi:
push #NMI_VECTOR
jmp p_exception
_breakpoint_exception:
push #BREAKPOINT_VECTOR
jmp p_exception
_overflow:
push #OVERFLOW_VECTOR
jmp p_exception
_bounds_check:
push #BOUNDS_VECTOR
jmp p_exception
_inval_opcode:
push #INVAL_OP_VECTOR
jmp p_exception
_copr_not_available:
push #COPROC_NOT_VECTOR
jmp p_exception
_double_fault:
push #DOUBLE_FAULT_VECTOR
jmp errexception
_copr_seg_overrun:
push #COPROC_SEG_VECTOR
jmp p_exception
_inval_tss:
push #INVAL_TSS_VECTOR
jmp errexception
_segment_not_present:
push #SEG_NOT_VECTOR
jmp errexception
_stack_exception:
push #STACK_FAULT_VECTOR
jmp errexception
_general_protection:
push #PROTECTION_VECTOR
jmp errexception
!*===========================================================================*
!* p_exception *
!*===========================================================================*
! This is called for all exceptions which do not push an error code.
p_exception:
sseg pop ds_ex_number
call p_save
jmp p1_exception
!*===========================================================================*
!* errexception *
!*===========================================================================*
! This is called for all exceptions which push an error code.
errexception:
sseg pop ds_ex_number
sseg pop trap_errno
call p_save
p1_exception: ! Common for all exceptions.
push ds_ex_number
call _exception
add sp,#2
cli
ret
!*===========================================================================*
!* data *
!*===========================================================================*
.data
begdata:
.data2 0x526F ! this must be the first data entry (magic #)
.bss
begbss:
k_stack:
.space K_STACK_BYTES ! kernel stack
k_stktop: ! top of kernel stack
.comm ds_ex_number, 2
.comm trap_errno, 2

View file

@ -19,7 +19,7 @@
* Oct 10, 2004 require BOTH for kernel sys_call() (Jorrit N. Herder)
* (to protect kernel tasks from being blocked)
* Sep 25, 2004 generalized notify() function (Jorrit N. Herder)
* Sep 23, 2004 removed MM sig check in mini_rec() (Jorrit N. Herder)
* Sep 23, 2004 removed PM sig check in mini_rec() (Jorrit N. Herder)
* Aug 19, 2004 generalized ready()/unready() (Jorrit N. Herder)
* Aug 18, 2004 added notify() function (Jorrit N. Herder)
* May 01, 2004 check p_sendmask in mini_send() (Jorrit N. Herder)
@ -163,7 +163,7 @@ message *m_ptr; /* pointer to message in the caller's space */
/* Calls directed to the kernel may only be sendrec(), because tasks always
* reply and may not block if the caller doesn't do receive(). Users also
* may only use sendrec() to protect the MM and FS.
* may only use sendrec() to protect the process manager and file system.
*/
if ((iskernel(src_dst) || isuserp(caller_ptr)) && function != BOTH) {
result = ECALLDENIED; /* BOTH was required */

View file

@ -14,6 +14,7 @@
* May 01, 2004 new p_sendmask to protect syscalls (Jorrit N. Herder)
*/
#include <minix/com.h>
#include "protect.h"
#include "const.h"
struct proc {
@ -21,8 +22,7 @@ struct proc {
#if (CHIP == INTEL)
reg_t p_ldt_sel; /* selector in gdt giving ldt base and limit*/
struct segdesc_s p_ldt[4]; /* local descriptors for code and data */
/* 4 is LDT_SIZE - avoid include protect.h */
struct segdesc_s p_ldt[2+NR_REMOTE_SEGS]; /* CS, DS and remote segments */
#endif /* (CHIP == INTEL) */
#if (CHIP == M68000)
@ -123,7 +123,7 @@ struct proc {
#define isalivep(p) ((p)->p_type > P_NONE)
#define isrxhardware(n) ((n) == ANY || (n) == HARDWARE)
#define iskernel(n) ((n) == CLOCK || (n) == SYSTASK)
#define issysentn(n) ((n) == FS_PROC_NR || (n) == MM_PROC_NR)
#define issysentn(n) ((n) == FS_PROC_NR || (n) == PM_PROC_NR)
#define issysentp(p) (issysentn((p)->p_nr))
#define isreservedp(p) ((p)->p_type == P_RESERVED)
#define isemptyp(p) ((p)->p_type == P_NONE)

View file

@ -82,10 +82,6 @@ PUBLIC void prot_init()
/* Set up tables for protected mode.
* All GDT slots are allocated at compile time.
*/
extern int etext, end;
#define code_bytes ((vir_bytes) &etext) /* Size of code segment. */
#define data_bytes ((vir_bytes) &end) /* Size of data segment. */
struct gate_table_s *gtp;
struct desctableptr_s *dtp;
unsigned ldt_index;
@ -149,8 +145,8 @@ PUBLIC void prot_init()
* (u32_t *) dtp->base = vir2phys(idt);
/* Build segment descriptors for tasks and interrupt handlers. */
init_codeseg(&gdt[CS_INDEX], code_base, code_bytes, INTR_PRIVILEGE);
init_dataseg(&gdt[DS_INDEX], data_base, data_bytes, INTR_PRIVILEGE);
init_codeseg(&gdt[CS_INDEX], kinfo.code_base, kinfo.code_size, INTR_PRIVILEGE);
init_dataseg(&gdt[DS_INDEX], kinfo.data_base, kinfo.data_size, INTR_PRIVILEGE);
init_dataseg(&gdt[ES_INDEX], 0L, 0, TASK_PRIVILEGE);
/* Build scratch descriptors for functions in klib88. */
@ -268,7 +264,7 @@ U16_t seg;
phys_bytes base;
struct segdesc_s *segdp;
if (!protected_mode) {
if (! machine.protected) {
base = hclick_to_physb(seg);
} else {
segdp = &gdt[seg >> 3];
@ -292,7 +288,7 @@ phys_bytes phys;
* address, for use by a driver doing memory I/O in the A0000 - DFFFF range.
*/
#if _WORD_SIZE == 2
if (!protected_mode) {
if (! machine.protected) {
*seg = phys / HCLICK_SIZE;
*off = phys % HCLICK_SIZE;
} else {
@ -342,3 +338,51 @@ struct proc *pp;
*/
pp->p_reg.psw |= 0x3000;
}
/*==========================================================================*
* alloc_segments *
*==========================================================================*/
PUBLIC void alloc_segments(rp)
register struct proc *rp;
{
/* This is called at system initialization from main() and by do_newmap().
* The code has a separate function because of all hardware-dependencies.
* Note that IDLE is part of the kernel and gets TASK_PRIVILEGE here.
*/
phys_bytes code_bytes;
phys_bytes data_bytes;
int privilege;
if (machine.protected) {
data_bytes = (phys_bytes) (rp->p_memmap[S].mem_vir +
rp->p_memmap[S].mem_len) << CLICK_SHIFT;
if (rp->p_memmap[T].mem_len == 0)
code_bytes = data_bytes; /* common I&D, poor protect */
else
code_bytes = (phys_bytes) rp->p_memmap[T].mem_len << CLICK_SHIFT;
privilege = (isidlep(rp) || istaskp(rp)) ?
TASK_PRIVILEGE : USER_PRIVILEGE;
init_codeseg(&rp->p_ldt[CS_LDT_INDEX],
(phys_bytes) rp->p_memmap[T].mem_phys << CLICK_SHIFT,
code_bytes, privilege);
init_dataseg(&rp->p_ldt[DS_LDT_INDEX],
(phys_bytes) rp->p_memmap[D].mem_phys << CLICK_SHIFT,
data_bytes, privilege);
rp->p_reg.cs = (CS_LDT_INDEX * DESC_SIZE) | TI | privilege;
#if _WORD_SIZE == 4
rp->p_reg.gs =
rp->p_reg.fs =
#endif
rp->p_reg.ss =
rp->p_reg.es =
rp->p_reg.ds = (DS_LDT_INDEX*DESC_SIZE) | TI | privilege;
} else {
rp->p_reg.cs = click_to_hclick(rp->p_memmap[T].mem_phys);
rp->p_reg.ss =
rp->p_reg.es =
rp->p_reg.ds = click_to_hclick(rp->p_memmap[D].mem_phys);
}
}

View file

@ -4,7 +4,7 @@
#define GDT_SIZE (FIRST_LDT_INDEX + NR_TASKS + NR_PROCS)
/* spec. and LDT's */
#define IDT_SIZE (IRQ8_VECTOR + 8) /* only up to the highest vector */
#define LDT_SIZE 4 /* contains CS, DS and two extras */
#define LDT_SIZE (2 + NR_REMOTE_SEGS) /* CS, DS and remote segments */
/* Fixed global descriptors. 1 to 7 are prescribed by the BIOS. */
#define GDT_INDEX 1 /* GDT descriptor */

View file

@ -46,10 +46,6 @@ _PROTOTYPE( void prepare_shutdown, (int how) );
_PROTOTYPE( void stop_sequence, (struct timer *tp) );
_PROTOTYPE( void shutdown, (struct timer *tp) );
/* memory.c */
_PROTOTYPE( void mem_init, (void) );
_PROTOTYPE( void alloc_segments, (struct proc *rp) );
/* misc.c */
_PROTOTYPE( void panic, (_CONST char *s, int n) );
@ -145,6 +141,7 @@ _PROTOTYPE( void phys_outsw, (Port_t port, phys_bytes buf, size_t count));
_PROTOTYPE( void reset, (void) );
_PROTOTYPE( void level0, (void (*func)(void)) );
_PROTOTYPE( void monitor, (void) );
_PROTOTYPE( void read_tsc, (unsigned long *low, unsigned long *high) );
/* mpx*.s */
_PROTOTYPE( void idle_task, (void) );
@ -202,6 +199,7 @@ _PROTOTYPE( void init_dataseg, (struct segdesc_s *segdp, phys_bytes base,
_PROTOTYPE( phys_bytes seg2phys, (U16_t seg) );
_PROTOTYPE( void phys2seg, (u16_t *seg, vir_bytes *off, phys_bytes phys));
_PROTOTYPE( void enable_iop, (struct proc *pp) );
_PROTOTYPE( void alloc_segments, (struct proc *rp) );
#endif /* (CHIP == INTEL) */

View file

@ -88,7 +88,7 @@
allow_all_mask \
deny(1, USER_PROC_NR)
#define MM_SENDMASK \
#define PM_SENDMASK \
deny_all_mask \
allow(1, IS_PROC_NR) /* output diagnostics */ \
allow(1, SYSTASK) \
@ -120,7 +120,7 @@
allow((NR_CTRLRS >= 3), CTRLR(2)) \
allow((NR_CTRLRS >= 4), CTRLR(3)) \
allow(1, INIT_PROC_NR) \
allow(1, MM_PROC_NR) /* cooperates with memory manager */ \
allow(1, PM_PROC_NR) /* cooperates with process manager */ \
allow(1, USER_PROC_NR) /* reply to system calls */
#endif
@ -154,12 +154,12 @@
#define INIT_SENDMASK \
deny_all_mask \
allow(1, FS_PROC_NR) /* init makes system calls to FS and MM */ \
allow(1, MM_PROC_NR)
allow(1, PM_PROC_NR)
#define USER_PROC_SENDMASK \
deny_all_mask \
allow(1, FS_PROC_NR) /* users can only make system calls */ \
allow(1, MM_PROC_NR) \
allow(1, PM_PROC_NR) \
allow(1, IS_PROC_NR) \
allow(ENABLE_TASKSERVER, TS_PROC_NR)

View file

@ -11,10 +11,12 @@
#include "kernel.h"
#include "protect.h"
#include "proc.h"
/* Environment strings passed by loader. */
PRIVATE char k_environ[128*sizeof(char *)];
FORWARD _PROTOTYPE( void mem_init, (void) );
/*==========================================================================*
* cstart *
@ -29,46 +31,127 @@ U16_t parmoff, parmsize; /* boot parameters offset and length */
*/
register char *envp;
unsigned mon_start;
extern int etext, end;
/* Decide if mode is protected; 386 or higher implies protected mode.
* This must be done first, because it is needed for, e.g., seg2phys().
* For 286 machines we cannot decide on protected mode, yet. This is
* done below.
*/
#if _WORD_SIZE != 2
machine.protected = 1;
#endif
/* Record where the kernel and the monitor are. */
code_base = seg2phys(cs);
data_base = seg2phys(ds);
kinfo.code_base = seg2phys(cs);
kinfo.code_size = (phys_bytes) &etext; /* size of code segment */
kinfo.data_base = seg2phys(ds);
kinfo.data_size = (phys_bytes) &end; /* size of data segment */
/* Initialize protected mode descriptors. */
prot_init();
/* Copy the boot parameters to kernel memory. */
mon_params = seg2phys(mds) + parmoff;
mon_parmsize = MAX(parmsize,sizeof(k_environ));
if (parmsize > sizeof k_environ - 2) parmsize = sizeof k_environ - 2;
phys_copy(mon_params, vir2phys(k_environ), (phys_bytes) parmsize);
kinfo.params_base = seg2phys(mds) + parmoff;
kinfo.params_size = MAX(parmsize,sizeof(k_environ)-2);
phys_copy(kinfo.params_base, vir2phys(k_environ), kinfo.params_size);
/* Type of VDU: */
envp = getkenv("video");
if (kstrcmp(envp, "ega") == 0) ega = TRUE;
if (kstrcmp(envp, "vga") == 0) vga = ega = TRUE;
/* Record miscellaneous information for user-space servers. */
kstrncpy(kinfo.version, OS_RELEASE "." OS_VERSION, 6);
kinfo.proc_addr = (vir_bytes) proc;
kinfo.kmem_base = vir2phys(0);
kinfo.kmem_size = (phys_bytes) &end;
/* Processor? */
processor = katoi(getkenv("processor")); /* 86, 186, 286, 386, ... */
machine.processor=katoi(getkenv("processor")); /* 86, 186, 286, 386, ... */
/* Decide if mode is protected for older machines. */
#if _WORD_SIZE == 2
machine.protected = machine.processor >= 286;
#endif
if (! machine.protected) mon_return = 0;
/* XT, AT or MCA bus? */
envp = getkenv("bus");
if (envp == NIL_PTR || kstrcmp(envp, "at") == 0) {
pc_at = TRUE;
} else
if (kstrcmp(envp, "mca") == 0) {
pc_at = ps_mca = TRUE;
machine.pc_at = TRUE; /* PC-AT compatible hardware */
} else if (kstrcmp(envp, "mca") == 0) {
machine.pc_at = machine.ps_mca = TRUE; /* PS/2 with micro channel */
}
/* Decide if mode is protected. */
/* Type of VDU: */
envp = getkenv("video"); /* EGA or VGA video unit */
if (kstrcmp(envp, "ega") == 0) machine.vdu_ega = TRUE;
if (kstrcmp(envp, "vga") == 0) machine.vdu_vga = machine.vdu_ega = TRUE;
/* Initialize free memory list from size passed by boot monitor. */
mem_init();
/* Return to assembler code to switch to protected mode (if 286),
* reload selectors and call main().
*/
}
/* In real mode only 1M can be addressed, and in 16-bit protected we can go
* no further than we can count in clicks. (The 286 is further limited by
* its 24 bit address bus, but we can assume in that case that no more than
* 16M memory is reported by the BIOS.)
*/
#define MAX_REAL 0x00100000L
#define MAX_16BIT (0xFFF0L << CLICK_SHIFT)
/*=========================================================================*
* mem_init *
*=========================================================================*/
PRIVATE void mem_init()
{
/* Initialize the free memory list from the 'memory' boot variable. Translate
* the byte offsets and sizes in this list to clicks, properly truncated. Also
* make sure that we don't exceed the maximum address space of the 286 or the
* 8086, i.e. when running in 16-bit protected mode or real mode.
*/
long base, size, limit;
char *s, *end; /* use to parse boot variable */
int i;
struct memory *memp;
#if _WORD_SIZE == 2
protected_mode = processor >= 286;
if (!protected_mode) mon_return = 0;
unsigned long max_address;
#endif
/* Return to assembler code to switch to protected mode (if 286), reload
* selectors and call main().
/* The available memory is determined by MINIX' boot loader as a list of
* (base:size)-pairs in boothead.s. The 'memory' boot variable is set in
* in boot.s. The format is "b0:s0,b1:s1,b2:s2", where b0:s0 is low mem,
* b1:s1 is mem between 1M and 16M, b2:s2 is mem above 16M. Pairs b1:s1
* and b2:s2 are combined if the memory is adjacent.
*/
s = getkenv("memory"); /* get memory boot variable */
for (i = 0; i < NR_MEMS; i++) {
memp = &mem[i]; /* result is stored here */
base = size = 0;
if (*s != 0) { /* end of boot variable */
/* Expect base to be read (end != s) and ':' as next char. */
base = kstrtoul(s, &end, 0x10); /* get number */
if (end != s && *end == ':') s = ++end; /* skip ':' */
else *s=0; /* fake end for next; should not happen */
/* Expect size to be read and skip ',', unless at end. */
size = kstrtoul(s, &end, 0x10); /* get number */
if (end != s && *end == ',') s = ++end; /* skip ',' */
else if (end != s && *end == 0) s = end; /* end found */
else *s=0; /* fake end for next; should not happen */
}
limit = base + size;
#if _WORD_SIZE == 2
max_address = kinfo.protected ? MAX_16BIT : MAX_REAL;
if (limit > max_address) limit = max_address;
#endif
base = (base + CLICK_SIZE-1) & ~(long)(CLICK_SIZE-1);
limit &= ~(long)(CLICK_SIZE-1);
if (limit <= base) continue;
memp->base = base >> CLICK_SHIFT;
memp->size = (limit - base) >> CLICK_SHIFT;
}
}

View file

@ -18,16 +18,16 @@
* umap_bios: map virtual address in BIOS_SEG to physical
* numap_local: umap_local D segment from proc nr instead of pointer
* virtual_copy: copy bytes from one virtual address to another
* vir_copy: copy bytes from one process to another
* generic_handler: interrupt handler for user-level device drivers
*
* Changes:
* Apr 25, 2005 made mapping of call vector explicit (Jorrit N. Herder)
* Oct 29, 2004 new clear_proc() function (Jorrit N. Herder)
* Oct 17, 2004 generic handler and IRQ policies (Jorrit N. Herder)
* Oct 10, 2004 dispatch system calls from call vector (Jorrit N. Herder)
* Sep 30, 2004 source code documentation updated (Jorrit N. Herder)
* Sep 10, 2004 system call functions in library (Jorrit N. Herder)
* 2003/2004 various new syscalls (see syslib.h) (Jorrit N. Herder)
* 2004 to 2005 various new syscalls (see syslib.h) (Jorrit N. Herder)
*/
#include "kernel.h"
@ -40,59 +40,24 @@
#include <minix/callnr.h>
#include "sendmask.h"
#if (CHIP == INTEL)
#include <ibm/memory.h>
#include "protect.h"
#endif
/* Declaration of the call vector that defines the mapping of system calls
* to handler functions. The vector is initialized in sys_init() with map(),
* which makes sure the system call numbers are ok. No space is allocated,
* because the dummy is declared extern. If an illegal call is given, the
* array size will be negative and this won't compile.
*/
PUBLIC int (*call_vec[NR_SYS_CALLS])(message *m_ptr);
#define map(call_nr, handler) \
{extern int dummy[NR_SYS_CALLS > (unsigned) (call_nr) ? 1 : -1];} \
call_vec[(call_nr)] = (handler)
FORWARD _PROTOTYPE( void initialize, (void));
/* Declaration of the call vector that defines the mapping of system calls to
* handler functions. The order of the do_call handler functions must match
* the SYS_CALL numbering defined in <minix/com.h>.
*/
PUBLIC _PROTOTYPE (int (*call_vec[]), (message *m_ptr) ) = {
do_times, /* 0: get uptime and process CPU time consumption */
do_xit, /* 1: informs kernel that a process has exited */
do_unused, /* 2: unused */
do_sigctl, /* 3: MM signal control (incl. POSIX style handling) */
do_fork, /* 4: informs kernel that a process has forked */
do_newmap, /* 5: allows MM to set up a process memory map */
do_copy, /* 6: copy a block of data between processes */
do_exec, /* 7: sets program counter and stack pointer after EXEC */
do_unused, /* 8: unused */
do_abort, /* 9: MM or FS cannot go on; abort MINIX */
do_kill, /* 10: cause a signal to be sent via MM */
do_umap, /* 11: compute the physical address for a virtual address */
do_unused, /* 12: returns the next free chunk of physical memory */
do_trace, /* 13: request a trace operation */
do_vcopy, /* 14: request a series of data blocks to be copied */
do_signalrm, /* 15: schedule an alarm that causes an alarm signal */
do_syncalrm, /* 16: schedule an alarm that sends a notification message */
do_flagalrm, /* 17: schedule an alarm that sets a timeout flag to 1 */
do_unused, /* 18: unused */
do_svrctl, /* 19: handles miscelleneous kernel control functions */
do_sdevio, /* 20: device I/O: phys_insb, _insw, _outsb, _outsw */
do_unused, /* 21: unused */
do_getinfo, /* 22: request some kind of system information */
do_devio, /* 23: device I/O: inb, inw, inl, outb, outw, outl */
do_vdevio, /* 24: device I/O: vector with in[b|w|l], out[b|w|l] */
do_irqctl, /* 25: request an interrupt control operation */
do_kmalloc, /* 26: request allocation of (DMA) buffer in mem chunk */
do_iopenable, /* 27: allow a user process to use I/O instructions */
do_phys2seg, /* 28: do a phys addr to segment selector/ offset conversion */
do_exit, /* 29: an server or driver requests to be aborted */
do_vircopy, /* 30: copy from process to process (virtual addressing) */
do_physcopy, /* 31: copy from anywhere to anywhere (physical addressing) */
};
/* Check if system call table is correct. This should not fail. No space is
* allocated here, because the dummy is declared extern. If the call vector
* is unbalanced, the array size will be negative and this won't compile.
*/
extern int dummy[sizeof(call_vec)==NR_SYS_CALLS*sizeof(call_vec[0]) ? 1 : -1];
/* Some system task variables. */
PRIVATE message m; /* used to receive requests */
/*===========================================================================*
* sys_task *
@ -100,7 +65,7 @@ PRIVATE message m; /* used to receive requests */
PUBLIC void sys_task()
{
/* Main entry point of sys_task. Get the message and dispatch on type. */
static message m;
register int result;
/* Initialize the system task. */
@ -145,6 +110,59 @@ PRIVATE void initialize(void)
tmr_inittimer(&(rp->p_syncalrm));
tmr_inittimer(&(rp->p_flagalrm));
}
/* Initialize the call vector to a safe default handler. Some system calls
* may be disabled or nonexistant. Then explicitely map known calls to their
* handler functions. This is done with a macro that gives a compile error
* if an illegal call number is used. The ordering is not important here.
*/
for (i=0; i<NR_SYS_CALLS; i++) {
call_vec[i] = do_unused;
}
/* Process management. */
map(SYS_FORK, do_fork); /* informs kernel that a process has forked */
map(SYS_XIT, do_xit); /* informs kernel that a process has exited */
map(SYS_NEWMAP, do_newmap); /* allows PM to set up a process memory map */
map(SYS_EXEC, do_exec); /* sets program counter and stack pointer after EXEC */
map(SYS_TRACE, do_trace); /* request a trace operation */
/* Signal handling. */
map(SYS_KILL, do_kill); /* cause a process to be signaled */
map(SYS_GETSIG, do_getsig); /* PM checks for pending signals */
map(SYS_ENDSIG, do_endsig); /* PM finished processing signal */
map(SYS_SIGSEND, do_sigsend); /* start POSIX-style signal */
map(SYS_SIGRETURN, do_sigreturn); /* return from POSIX-style signal */
/* Clock functionality. */
map(SYS_TIMES, do_times); /* get uptime and process times */
map(SYS_SIGNALRM, do_signalrm); /* causes an alarm signal */
map(SYS_SYNCALRM, do_syncalrm); /* send a notification message */
map(SYS_FLAGALRM, do_flagalrm); /* set a timeout flag to 1 */
/* Device I/O. */
map(SYS_IRQCTL, do_irqctl); /* interrupt control operations */
map(SYS_DEVIO, do_devio); /* inb, inw, inl, outb, outw, outl */
map(SYS_SDEVIO, do_sdevio); /* phys_insb, _insw, _outsb, _outsw */
map(SYS_VDEVIO, do_vdevio); /* vector with devio requests */
/* Server and driver control. */
map(SYS_KMALLOC, do_kmalloc); /* request chunk of free memory */
map(SYS_SEGCTL, do_segctl); /* add segment and get selector */
map(SYS_IOPENABLE, do_iopenable); /* enable CPU I/O protection bits */
map(SYS_SVRCTL, do_svrctl); /* kernel control functions */
map(SYS_EXIT, do_exit); /* exit a system process*/
/* Copying. */
map(SYS_UMAP, do_umap); /* map virtual to physical address */
map(SYS_VIRCOPY, do_vircopy); /* use virtual addressing */
map(SYS_PHYSCOPY, do_physcopy); /* use physical addressing */
map(SYS_VIRVCOPY, do_virvcopy); /* vector with copy requests */
/* Miscellaneous. */
map(SYS_ABORT, do_abort); /* abort MINIX */
map(SYS_GETINFO, do_getinfo); /* request system information */
map(SYS_RANDOM, do_random); /* request kernel random data */
}
/*===========================================================================*
@ -216,6 +234,14 @@ int proc_nr; /* slot of process to clean up */
PUBLIC int generic_handler(hook)
irq_hook_t *hook;
{
/* This function handles hardware interrupt in a simpel and generic way. All
* interrupts are transformed into messages to a driver. The IRQ line will be
* reenabled if the policy says so.
*/
irq_policy_t policy = irqtab[hook->irq].policy;
int proc_nr = irqtab[hook->irq].proc_nr;
#if DEAD_CODE
/* This function handles hardware interrupt in a generic way, according to
* the policy set with SYS_IRQCTL. This is rather complicated since different
* devices require different actions. Options are (1) do nothing, (2a) read a
@ -223,8 +249,6 @@ irq_hook_t *hook;
* read, or (3) write a value to a port. Finally, the policy may or may not
* reenable IRQs. A notification is sent in all cases.
*/
irq_policy_t policy = irqtab[hook->irq].policy;
int proc_nr = irqtab[hook->irq].proc_nr;
long port = irqtab[hook->irq].port;
phys_bytes addr = irqtab[hook->irq].addr;
long mask_val = irqtab[hook->irq].mask_val;
@ -270,6 +294,7 @@ irq_hook_t *hook;
default: /* do nothing */ ; /* wrong type flags */
}
}
#endif /* DEAD_CODE */
/* Almost done, send a HARD_INT notification to allow further processing
* and possibly reenable interrupts - this depends on the policy given.
@ -290,12 +315,12 @@ int sig_nr; /* signal to be sent, 1 to _NSIG */
* TTY wanting to cause SIGINT upon getting a DEL
* CLOCK wanting to cause SIGALRM when timer expires
* FS also uses this to send a signal, via the SYS_KILL message. Signals are
* handled by sending a message to MM. This central function handles the
* signals and makes sure the MM gets them by sending a notification. The
* process being signaled is blocked while MM has not finished all signals
* handled by sending a message to PM. This central function handles the
* signals and makes sure the PM gets them by sending a notification. The
* process being signaled is blocked while PM has not finished all signals
* for it. These signals are counted in p_pendcount, and the SIG_PENDING
* flag is kept nonzero while there are some. It is not sufficient to ready
* the process when MM is informed, because MM can block waiting for FS to
* the process when PM is informed, because PM can block waiting for FS to
* do a core dump.
*/
register struct proc *rp, *mmp;
@ -309,7 +334,7 @@ int sig_nr; /* signal to be sent, 1 to _NSIG */
return; /* another signal already pending */
if (rp->p_flags == 0) lock_unready(rp);
rp->p_flags |= PENDING | SIG_PENDING;
notify(MM_PROC_NR, KSIG_PENDING);
notify(PM_PROC_NR, KSIG_PENDING);
}
@ -321,12 +346,22 @@ register struct proc *rp; /* pointer to proc table entry for process */
vir_bytes vir_addr; /* virtual address in BIOS segment */
vir_bytes bytes; /* # of bytes to be copied */
{
/* Calculate the physical memory address at the BIOS. */
/* Calculate the physical memory address at the BIOS. Note: currently, BIOS
* address zero (the first BIOS interrupt vector) is not considered, as an
* error here, but since the physical address will be zero as well, the
* calling function will think an error occurred. This is not a problem,
* since no one uses the first BIOS interrupt vector.
*/
phys_bytes phys_addr;
phys_addr = (phys_bytes) vir_addr; /* no check currently! */
/* Check all acceptable ranges. */
if (vir_addr >= BIOS_MEM_BEGIN && vir_addr + bytes <= BIOS_MEM_END)
return (phys_bytes) vir_addr;
else if (vir_addr >= UPPER_MEM_BEGIN && vir_addr + bytes <= UPPER_MEM_END)
return (phys_bytes) vir_addr;
return phys_addr;
kprintf("Warning, error in umap_bios, virtual address 0x%x\n", vir_addr);
return 0;
}
/*===========================================================================*
@ -438,11 +473,16 @@ vir_bytes vir_addr; /* virtual address in bytes within the seg */
vir_bytes bytes; /* # of bytes to be copied */
{
/* Calculate the physical memory address for a given virtual address. */
phys_bytes phys_addr;
struct far_mem *fm;
phys_addr = (phys_bytes) 0; /* no yet supported currently! */
if (bytes <= 0) return( (phys_bytes) 0);
if (seg < 0 || seg >= NR_REMOTE_SEGS) return( (phys_bytes) 0);
return phys_addr;
fm = &rp->p_farmem[seg];
if (! fm->in_use) return( (phys_bytes) 0);
if (vir_addr + bytes > fm->mem_len) return( (phys_bytes) 0);
return(fm->mem_phys + (phys_bytes) vir_addr);
}
/*==========================================================================*
@ -454,7 +494,7 @@ struct vir_addr *dst_addr; /* destination virtual address */
vir_bytes bytes; /* # of bytes to copy */
{
/* Copy bytes from virtual address src_addr to virtual address dst_addr.
* Virtual addresses can be in LOCAL_SEG, REMOTE_SEG, or BIOS_SEG.
* Virtual addresses can be in ABS, LOCAL_SEG, REMOTE_SEG, or BIOS_SEG.
*/
struct vir_addr *vir_addr[2]; /* virtual source and destination address */
phys_bytes phys_addr[2]; /* absolute source and destination */
@ -488,6 +528,9 @@ vir_bytes bytes; /* # of bytes to copy */
phys_addr[i] = umap_bios( proc_addr(vir_addr[i]->proc_nr),
vir_addr[i]->offset, bytes );
break;
case PHYS_SEG:
phys_addr[i] = vir_addr[i]->offset;
break;
default:
kprintf("v_cp: Unknown segment type: %d\n",
vir_addr[i]->segment & SEGMENT_TYPE);
@ -495,7 +538,7 @@ vir_bytes bytes; /* # of bytes to copy */
}
/* Check if mapping succeeded. */
if (phys_addr[i] <= 0) {
if (phys_addr[i] <= 0 && vir_addr[i]->segment != PHYS_SEG) {
kprintf("v_cp: Mapping failed ... phys <= 0\n", NO_ARG);
return(EFAULT);
}

View file

@ -19,22 +19,23 @@ _PROTOTYPE( int do_fork, (message *m_ptr) );
_PROTOTYPE( int do_newmap, (message *m_ptr) );
_PROTOTYPE( int do_xit, (message *m_ptr) );
_PROTOTYPE( int do_vircopy, (message *m_ptr) ); /* copying */
_PROTOTYPE( int do_physcopy, (message *m_ptr) );
_PROTOTYPE( int do_copy, (message *m_ptr) ); /* copying */
#define do_vircopy do_copy
#define do_physcopy do_copy
_PROTOTYPE( int do_vcopy, (message *m_ptr) );
#define do_virvcopy do_vcopy
_PROTOTYPE( int do_umap, (message *m_ptr) );
_PROTOTYPE( int do_vcopy, (message *m_ptr) );
_PROTOTYPE( int do_copy, (message *m_ptr) );
_PROTOTYPE( int do_unused, (message *m_ptr) ); /* miscellaneous */
_PROTOTYPE( int do_abort, (message *m_ptr) );
_PROTOTYPE( int do_times, (message *m_ptr) );
_PROTOTYPE( int do_getinfo, (message *m_ptr) );
_PROTOTYPE( int do_random, (message *m_ptr) );
_PROTOTYPE( int do_exit, (message *m_ptr) ); /* server control */
_PROTOTYPE( int do_svrctl, (message *m_ptr) );
_PROTOTYPE( int do_kmalloc, (message *m_ptr) );
_PROTOTYPE( int do_iopenable, (message *m_ptr) );
_PROTOTYPE( int do_phys2seg, (message *m_ptr) );
_PROTOTYPE( int do_segctl, (message *m_ptr) );
_PROTOTYPE( int do_devio, (message *m_ptr) ); /* device I/O */
_PROTOTYPE( int do_vdevio, (message *m_ptr) );
@ -43,9 +44,13 @@ _PROTOTYPE( int do_sdevio, (message *m_ptr) );
_PROTOTYPE( int do_irqctl, (message *m_ptr) ); /* interrupt control */
_PROTOTYPE( int do_kill, (message *m_ptr) ); /* signal handling */
_PROTOTYPE( int do_sigctl, (message *m_ptr) );
_PROTOTYPE( int do_getsig, (message *m_ptr) );
_PROTOTYPE( int do_endsig, (message *m_ptr) );
_PROTOTYPE( int do_sigsend, (message *m_ptr) );
_PROTOTYPE( int do_sigreturn, (message *m_ptr) );
_PROTOTYPE( int do_setalarm, (message *m_ptr) ); /* alarm functions */
_PROTOTYPE( int do_times, (message *m_ptr) ); /* clock functions */
_PROTOTYPE( int do_setalarm, (message *m_ptr) );
#define do_flagalrm do_setalarm
#define do_signalrm do_setalarm
#define do_syncalrm do_setalarm
@ -57,6 +62,7 @@ _PROTOTYPE( int do_trace, (message *m_ptr) ); /* process tracing */
#endif
#if ENABLE_K_DEBUGGING /* debugging */
#error Kernel debugging routines are not implemented.
#else
#endif

View file

@ -20,8 +20,7 @@ CFLAGS = -I$i
LDFLAGS = -i
SYS = alarms.o copying.o debugging.o devio.o irqctl.o proctl.o \
srvrctl.o misc.o sigctl.o tracing.o \
do_copy.o do_vcopy.o
sysctl.o misc.o sigctl.o tracing.o \
# What to make.
all build: $(SYS)
@ -48,11 +47,8 @@ irqctl.o: $a $b
misc.o: $a $b $i/unistd.h
proctl.o: $a $b $k/sendmask.h $k/protect.h $i/signal.h
sigctl.o: $a $b $i/signal.h $s/sigcontext.h
srvrctl.o: $a $b $s/svrctl.h $k/sendmask.h
sysctl.o: $a $b $s/svrctl.h $k/sendmask.h
tracing.o: $a $b $s/ptrace.h
do_copy.o: $a $b
do_vcopy.o: $a $b

View file

@ -1,5 +1,5 @@
/* The system call implemented in this file:
* m_type: SYS_VIRCOPY
* m_type: SYS_VIRCOPY, SYS_PHYSCOPY
*
* The parameters for this system call are:
* m5_c1: CP_SRC_SPACE
@ -13,14 +13,17 @@
#include "../kernel.h"
#include "../system.h"
#include <minix/type.h>
/*===========================================================================*
* do_vircopy *
* do_copy *
*===========================================================================*/
PUBLIC int do_vircopy(m_ptr)
PUBLIC int do_copy(m_ptr)
register message *m_ptr; /* pointer to request message */
{
/* Handle sys_vircopy(). Copy data by using virtual addressing. */
/* Handle sys_vircopy() and sys_physcopy(). Copy data using virtual or
* physical addressing.
*/
struct vir_addr vir_addr[2]; /* virtual source and destination address */
vir_bytes bytes; /* number of bytes to copy */
int i;
@ -41,21 +44,18 @@ register message *m_ptr; /* pointer to request message */
/* Check if process number was given implictly with SELF and is valid. */
if (vir_addr[i].proc_nr == SELF) vir_addr[i].proc_nr = m_ptr->m_source;
if (! isokprocn(vir_addr[i].proc_nr)) {
kprintf("do_vircopy: illegal proc nr\n",NO_ARG);
if (! isokprocn(vir_addr[i].proc_nr) && vir_addr[i].segment != PHYS_SEG) {
kprintf("do_vircopy: illegal proc nr, while not phys addr\n",NO_ARG);
return(EINVAL);
}
/* Copying from or to special segments can only done by the owner. */
if ((vir_addr[i].segment & SEGMENT_TYPE) != LOCAL_SEG &&
vir_addr[i].proc_nr != m_ptr->m_source) {
kprintf("do_vircopy: special seg permission denied\n", NO_ARG);
return(EPERM);
}
/* Check if physical addressing is used without SYS_PHYSCOPY. */
if ((vir_addr[i].segment & SEGMENT_TYPE) == PHYS_SEG &&
m_ptr->m_type != SYS_PHYSCOPY) return(EPERM);
}
/* Check for overflow. This would happen for 64K segments and 16-bit
* vir_bytes. Especially copying by the MM on do_fork() is affected.
* vir_bytes. Especially copying by the PM on do_fork() is affected.
*/
if (bytes != (vir_bytes) bytes) {
kprintf("do_vircopy: overflow\n", NO_ARG);
@ -67,37 +67,44 @@ register message *m_ptr; /* pointer to request message */
}
/* The system call implemented in this file:
* m_type: SYS_PHYSCOPY
*
* The parameters for this system call are:
* m5_l1: CP_SRC_ADDR (physical source address)
* m5_l2: CP_DST_ADDR (physical destination address)
* m5_l3: CP_NR_BYTES (number of bytes to copy)
*
* Author:
* Jorrit N. Herder <jnherder@cs.vu.nl>
*/
/* Buffer to hold copy request vector from user. */
PRIVATE struct vir_cp_req vir_cp_req[VCOPY_VEC_SIZE];
/*===========================================================================*
* do_physcopy *
* do_vcopy *
*===========================================================================*/
PUBLIC int do_physcopy(m_ptr)
PUBLIC int do_vcopy(m_ptr)
register message *m_ptr; /* pointer to request message */
{
/* Handle sys_physcopy(). Copy data by using physical addressing. */
/* Handle sys_virvcopy(). Handle virtual copy requests from vector. */
int nr_req;
int caller_pid;
vir_bytes caller_vir;
phys_bytes caller_phys;
phys_bytes kernel_phys;
phys_bytes bytes;
int i,s;
phys_bytes src_phys, dst_phys, bytes;
/* Check if request vector size is ok. */
nr_req = (unsigned) m_ptr->VCP_VEC_SIZE;
if (nr_req > VCOPY_VEC_SIZE) return(EINVAL);
bytes = nr_req * sizeof(struct vir_cp_req);
/* Dismember the command message. */
src_phys = (phys_bytes) m_ptr->CP_SRC_ADDR;
dst_phys = (phys_bytes) m_ptr->CP_DST_ADDR;
bytes = (phys_bytes) m_ptr->CP_NR_BYTES;
/* Calculate physical addresses and copy (port,value)-pairs from user. */
caller_pid = (int) m_ptr->m_source;
caller_vir = (vir_bytes) m_ptr->VCP_VEC_ADDR;
caller_phys = umap_local(proc_addr(caller_pid), D, caller_vir, bytes);
if (0 == caller_phys) return(EFAULT);
kernel_phys = vir2phys(vir_cp_req);
phys_copy(caller_phys, kernel_phys, (phys_bytes) bytes);
/* Do some checks and copy the data. */
if (src_phys == 0 || dst_phys == 0) return(EFAULT);
phys_copy(src_phys, dst_phys, bytes);
return(OK);
/* Assume vector with requests is correct. Try to copy everything. */
for (i=0; i<nr_req; i++) {
s = virtual_copy(&vir_cp_req[i].src, &vir_cp_req[i].dst,
vir_cp_req[i].count);
if (s != OK) break;
}
return(s);
}

View file

@ -1,69 +0,0 @@
/* The system call implemented in this file:
* m_type: SYS_COPY
*
* The parameters for this system call are:
* m5_c1: CP_SRC_SPACE
* m5_i1: CP_SRC_PROC_NR
* m5_l1: CP_SRC_ADDR
* m5_c2: CP_DST_SPACE
* m5_i2: CP_DST_PROC_NR
* m5_l2: CP_DST_ADDR
* m5_l3: CP_NR_BYTES
*/
#include "../kernel.h"
#include "../system.h"
/*===========================================================================*
* do_copy *
*===========================================================================*/
PUBLIC int do_copy(m_ptr)
register message *m_ptr; /* pointer to request message */
{
/* Handle sys_copy(). Copy data by using virtual or physical addressing. */
int src_proc, dst_proc, src_space, dst_space;
vir_bytes src_vir, dst_vir;
phys_bytes src_phys, dst_phys, bytes;
/* Dismember the command message. */
src_proc = m_ptr->CP_SRC_PROC_NR;
dst_proc = m_ptr->CP_DST_PROC_NR;
src_space = m_ptr->CP_SRC_SPACE;
dst_space = m_ptr->CP_DST_SPACE;
src_vir = (vir_bytes) m_ptr->CP_SRC_ADDR;
dst_vir = (vir_bytes) m_ptr->CP_DST_ADDR;
bytes = (phys_bytes) m_ptr->CP_NR_BYTES;
/* Check if process number was given implicitly with SELF. */
if (src_proc == SELF) src_proc = m_ptr->m_source;
if (dst_proc == SELF) dst_proc = m_ptr->m_source;
/* Compute the source and destination addresses and do the copy. */
if (src_proc == ABS) {
src_phys = (phys_bytes) m_ptr->CP_SRC_ADDR;
} else {
if (bytes != (vir_bytes) bytes) {
/* This would happen for 64K segments and 16-bit vir_bytes.
* It would happen a lot for do_fork except MM uses ABS
* copies for that case.
*/
panic("overflow in count in do_copy", NO_NUM);
}
src_phys = umap_local(proc_addr(src_proc), src_space, src_vir,
(vir_bytes) bytes);
}
if (dst_proc == ABS) {
dst_phys = (phys_bytes) m_ptr->CP_DST_ADDR;
} else {
dst_phys = umap_local(proc_addr(dst_proc), dst_space, dst_vir,
(vir_bytes) bytes);
}
if (src_phys == 0 || dst_phys == 0) return(EFAULT);
phys_copy(src_phys, dst_phys, bytes);
return(OK);
}

View file

@ -1,55 +0,0 @@
/* The system call implemented in this file:
* m_type: SYS_VCOPY
*
* The parameters for this system call are:
* m1_i1: VCP_SRC_PROC (source process number)
* m1_i2: VCP_DST_PROC (destination process number)
* m1_i3: VCP_VEC_SIZE (vector size)
* m1_p1: VCP_VEC_ADDR (pointer to vector)
*
* Author:
* Jorrit N. Herder <jnherder@cs.vu.nl>
*/
#include "../kernel.h"
#include "../system.h"
/*===========================================================================*
* do_vcopy *
*===========================================================================*/
PUBLIC int do_vcopy(m_ptr)
register message *m_ptr; /* pointer to request message */
{
/* Handle sys_vcopy(). Copy multiple blocks of memory */
int src_proc, dst_proc, vect_s, i;
vir_bytes src_vir, dst_vir, vect_addr;
phys_bytes src_phys, dst_phys, bytes;
cpvec_t cpvec_table[CPVEC_NR];
/* Dismember the command message. */
src_proc = m_ptr->VCP_SRC_PROC;
dst_proc = m_ptr->VCP_DST_PROC;
vect_s = m_ptr->VCP_VEC_SIZE;
vect_addr = (vir_bytes)m_ptr->VCP_VEC_ADDR;
if (vect_s > CPVEC_NR) return EDOM;
src_phys= numap_local(m_ptr->m_source, vect_addr, vect_s * sizeof(cpvec_t));
if (!src_phys) return EFAULT;
phys_copy(src_phys, vir2phys(cpvec_table),
(phys_bytes) (vect_s * sizeof(cpvec_t)));
for (i = 0; i < vect_s; i++) {
src_vir= cpvec_table[i].cpv_src;
dst_vir= cpvec_table[i].cpv_dst;
bytes= cpvec_table[i].cpv_size;
src_phys = numap_local(src_proc,src_vir,(vir_bytes)bytes);
dst_phys = numap_local(dst_proc,dst_vir,(vir_bytes)bytes);
if (src_phys == 0 || dst_phys == 0) return(EFAULT);
phys_copy(src_phys, dst_phys, bytes);
}
return(OK);
}

View file

@ -27,11 +27,13 @@ register message *m_ptr; /* pointer to request message */
/* Dismember the request message. */
int irq = m_ptr->IRQ_VECTOR; /* which IRQ vector */
int policy = m_ptr->IRQ_POLICY; /* policy field with flags */
int proc_nr = m_ptr->IRQ_PROC_NR; /* process number to forward to */
#if DEAD_CODE
long port = m_ptr->IRQ_PORT; /* port to read or write */
vir_bytes vir_addr = m_ptr->IRQ_VIR_ADDR; /* address at caller */
phys_bytes phys_addr = 0; /* calculate physical address */
long mask_val = m_ptr->IRQ_MASK_VAL; /* mask or value to be written */
int proc_nr = m_ptr->IRQ_PROC_NR; /* process number to forward to */
#endif
/* Check if IRQ line is acceptable. */
if ((unsigned) irq >= NR_IRQ_VECTORS) {
@ -76,6 +78,7 @@ register message *m_ptr; /* pointer to request message */
kprintf("ST: notify: invalid proc_nr: %d\n", proc_nr);
return(EINVAL);
}
#if DEAD_CODE
if (policy & IRQ_READ_PORT) { /* get phys_addr at caller */
switch(policy & (IRQ_BYTE|IRQ_WORD|IRQ_LONG)) {
case IRQ_BYTE: phys_addr=numap_local(proc_nr,vir_addr,sizeof( u8_t));
@ -88,12 +91,15 @@ register message *m_ptr; /* pointer to request message */
}
if (phys_addr==0) return(EFAULT); /* invalid address */
}
#endif
/* Arguments seem to be OK, register them in the IRQ table. */
irqtab[irq].policy = policy; /* policy for interrupts */
irqtab[irq].proc_nr = proc_nr; /* process number to notify */
#if DEAD_CODE
irqtab[irq].port = port; /* port to read or write */
irqtab[irq].addr = phys_addr; /* address to store status */
irqtab[irq].mask_val = mask_val; /* strobe mask or value */
#endif
put_irq_handler(&irqtab[irq].hook, irq, generic_handler);
}
break;

View file

@ -54,6 +54,16 @@ message *m; /* pointer to request message */
}
/*===========================================================================*
* do_random *
*===========================================================================*/
PUBLIC int do_random(m)
message *m; /* pointer to request message */
{
return(ENOSYS); /* no yet implemented */
}
/* The system call implemented in this file:
* m_type: SYS_ABORT
*
@ -71,7 +81,7 @@ PUBLIC int do_abort(m_ptr)
message *m_ptr; /* pointer to request message */
{
/* Handle sys_abort. MINIX is unable to continue. This can originate in the
* MM (normal abort or panic) or FS (panic), or TTY (a CTRL-ALT-DEL or ESC
* PM (normal abort or panic) or FS (panic), or TTY (a CTRL-ALT-DEL or ESC
* after debugging dumps).
*/
register struct proc *rp;
@ -84,11 +94,11 @@ message *m_ptr; /* pointer to request message */
if (how == RBT_MONITOR) {
/* The monitor is to run user specified instructions. */
len = m_ptr->ABRT_MON_LEN + 1;
assert(len <= mon_parmsize);
assert(len <= kinfo.params_size);
src_phys = numap_local(m_ptr->ABRT_MON_PROC,
(vir_bytes) m_ptr->ABRT_MON_ADDR, len);
assert(src_phys != 0);
phys_copy(src_phys, mon_params, (phys_bytes) len);
phys_copy(src_phys, kinfo.params_base, (phys_bytes) len);
}
prepare_shutdown(how);
return(OK); /* pro-forma (really EDISASTER) */
@ -125,23 +135,14 @@ register message *m_ptr; /* pointer to request message */
/* Set source address and length based on request type. */
switch (m_ptr->I_REQUEST) {
case GET_KENVIRON: {
struct kenviron kenv;
extern int end;
kenv.pc_at = pc_at; kenv.ps_mca = ps_mca;
kenv.processor = processor; kenv.protected = protected_mode;
kenv.ega = ega; kenv.vga = vga;
kenv.proc_addr = (vir_bytes) proc;
kenv.params_base = mon_params;
kenv.params_size = mon_parmsize;
kenv.kmem_base = vir2phys(0);
kenv.kmem_size = vir2phys(&end) - vir2phys(0) + 1;
kenv.bootfs_base = proc_addr(MEMORY)->p_farmem[0].mem_phys;
kenv.bootfs_size = proc_addr(MEMORY)->p_farmem[0].mem_len;
length = sizeof(struct kenviron);
src_phys = vir2phys(&kenv);
case GET_MACHINE: {
length = sizeof(struct machine);
src_phys = vir2phys(&machine);
break;
}
case GET_KINFO: {
length = sizeof(struct kinfo);
src_phys = vir2phys(&kinfo);
break;
}
case GET_IMAGE: {
@ -184,20 +185,26 @@ register message *m_ptr; /* pointer to request message */
break;
}
case GET_MONPARAMS: {
src_phys = mon_params; /* already is a physical address! */
length = mon_parmsize;
src_phys = kinfo.params_base; /* already is a physical address! */
length = kinfo.params_size;
break;
}
case GET_PROCNR: {
length = sizeof(int);
if (m_ptr->I_KEY_LEN == 0) { /* get own process nr */
#if DEAD_CODE
/* GET_PROCNR functionality will be moved to the Process Manager! */
kprintf("GET_PROCNR (own) from %d\n", m_ptr->m_source);
#endif
src_phys = vir2phys(&proc_nr);
length = sizeof(int);
} else { /* lookup nr by name */
int proc_found = FALSE;
struct proc *pp;
char key[8]; /* storage for process name to lookup */
kprintf("GET_PROCNR (others) from %d\n", m_ptr->m_source);
#if DEAD_CODE
/* GET_PROCNR functionality will be moved to the Process Manager! */
kprintf("GET_PROCNR (by name) from %d\n", m_ptr->m_source);
#endif
proc_nr = m_ptr->m_source; /* only caller can request copy */
if (m_ptr->I_KEY_LEN > sizeof(key)) return(EINVAL);
if (vir_copy(proc_nr, (vir_bytes) m_ptr->I_KEY_PTR, SYSTASK,
@ -205,6 +212,7 @@ register message *m_ptr; /* pointer to request message */
for (pp=BEG_PROC_ADDR; pp<END_PROC_ADDR; pp++) {
if (kstrncmp(pp->p_name, key, m_ptr->I_KEY_LEN) == 0) {
src_phys = vir2phys(&(pp->p_nr));
length = sizeof(int);
proc_found = TRUE;
break;
}

View file

@ -4,7 +4,7 @@
* The parameters for this system call are:
* m1_i1: PR_PROC_NR (child's process table slot)
* m1_i2: PR_PPROC_NR (parent, process that forked)
* m1_i3: PR_PID (child pid received from MM)
* m1_i3: PR_PID (child pid received from PM)
*/
#include "../kernel.h"
@ -81,23 +81,23 @@ register message *m_ptr; /* pointer to request message */
PUBLIC int do_newmap(m_ptr)
message *m_ptr; /* pointer to request message */
{
/* Handle sys_newmap(). Fetch the memory map from MM. */
/* Handle sys_newmap(). Fetch the memory map from PM. */
register struct proc *rp;
phys_bytes src_phys;
int caller; /* whose space has the new map (usually MM) */
int caller; /* whose space has the new map (usually PM) */
int k; /* process whose map is to be loaded */
int old_flags; /* value of flags before modification */
struct mem_map *map_ptr; /* virtual address of map inside caller (MM) */
struct mem_map *map_ptr; /* virtual address of map inside caller (PM) */
/* Extract message parameters and copy new memory map from MM. */
/* Extract message parameters and copy new memory map from PM. */
caller = m_ptr->m_source;
k = m_ptr->PR_PROC_NR;
map_ptr = (struct mem_map *) m_ptr->PR_MEM_PTR;
if (!isokprocn(k)) return(EINVAL);
rp = proc_addr(k); /* ptr to entry of user getting new map */
/* Copy the map from MM. */
/* Copy the map from PM. */
src_phys = umap_local(proc_addr(caller), D, (vir_bytes) map_ptr,
sizeof(rp->p_memmap));
assert(src_phys != 0);
@ -158,7 +158,7 @@ register message *m_ptr; /* pointer to request message */
(LDT_SIZE - EXTRA_LDT_INDEX) * sizeof(rp->p_ldt[0]));
#endif
rp->p_reg.pc = (reg_t) m_ptr->PR_IP_PTR; /* set pc */
rp->p_flags &= ~RECEIVING; /* MM does not reply to EXEC call */
rp->p_flags &= ~RECEIVING; /* PM does not reply to EXEC call */
if (rp->p_flags == 0) lock_ready(rp);
/* Save command name for debugging, ps(1) output, etc. */
@ -189,7 +189,7 @@ register message *m_ptr; /* pointer to request message */
PUBLIC int do_xit(m_ptr)
message *m_ptr; /* pointer to request message */
{
/* Handle sys_exit. A user process has exited (the MM sent the request).
/* Handle sys_exit. A user process has exited (the PM sent the request).
*/
register struct proc *rp, *rc;
struct proc *np, *xp;
@ -201,7 +201,7 @@ message *m_ptr; /* pointer to request message */
if (! isokprocn(exit_proc_nr)) return(EINVAL);
rc = proc_addr(exit_proc_nr);
/* If this is a user process and the MM passed in a valid parent process,
/* If this is a user process and the PM passed in a valid parent process,
* accumulate the child times at the parent.
*/
if (isuserp(rc) && isokprocn(m_ptr->PR_PPROC_NR)) {
@ -217,7 +217,7 @@ message *m_ptr; /* pointer to request message */
* and resets important process table fields.
*/
clear_proc(exit_proc_nr);
return(OK); /* tell MM that cleanup succeeded */
return(OK); /* tell PM that cleanup succeeded */
}

View file

@ -23,67 +23,54 @@
#include <sys/sigcontext.h>
INIT_ASSERT
/*===========================================================================*
* do_sigctl *
*===========================================================================*/
PUBLIC int do_sigctl(m_ptr)
/* PM is ready to accept signals and repeatedly does a system call to get
* one. Find a process with pending signals. If no signals are available,
* return NONE in the process number field.
*/
PUBLIC int do_getsig(m_ptr)
message *m_ptr; /* pointer to request message */
{
/* Only the MM and FS are allowed to use signal control operations. */
if (m_ptr->m_source != MM_PROC_NR && m_ptr->m_source != FS_PROC_NR)
return(EPERM);
register struct proc *rp;
/* Now see what request we got. The supported requests are S_GETSIG,
* S_ENDSIG, S_SENDSIG, S_SIGRETURN, and S_KILL. Unsupported requests
* result in an EINVAL error.
*/
switch(m_ptr->SIG_REQUEST) {
/* MM is ready to accept signals and repeatedly does a system call to get
* one. Find a process with pending signals. If no signals are available,
* return NONE in the process number field.
*/
case S_GETSIG: {
register struct proc *rp;
/* Find the next process with pending signals. */
for (rp = BEG_USER_ADDR; rp < END_PROC_ADDR; rp++) {
if (rp->p_flags & PENDING) {
m_ptr->SIG_PROC = proc_number(rp);
m_ptr->SIG_MAP = rp->p_pending;
sigemptyset(&rp->p_pending); /* ball is in MM's court */
rp->p_flags &= ~PENDING; /* blocked by SIG_PENDING */
return(OK);
}
}
/* No process with pending signals was found. */
m_ptr->SIG_PROC = NONE;
return(OK);
/* Find the next process with pending signals. */
for (rp = BEG_USER_ADDR; rp < END_PROC_ADDR; rp++) {
if (rp->p_flags & PENDING) {
m_ptr->SIG_PROC = proc_number(rp);
m_ptr->SIG_MAP = rp->p_pending;
sigemptyset(&rp->p_pending); /* ball is in PM's court */
rp->p_flags &= ~PENDING; /* blocked by SIG_PENDING */
return(OK);
}
}
/* Finish up after a KSIG-type signal, caused by a SYS_KILL message or a
* call to cause_sig by a task
*/
case S_ENDSIG: {
/* No process with pending signals was found. */
m_ptr->SIG_PROC = NONE;
return(OK);
}
register struct proc *rp;
PUBLIC int do_endsig(m_ptr)
message *m_ptr; /* pointer to request message */
{
/* Finish up after a kernel type signal, caused by a SYS_KILL message or a
* call to cause_sig by a task. This is called by the PM after processing a
* signal it got with SYS_GETSIG.
*/
register struct proc *rp;
rp = proc_addr(m_ptr->SIG_PROC);
if (isemptyp(rp)) return(EINVAL); /* process already dead? */
assert(isuserp(rp));
rp = proc_addr(m_ptr->SIG_PROC);
if (isemptyp(rp)) return(EINVAL); /* process already dead? */
/* MM has finished one KSIG. Perhaps process is ready now? */
if (rp->p_pendcount != 0 && --rp->p_pendcount == 0
&& (rp->p_flags &= ~SIG_PENDING) == 0)
lock_ready(rp);
return(OK);
}
/* PM has finished one kernel signal. Perhaps process is ready now? */
if (rp->p_pendcount != 0 && --rp->p_pendcount == 0
&& (rp->p_flags &= ~SIG_PENDING) == 0)
lock_ready(rp);
return(OK);
}
/* Handle sys_sendsig, POSIX-style signal handling.
*/
case S_SENDSIG: {
PUBLIC int do_sigsend(m_ptr)
message *m_ptr; /* pointer to request message */
{
/* Handle sys_sigsend, POSIX-style signal handling. */
struct sigmsg smsg;
register struct proc *rp;
@ -95,7 +82,7 @@ message *m_ptr; /* pointer to request message */
assert(isuserp(rp));
/* Get the sigmsg structure into our address space. */
src_phys = umap_local(proc_addr(MM_PROC_NR), D, (vir_bytes)
src_phys = umap_local(proc_addr(PM_PROC_NR), D, (vir_bytes)
m_ptr->SIG_CTXT_PTR, (vir_bytes) sizeof(struct sigmsg));
assert(src_phys != 0);
phys_copy(src_phys,vir2phys(&smsg),(phys_bytes) sizeof(struct sigmsg));
@ -140,13 +127,14 @@ message *m_ptr; /* pointer to request message */
rp->p_reg.pc = (reg_t) smsg.sm_sighandler;
return(OK);
}
/* POSIX style signals require sys_sigreturn to put things in order before
* the signalled process can resume execution
*/
case S_SIGRETURN: {
}
PUBLIC int do_sigreturn(m_ptr)
message *m_ptr; /* pointer to request message */
{
/* POSIX style signals require sys_sigreturn to put things in order before
* the signalled process can resume execution
*/
struct sigcontext sc;
register struct proc *rp;
phys_bytes src_phys;
@ -193,30 +181,18 @@ message *m_ptr; /* pointer to request message */
/* Restore the registers. */
kmemcpy(&rp->p_reg, (char *)&sc.sc_regs, sizeof(struct sigregs));
return(OK);
}
/* Handle sys_kill(). Cause a signal to be sent to a process via MM.
* Note that this has nothing to do with the kill(2) system call, this
* is how the FS (and possibly other servers) get access to cause_sig.
*/
case S_KILL: {
cause_sig(m_ptr->SIG_PROC, m_ptr->SIG_NUMBER);
return(OK);
}
default:
return(EINVAL);
}
}
/*===========================================================================*
* do_sigctl *
*===========================================================================*/
PUBLIC int do_kill(m_ptr)
message *m_ptr; /* pointer to request message */
{
/* Handle sys_kill(). Cause a signal to be sent to a process via MM.
/* Handle sys_kill(). Cause a signal to be sent to a process via PM.
* Note that this has nothing to do with the kill (2) system call, this
* is how the FS (and possibly other servers) get access to cause_sig.
*/

View file

@ -82,7 +82,7 @@ message *m_ptr; /* pointer to request message */
argp = (vir_bytes) m_ptr->CTL_ARG_PTR;
rp = proc_addr(proc_nr);
/* Check if the MM privileges are super user. */
/* Check if the PM privileges are super user. */
if (!priv || !isuserp(rp))
return(EPERM);
@ -99,7 +99,7 @@ message *m_ptr; /* pointer to request message */
rp->p_type = P_SERVER;
rp->p_sendmask = ALLOW_ALL_MASK;
send_mask_allow(proc_addr(RTL8139)->p_sendmask, proc_nr);
send_mask_allow(proc_addr(MM_PROC_NR)->p_sendmask, proc_nr);
send_mask_allow(proc_addr(PM_PROC_NR)->p_sendmask, proc_nr);
send_mask_allow(proc_addr(FS_PROC_NR)->p_sendmask, proc_nr);
send_mask_allow(proc_addr(IS_PROC_NR)->p_sendmask, proc_nr);
send_mask_allow(proc_addr(CLOCK)->p_sendmask, proc_nr);
@ -112,7 +112,7 @@ message *m_ptr; /* pointer to request message */
}
/* The system call implemented in this file:
* m_type: SYS_MEMCTL
* m_type: SYS_SEGCTL
*
* The parameters for this system call are:
* m4_l3: SEG_PHYS (physical base address)
@ -127,9 +127,9 @@ message *m_ptr; /* pointer to request message */
/*===========================================================================*
* do_phys2seg *
* do_segctl *
*===========================================================================*/
PUBLIC int do_phys2seg(m_ptr)
PUBLIC int do_segctl(m_ptr)
register message *m_ptr; /* pointer to request message */
{
/* Return a segment selector and offset that can be used to reach a physical
@ -137,14 +137,28 @@ register message *m_ptr; /* pointer to request message */
*/
u16_t selector;
vir_bytes offset;
int i, index;
register struct proc *rp;
phys_bytes phys = (phys_bytes) m_ptr->SEG_PHYS;
vir_bytes size = (vir_bytes) m_ptr->SEG_SIZE;
int result;
kprintf("Using Experimental LDT selector for video memory\n", NO_ARG);
/* First check if there is a slot available for this segment. */
rp = proc_addr(m_ptr->m_source);
index = -1;
for (i=0; i < NR_REMOTE_SEGS; i++) {
if (! rp->p_farmem[i].in_use) {
index = i;
rp->p_farmem[i].in_use = TRUE;
rp->p_farmem[i].mem_phys = phys;
rp->p_farmem[i].mem_len = size;
break;
}
}
if (index < 0) return(ENOSPC);
if (!protected_mode) {
if (! machine.protected) {
selector = phys / HCLICK_SIZE;
offset = phys % HCLICK_SIZE;
result = OK;
@ -155,26 +169,22 @@ register message *m_ptr; /* pointer to request message */
* instead of bytes are used.
*/
if (size < BYTE_GRAN_MAX) {
rp = proc_addr(m_ptr->m_source);
init_dataseg(&rp->p_ldt[EXTRA_LDT_INDEX], phys, size,
init_dataseg(&rp->p_ldt[EXTRA_LDT_INDEX+i], phys, size,
USER_PRIVILEGE);
selector = (EXTRA_LDT_INDEX * 0x08) | (1 * 0x04) | USER_PRIVILEGE;
selector = ((EXTRA_LDT_INDEX+i)*0x08) | (1*0x04) | USER_PRIVILEGE;
offset = 0;
result = OK;
} else {
#if ENABLE_USERPRIV && ENABLE_LOOSELDT
rp = proc_addr(m_ptr->m_source);
init_dataseg(&rp->p_ldt[EXTRA_LDT_INDEX], phys & ~0xFFFF, 0,
init_dataseg(&rp->p_ldt[EXTRA_LDT_INDEX+i], phys & ~0xFFFF, 0,
USER_PRIVILEGE);
selector = (EXTRA_LDT_INDEX * 0x08) | (1 * 0x04) | USER_PRIVILEGE;
selector = ((EXTRA_LDT_INDEX+i)*0x08) | (1*0x04) | USER_PRIVILEGE;
offset = phys & 0xFFFF;
result = OK;
#else
result = E2BIG; /* allow settings only */
#endif
}
}
/* Request successfully done. Now return the result. */
m_ptr->SEG_INDEX = index | REMOTE_SEG;
m_ptr->SEG_SELECT = selector;
m_ptr->SEG_OFFSET = offset;
return(result);

View file

@ -36,7 +36,7 @@ register message *m_ptr;
* T_EXIT exit
* T_STEP set trace bit
*
* The T_OK and T_EXIT commands are handled completely by the memory manager,
* The T_OK and T_EXIT commands are handled completely by the process manager,
* all others come here.
*/

View file

@ -70,7 +70,7 @@ PUBLIC struct system_image image[] = {
{ CLOCK, clock_task, P_TASK, PPRI_TASK, CLOCK_STACK, CLOCK_SENDMASK, "CLOCK" },
{ SYSTASK, sys_task, P_TASK, PPRI_TASK, SYS_STACK, SYSTEM_SENDMASK, "SYS" },
{ HARDWARE, 0, P_TASK, PPRI_TASK, HARDWARE_STACK,HARDWARE_SENDMASK,"HARDWAR" },
{ MM_PROC_NR, 0, P_SERVER, PPRI_NORMAL, 0, MM_SENDMASK, "MM" },
{ PM_PROC_NR, 0, P_SERVER, PPRI_NORMAL, 0, PM_SENDMASK, "PM" },
{ FS_PROC_NR, 0, P_SERVER, PPRI_NORMAL, 0, FS_SENDMASK, "FS" },
{ IS_PROC_NR, 0, P_SYSTEM, PPRI_HIGHER, 0, IS_SENDMASK, "IS" },
{ TTY, 0, P_SYSTEM, PPRI_HIGHER, 0, TTY_SENDMASK, "TTY" },

View file

@ -5,13 +5,6 @@ typedef _PROTOTYPE( void task_t, (void) );
typedef _PROTOTYPE( int (*rdwt_t), (message *m_ptr) );
typedef _PROTOTYPE( void (*watchdog_t), (void) );
/* This is used within the kernel to handle virtual copying. */
struct vir_addr {
int proc_nr;
int segment;
vir_bytes offset;
};
/* Type accepted by kprintf(). This is a hack to accept both integers and
* char pointers in the same argument.
*/

View file

@ -13,12 +13,14 @@ OBJECTS = \
$(LIBSYS)(sys_times.o) \
$(LIBSYS)(sys_getuptm.o) \
$(LIBSYS)(sys_abort.o) \
$(LIBSYS)(sys_copy.o) \
$(LIBSYS)(sys_exec.o) \
$(LIBSYS)(sys_fork.o) \
$(LIBSYS)(sys_kill.o) \
$(LIBSYS)(sys_newmap.o) \
$(LIBSYS)(sys_sigctl.o) \
$(LIBSYS)(sys_sigsend.o) \
$(LIBSYS)(sys_sigret.o) \
$(LIBSYS)(sys_endsig.o) \
$(LIBSYS)(sys_getsig.o) \
$(LIBSYS)(sys_svrctl.o) \
$(LIBSYS)(sys_trace.o) \
$(LIBSYS)(sys_xit.o) \
@ -27,7 +29,7 @@ OBJECTS = \
$(LIBSYS)(sys_kmalloc.o) \
$(LIBSYS)(sys_irqctl.o) \
$(LIBSYS)(sys_eniop.o) \
$(LIBSYS)(sys_ph2sg.o) \
$(LIBSYS)(sys_segctl.o) \
$(LIBSYS)(sys_umap.o) \
$(LIBSYS)(sys_exit.o) \
$(LIBSYS)(sys_physcp.o) \
@ -67,9 +69,6 @@ $(LIBSYS)(sys_getuptm.o): sys_getuptm.c
$(LIBSYS)(sys_abort.o): sys_abort.c
$(CC1) sys_abort.c
$(LIBSYS)(sys_copy.o): sys_copy.c
$(CC1) sys_copy.c
$(LIBSYS)(sys_exec.o): sys_exec.c
$(CC1) sys_exec.c
@ -106,8 +105,8 @@ $(LIBSYS)(sys_irqctl.o): sys_irqctl.c
$(LIBSYS)(sys_eniop.o): sys_eniop.c
$(CC1) sys_eniop.c
$(LIBSYS)(sys_ph2sg.o): sys_ph2sg.c
$(CC1) sys_ph2sg.c
$(LIBSYS)(sys_segctl.o): sys_segctl.c
$(CC1) sys_segctl.c
$(LIBSYS)(sys_umap.o): sys_umap.c
$(CC1) sys_umap.c
@ -115,8 +114,17 @@ $(LIBSYS)(sys_umap.o): sys_umap.c
$(LIBSYS)(sys_exit.o): sys_exit.c
$(CC1) sys_exit.c
$(LIBSYS)(sys_sigctl.o): sys_sigctl.c
$(CC1) sys_sigctl.c
$(LIBSYS)(sys_getsig.o): sys_getsig.c
$(CC1) sys_getsig.c
$(LIBSYS)(sys_endsig.o): sys_endsig.c
$(CC1) sys_endsig.c
$(LIBSYS)(sys_sigsend.o): sys_sigsend.c
$(CC1) sys_sigsend.c
$(LIBSYS)(sys_sigret.o): sys_sigret.c
$(CC1) sys_sigret.c
$(LIBSYS)(sys_physcp.o): sys_physcp.c
$(CC1) sys_physcp.c

View file

@ -1,31 +0,0 @@
#include "syslib.h"
PUBLIC int sys_copy(src_proc, src_seg, src_vir,
dst_proc, dst_seg, dst_vir, bytes)
int src_proc; /* source process */
int src_seg; /* source segment: T, D, or S */
phys_bytes src_vir; /* source virtual address (phys addr for ABS)*/
int dst_proc; /* dest process */
int dst_seg; /* dest segment: T, D, or S */
phys_bytes dst_vir; /* dest virtual address (phys addr for ABS) */
phys_bytes bytes; /* how many bytes */
{
/* Transfer a block of data. The source and destination can each either be a
* process number, SELF (to set own process number), or ABS (to indicate the
* use of an absolute memory address).
*/
message copy_mess;
if (bytes == 0L) return(OK);
copy_mess.CP_SRC_SPACE = src_seg;
copy_mess.CP_SRC_PROC_NR = src_proc;
copy_mess.CP_SRC_ADDR = (long) src_vir;
copy_mess.CP_DST_SPACE = dst_seg;
copy_mess.CP_DST_PROC_NR = dst_proc;
copy_mess.CP_DST_ADDR = (long) dst_vir;
copy_mess.CP_NR_BYTES = (long) bytes;
return(_taskcall(SYSTASK, SYS_COPY, &copy_mess));
}

View file

@ -1,10 +1,16 @@
#include "syslib.h"
PUBLIC int sys_endsig(proc)
int proc;
/*===========================================================================*
* sys_endsig *
*===========================================================================*/
PUBLIC int sys_endsig(proc_nr)
int proc_nr; /* process number */
{
message m;
message m;
int result;
m.m1_i1 = proc;
return(_taskcall(SYSTASK, SYS_ENDSIG, &m));
m.SIG_PROC = proc_nr;
result = _taskcall(SYSTASK, SYS_ENDSIG, &m);
return(result);
}

View file

@ -1,14 +0,0 @@
#include "syslib.h"
PUBLIC int sys_getmap(proc, ptr)
int proc; /* process whose map is to be fetched */
struct mem_map *ptr; /* pointer to new map */
{
/* Want to know map of a process, ask the kernel. */
message m;
m.m1_i1 = proc;
m.m1_p1 = (char *) ptr;
return(_taskcall(SYSTASK, SYS_GETMAP, &m));
}

18
lib/syslib/sys_getsig.c Normal file
View file

@ -0,0 +1,18 @@
#include "syslib.h"
/*===========================================================================*
* sys_getsig *
*===========================================================================*/
PUBLIC int sys_getsig(k_proc_nr, k_sig_map)
int *k_proc_nr; /* return process number here */
sigset_t *k_sig_map; /* return signal map here */
{
message m;
int result;
result = _taskcall(SYSTASK, SYS_GETSIG, &m);
*k_proc_nr = m.SIG_PROC;
*k_sig_map = (sigset_t) m.SIG_MAP;
return(result);
}

View file

@ -1,16 +0,0 @@
#include "syslib.h"
PUBLIC int sys_oldsig(proc, sig, sighandler)
int proc; /* process to be signaled */
int sig; /* signal number: 1 to _NSIG */
sighandler_t sighandler; /* pointer to signal handler in user space */
{
/* A proc has to be signaled. Tell the kernel. This function is obsolete. */
message m;
m.m6_i1 = proc;
m.m6_i2 = sig;
m.m6_f1 = sighandler;
return(_taskcall(SYSTASK, SYS_OLDSIG, &m));
}

View file

@ -1,18 +1,30 @@
#include "syslib.h"
PUBLIC int sys_physcopy(src_phys, dst_phys, bytes)
phys_bytes src_phys; /* source physical address */
phys_bytes dst_phys; /* destination physical address */
PUBLIC int sys_physcopy(src_proc, src_seg, src_vir,
dst_proc, dst_seg, dst_vir, bytes)
int src_proc; /* source process */
int src_seg; /* source memory segment */
vir_bytes src_vir; /* source virtual address */
int dst_proc; /* destination process */
int dst_seg; /* destination memory segment */
vir_bytes dst_vir; /* destination virtual address */
phys_bytes bytes; /* how many bytes */
{
/* Transfer a block of data. This uses absolute memory addresses only. Use
* sys_umap to convert a virtual address into a physical address if needed.
/* Transfer a block of data. The source and destination can each either be a
* process number or SELF (to indicate own process number). Virtual addresses
* are offsets within LOCAL_SEG (text, stack, data), REMOTE_SEG, or BIOS_SEG.
* Physicall addressing is also possible with PHYS_SEG.
*/
message copy_mess;
if (bytes == 0L) return(OK);
copy_mess.CP_SRC_ADDR = (long) src_phys;
copy_mess.CP_DST_ADDR = (long) dst_phys;
copy_mess.CP_SRC_PROC_NR = src_proc;
copy_mess.CP_SRC_SPACE = src_seg;
copy_mess.CP_SRC_ADDR = (long) src_vir;
copy_mess.CP_DST_PROC_NR = dst_proc;
copy_mess.CP_DST_SPACE = dst_seg;
copy_mess.CP_DST_ADDR = (long) dst_vir;
copy_mess.CP_NR_BYTES = (long) bytes;
return(_taskcall(SYSTASK, SYS_PHYSCOPY, &copy_mess));
}

View file

@ -1,9 +1,10 @@
#include "syslib.h"
/*===========================================================================*
* sys_phys2seg *
* sys_segctl *
*===========================================================================*/
PUBLIC int sys_phys2seg(seg, off, phys, size)
PUBLIC int sys_segctl(index, seg, off, phys, size)
int *index; /* return index of remote segment */
u16_t *seg; /* return segment selector here */
vir_bytes *off; /* return offset in segment here */
phys_bytes phys; /* physical address to convert */
@ -13,7 +14,8 @@ vir_bytes size; /* size of segment */
int s;
m.SEG_PHYS = phys;
m.SEG_SIZE = size;
s = _taskcall(SYSTASK, SYS_PHYS2SEG, &m);
s = _taskcall(SYSTASK, SYS_SEGCTL, &m);
*index = (int) m.SEG_INDEX;
*seg = (u16_t) m.SEG_SELECT;
*off = (vir_bytes) m.SEG_OFFSET;
return s;

View file

@ -1,12 +0,0 @@
#include "syslib.h"
PUBLIC int sys_sendsig(proc, smp)
int proc;
struct sigmsg *smp;
{
message m;
m.m1_i1 = proc;
m.m1_p1 = (char *) smp;
return(_taskcall(SYSTASK, SYS_SENDSIG, &m));
}

View file

@ -1,29 +0,0 @@
#include "syslib.h"
/*===========================================================================*
* sys_sigctl *
*===========================================================================*/
PUBLIC int sys_sigctl(request, proc_nr, sig_ctxt, flags, k_proc_nr, k_sig_map)
int request; /* control operation requested */
int proc_nr; /* for which process */
struct sigmsg *sig_ctxt; /* POSIX style handling */
int flags; /* flags for POSIX handling */
int *k_proc_nr; /* return process number here */
sigset_t *k_sig_map; /* return signal map here */
{
message m;
int result;
m.m_type = SYS_SIGCTL;
m.SIG_REQUEST = request;
m.SIG_PROC = proc_nr;
m.SIG_FLAGS = flags;
m.SIG_CTXT_PTR = (char *) sig_ctxt;
result = _taskcall(SYSTASK, SYS_SIGCTL, &m);
if (request == S_GETSIG && k_proc_nr != 0 && k_sig_map != 0) {
*k_proc_nr = m.SIG_PROC;
*k_sig_map = (sigset_t) m.SIG_MAP;
}
return(result);
}

View file

@ -1,14 +1,20 @@
#include "syslib.h"
PUBLIC int sys_sigreturn(proc, scp, flags)
int proc;
vir_bytes scp;
int flags;
/*===========================================================================*
* sys_sigreturn *
*===========================================================================*/
PUBLIC int sys_sigreturn(proc_nr, sig_ctxt, flags)
int proc_nr; /* for which process */
struct sigmsg *sig_ctxt; /* POSIX style handling */
int flags; /* flags for POSIX handling */
{
message m;
message m;
int result;
m.m1_i1 = proc;
m.m1_i2 = flags;
m.m1_p1 = (char *) scp;
return(_taskcall(SYSTASK, SYS_SIGRETURN, &m));
m.SIG_PROC = proc_nr;
m.SIG_CTXT_PTR = (char *) sig_ctxt;
m.SIG_FLAGS = flags;
result = _taskcall(SYSTASK, SYS_SIGRETURN, &m);
return(result);
}

18
lib/syslib/sys_sigsend.c Normal file
View file

@ -0,0 +1,18 @@
#include "syslib.h"
/*===========================================================================*
* sys_sigsend *
*===========================================================================*/
PUBLIC int sys_sigsend(proc_nr, sig_ctxt)
int proc_nr; /* for which process */
struct sigmsg *sig_ctxt; /* POSIX style handling */
{
message m;
int result;
m.SIG_PROC = proc_nr;
m.SIG_CTXT_PTR = (char *) sig_ctxt;
result = _taskcall(SYSTASK, SYS_SIGSEND, &m);
return(result);
}

View file

@ -1,22 +0,0 @@
#include "syslib.h"
/*===========================================================================*
* sys_vidcopy *
*===========================================================================*/
PUBLIC int sys_vidcopy(request, src_mem, src_vid, dst_vid, count)
int request; /* MEM_VID_COPY or VID_VID_COPY */
u16_t *src_mem; /* source address in memory */
unsigned src_vid; /* source address in video memory */
unsigned dst_vid; /* destination address in video */
unsigned count; /* number of words to copy */
{
/* Console wants to display something on the screen. */
message m;
m.VID_REQUEST = request;
m.VID_SRC_ADDR = src_mem;
m.VID_SRC_OFFSET = src_vid;
m.VID_DST_OFFSET = dst_vid;
m.VID_CP_COUNT = count;
return(_taskcall(SYSTASK, SYS_VIDCOPY, &m));
}

View file

@ -11,8 +11,8 @@ vir_bytes dst_vir; /* destination virtual address */
phys_bytes bytes; /* how many bytes */
{
/* Transfer a block of data. The source and destination can each either be a
* process number or SELF (to set own process number). The virtual address is
* in the data segment (D).
* process number or SELF (to indicate own process number). Virtual addresses
* are offsets within LOCAL_SEG (text, stack, data), REMOTE_SEG, or BIOS_SEG.
*/
message copy_mess;

View file

@ -12,7 +12,7 @@ PUBLIC int get_proc_nr(proc_nr, proc_name)
int *proc_nr; /* store process number here */
char *proc_name; /* lookup process by name */
{
struct proc proc;
static struct proc proc;
message m;
int s;
if (proc_name != NULL) { /* lookup by name */
@ -23,6 +23,7 @@ char *proc_name; /* lookup process by name */
m.I_PROC_NR = SELF;
m.I_KEY_LEN = SELF;
m.I_VAL_PTR = (char *) &proc;
m.I_VAL_LEN = 0;
if ((s=_taskcall(SYSTASK, SYS_GETINFO, &m)) != OK)
return(s);
*proc_nr = proc.p_nr;

View file

@ -33,8 +33,8 @@ PUBLIC int do_cmostime(void)
/* 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) ADR_MACHINE_ID,
SELF, D, (vir_bytes) &mach_id, LEN_MACHINE_ID);
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);

View file

@ -206,7 +206,7 @@ PUBLIC int do_setsid()
register struct fproc *rfp;
/* Only MM may do the SETSID call directly. */
if (who != MM_PROC_NR) return(ENOSYS);
if (who != PM_PROC_NR) return(ENOSYS);
/* Make the process a session leader with no controlling tty. */
rfp = &fproc[m_in.slot1];

View file

@ -305,10 +305,10 @@ 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 MM the RAM disk size, and wait for it to come "on-line". */
/* 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(MM_PROC_NR, &m_out) != OK)
panic("FS can't sync up with MM", NO_NUM);
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

@ -171,8 +171,8 @@ PUBLIC int do_reboot()
struct super_block *sp;
struct inode dummy;
/* Only MM may make this call directly. */
if (who != MM_PROC_NR) return(EGENERIC);
/* Only PM may make this call directly. */
if (who != PM_PROC_NR) return(EGENERIC);
/* Do exit processing for all leftover processes and servers. */
for (i = 0; i < NR_PROCS; i++) { m_in.slot1 = i; do_exit(); }
@ -212,8 +212,8 @@ PUBLIC int do_fork()
register struct fproc *cp;
int i;
/* Only MM may make this call directly. */
if (who != MM_PROC_NR) return(EGENERIC);
/* Only PM may make this call directly. */
if (who != PM_PROC_NR) return(EGENERIC);
/* Copy the parent's fproc struct to the child. */
fproc[m_in.child] = fproc[m_in.parent];
@ -248,8 +248,8 @@ PUBLIC int do_exec()
register int i;
long bitmap;
/* Only MM may make this call directly. */
if (who != MM_PROC_NR) return(EGENERIC);
/* Only PM may make this call directly. */
if (who != PM_PROC_NR) return(EGENERIC);
/* The array of FD_CLOEXEC bits is in the fp_cloexec bit map. */
fp = &fproc[m_in.slot1]; /* get_filp() needs 'fp' */
@ -279,8 +279,8 @@ PUBLIC int do_exit()
register struct inode *rip;
dev_t dev;
/* Only MM may do the EXIT call directly. */
if (who != MM_PROC_NR) return(EGENERIC);
/* Only PM may do the EXIT call directly. */
if (who != PM_PROC_NR) return(EGENERIC);
/* Nevertheless, pretend that the call came from the user. */
fp = &fproc[m_in.slot1]; /* get_filp() needs 'fp' */
@ -343,8 +343,8 @@ PUBLIC int do_set()
register struct fproc *tfp;
/* Only MM may make this call directly. */
if (who != MM_PROC_NR) return(EGENERIC);
/* Only PM may make this call directly. */
if (who != PM_PROC_NR) return(EGENERIC);
tfp = &fproc[m_in.slot1];
if (call_nr == SETUID) {

View file

@ -267,7 +267,7 @@ PUBLIC int do_unpause()
dev_t dev;
message mess;
if (who > MM_PROC_NR) return(EPERM);
if (who > PM_PROC_NR) return(EPERM);
proc_nr = m_in.pro;
if (proc_nr < 0 || proc_nr >= NR_PROCS) panic("unpause err 1", proc_nr);
rfp = &fproc[proc_nr];

View file

@ -54,7 +54,7 @@ int rw_flag; /* READING or WRITING */
int block_size;
/* MM loads segments by putting funny things in upper 10 bits of 'fd'. */
if (who == MM_PROC_NR && (m_in.fd & (~BYTE)) ) {
if (who == PM_PROC_NR && (m_in.fd & (~BYTE)) ) {
usr = m_in.fd >> 7;
seg = (m_in.fd >> 5) & 03;
m_in.fd &= 037; /* get rid of user and segment bits */

View file

@ -36,7 +36,7 @@ PUBLIC int do_chdir()
int r;
register struct fproc *rfp;
if (who == MM_PROC_NR) {
if (who == PM_PROC_NR) {
rfp = &fproc[m_in.slot1];
put_inode(fp->fp_rootdir);
dup_inode(fp->fp_rootdir = rfp->fp_rootdir);

View file

@ -107,6 +107,7 @@ FORWARD _PROTOTYPE ( int cp_b2u, (acc_t *acc_ptr, int proc, char *dest) );
PRIVATE sr_fd_t sr_fd_table[FD_NR];
PRIVATE mq_t *repl_queue, *repl_queue_tail;
PRIVATE cpvec_t cpvec[CPVEC_NR];
PRIVATE struct vir_cp_req vir_cp_req[CPVEC_NR];
PUBLIC void sr_init()
{
@ -650,9 +651,13 @@ int size;
{
size= (vir_bytes)acc->acc_length;
cpvec[i].cpv_src= (vir_bytes)src;
cpvec[i].cpv_dst= (vir_bytes)ptr2acc_data(acc);
cpvec[i].cpv_size= size;
vir_cp_req[i].count= size;
vir_cp_req[i].src.proc_nr = proc;
vir_cp_req[i].src.segment = D;
vir_cp_req[i].src.offset = (vir_bytes) src;
vir_cp_req[i].dst.proc_nr = this_proc;
vir_cp_req[i].dst.segment = D;
vir_cp_req[i].dst.offset = (vir_bytes) ptr2acc_data(acc);
src += size;
acc= acc->acc_next;
@ -660,11 +665,9 @@ int size;
if (i == CPVEC_NR || acc == NULL)
{
mess.m_type= SYS_VCOPY;
mess.m1_i1= proc;
mess.m1_i2= this_proc;
mess.m1_i3= i;
mess.m1_p1= (char *)cpvec;
mess.m_type= SYS_VIRVCOPY;
mess.VCP_VEC_SIZE = i;
mess.VCP_VEC_ADDR = (char *) vir_cp_req;
if (sendrec(SYSTASK, &mess) <0)
ip_panic(("unable to sendrec"));
if (mess.m_type <0)
@ -697,9 +700,13 @@ char *dest;
if (size)
{
cpvec[i].cpv_src= (vir_bytes)ptr2acc_data(acc);
cpvec[i].cpv_dst= (vir_bytes)dest;
cpvec[i].cpv_size= size;
vir_cp_req[i].src.proc_nr = this_proc;
vir_cp_req[i].src.segment = D;
vir_cp_req[i].src.offset= (vir_bytes)ptr2acc_data(acc);
vir_cp_req[i].dst.proc_nr = proc;
vir_cp_req[i].dst.segment = D;
vir_cp_req[i].dst.offset= (vir_bytes)dest;
vir_cp_req[i].count= size;
i++;
}
@ -708,11 +715,9 @@ char *dest;
if (i == CPVEC_NR || acc == NULL)
{
mess.m_type= SYS_VCOPY;
mess.m1_i1= this_proc;
mess.m1_i2= proc;
mess.m1_i3= i;
mess.m1_p1= (char *)cpvec;
mess.m_type= SYS_VIRVCOPY;
mess.VCP_VEC_SIZE = i;
mess.VCP_VEC_ADDR = (char *) vir_cp_req;
if (sendrec(SYSTASK, &mess) <0)
ip_panic(("unable to sendrec"));
if (mess.m_type <0)
@ -746,7 +751,7 @@ assert(!m_cancel);
m= m->mq_next;
continue;
}
assert(m->mq_mess.m_source != MM_PROC_NR);
assert(m->mq_mess.m_source != PM_PROC_NR);
assert(m->mq_mess.m_type == REVIVE);
result= send(m->mq_mess.m_source, &m->mq_mess);
if (result != OK)
@ -758,7 +763,7 @@ assert(m->mq_mess.m_type == REVIVE);
repl_queue= NULL;
if (m_cancel)
{
assert(m_cancel->mq_mess.m_source != MM_PROC_NR);
assert(m_cancel->mq_mess.m_source != PM_PROC_NR);
assert(m_cancel->mq_mess.m_type == REVIVE);
result= send(m_cancel->mq_mess.m_source, &m_cancel->mq_mess);
if (result != OK)

View file

@ -35,7 +35,7 @@ FORWARD _PROTOTYPE( void kmessages_dmp, (void) );
FORWARD _PROTOTYPE( void diagnostics_dmp, (void) );
FORWARD _PROTOTYPE( void sched_dmp, (void) );
FORWARD _PROTOTYPE( void monparams_dmp, (void) );
FORWARD _PROTOTYPE( void kenviron_dmp, (void) );
FORWARD _PROTOTYPE( void kenv_dmp, (void) );
FORWARD _PROTOTYPE( void memchunks_dmp, (void) );
/* Some global data that is shared among several dumping procedures.
@ -62,7 +62,7 @@ PUBLIC int do_fkey_pressed(message *m)
case F6: irqtab_dmp(); break;
case F7: kmessages_dmp(); break;
case F9: diagnostics_dmp(); break;
case F10: kenviron_dmp(); break;
case F10: kenv_dmp(); break;
case F11: memchunks_dmp(); break;
case F12: sched_dmp(); break;
default:
@ -253,7 +253,7 @@ PRIVATE void sched_dmp()
{
struct proc *rdy_head[NR_SCHED_QUEUES];
char *types[] = {"task","higher","high","normal","low","lower","user","idle"};
struct kenviron kenviron;
struct kinfo kinfo;
register struct proc *rp;
vir_bytes ptr_diff;
int r;
@ -264,13 +264,13 @@ PRIVATE void sched_dmp()
return;
}
/* Then obtain kernel addresses to correct pointer information. */
if ((r = sys_getkenviron(&kenviron)) != OK) {
if ((r = sys_getkinfo(&kinfo)) != OK) {
report("warning: couldn't get kernel addresses", r);
return;
}
/* Update all pointers. Nasty pointer algorithmic ... */
ptr_diff = (vir_bytes) proc - (vir_bytes) kenviron.proc_addr;
ptr_diff = (vir_bytes) proc - (vir_bytes) kinfo.proc_addr;
for (r=0;r<NR_SCHED_QUEUES; r++)
if (rdy_head[r] != NIL_PROC)
rdy_head[r] =
@ -296,30 +296,43 @@ PRIVATE void sched_dmp()
}
/*===========================================================================*
* kenviron_dmp *
* kenv_dmp *
*===========================================================================*/
PRIVATE void kenviron_dmp()
PRIVATE void kenv_dmp()
{
struct kenviron kenv;
struct kinfo kinfo;
struct machine machine;
int r;
if ((r = sys_getkenviron(&kenv)) != OK) {
report("warning: couldn't get copy of kernel env", r);
if ((r = sys_getkinfo(&kinfo)) != OK) {
report("warning: couldn't get copy of kernel info struct", r);
return;
}
if ((r = sys_getmachine(&machine)) != OK) {
report("warning: couldn't get copy of kernel machine struct", r);
return;
}
printf("Dump of kernel variables based on the environment set by the boot loader.\n");
printf("- pc_at: %3d\n", kenv.pc_at);
printf("- ps_mca: %3d\n", kenv.ps_mca);
printf("- processor: %3d\n", kenv.processor);
printf("- protected: %3d\n", kenv.protected);
printf("- ega: %3d\n", kenv.ega);
printf("- vga: %3d\n", kenv.vga);
printf("- params_base:%5u\n", kenv.params_base);
printf("- params_size:%5u\n", kenv.params_size);
printf("- kmem_base:%5u\n", kenv.kmem_base);
printf("- kmem_size:%5u\n", kenv.kmem_size);
printf("- bootfs_base:%5u\n", kenv.bootfs_base);
printf("- bootfs_size:%5u\n", kenv.bootfs_size);
printf("Dump of kinfo and machine structures.\n\n");
printf("Machine structure:\n");
printf("- pc_at: %3d\n", machine.pc_at);
printf("- ps_mca: %3d\n", machine.ps_mca);
printf("- processor: %3d\n", machine.processor);
printf("- protected: %3d\n", machine.protected);
printf("- vdu_ega: %3d\n", machine.vdu_ega);
printf("- vdu_vga: %3d\n\n", machine.vdu_vga);
printf("Kernel info structure:\n");
printf("- code_base: %5u\n", kinfo.code_base);
printf("- code_size: %5u\n", kinfo.code_size);
printf("- data_base: %5u\n", kinfo.data_base);
printf("- data_size: %5u\n", kinfo.data_size);
printf("- proc_addr: %5u\n", kinfo.proc_addr);
printf("- kmem_base: %5u\n", kinfo.kmem_base);
printf("- kmem_size: %5u\n", kinfo.kmem_size);
printf("- bootdev_base: %5u\n", kinfo.bootdev_base);
printf("- bootdev_size: %5u\n", kinfo.bootdev_size);
printf("- params_base: %5u\n", kinfo.params_base);
printf("- params_size: %5u\n", kinfo.params_size);
printf("- version: %.6s\n", kinfo.version);
printf("\n");
}

View file

@ -75,14 +75,14 @@ PUBLIC int do_exec()
src = (vir_bytes) m_in.exec_name;
dst = (vir_bytes) name_buf;
r = sys_datacopy(who, (vir_bytes) src,
MM_PROC_NR, (vir_bytes) dst, (phys_bytes) m_in.exec_len);
PM_PROC_NR, (vir_bytes) dst, (phys_bytes) m_in.exec_len);
if (r != OK) return(r); /* file name not in user data segment */
/* Fetch the stack from the user before destroying the old core image. */
src = (vir_bytes) m_in.stack_ptr;
dst = (vir_bytes) mbuf;
r = sys_datacopy(who, (vir_bytes) src,
MM_PROC_NR, (vir_bytes) dst, (phys_bytes)stk_bytes);
PM_PROC_NR, (vir_bytes) dst, (phys_bytes)stk_bytes);
if (r != OK) return(EACCES); /* can't fetch stack (e.g. bad virtual addr) */
@ -128,7 +128,7 @@ PUBLIC int do_exec()
vsp -= stk_bytes;
patch_ptr(mbuf, vsp);
src = (vir_bytes) mbuf;
r = sys_datacopy(MM_PROC_NR, (vir_bytes) src,
r = sys_datacopy(PM_PROC_NR, (vir_bytes) src,
who, (vir_bytes) vsp, (phys_bytes)stk_bytes);
if (r != OK) panic("do_exec stack copy err on", who);
@ -374,8 +374,8 @@ phys_bytes tot_bytes; /* total memory to allocate, including gap */
while (bytes > 0) {
count = MIN(bytes, (phys_bytes) sizeof(zero));
if (sys_copy(MM_PROC_NR, D, (phys_bytes) zero,
ABS, 0, base, count) != OK) {
if (sys_physcopy(PM_PROC_NR, D, (phys_bytes) zero,
NONE, PHYS_SEG, base, count) != OK) {
panic("new_mem can't zero", NO_NUM);
}
base += count;

View file

@ -64,7 +64,7 @@ PUBLIC int do_fork()
/* Create a copy of the parent's core image for the child. */
child_abs = (phys_bytes) child_base << CLICK_SHIFT;
parent_abs = (phys_bytes) rmp->mp_seg[D].mem_phys << CLICK_SHIFT;
i = sys_physcopy(parent_abs, child_abs, prog_bytes);
i = sys_abscopy(parent_abs, child_abs, prog_bytes);
if (i < 0) panic("do_fork can't copy", i);
/* Find a slot in 'mproc' for the child process. A slot must exist. */

View file

@ -91,7 +91,7 @@ PRIVATE void get_work()
/* Process slot of caller. Misuse MM's own process slot if the kernel is
* calling. The can happen in case of pending kernel signals.
*/
mp = &mproc[who < 0 ? MM_PROC_NR : who];
mp = &mproc[who < 0 ? PM_PROC_NR : who];
}

View file

@ -49,7 +49,7 @@ PUBLIC int do_reboot()
case RBT_MONITOR:
if (m_in.reboot_size >= sizeof(monitor_code)) return(EINVAL);
if (sys_datacopy(who, (vir_bytes) m_in.reboot_code,
MM_PROC_NR, (vir_bytes) monitor_code,
PM_PROC_NR, (vir_bytes) monitor_code,
(phys_bytes) (m_in.reboot_size+1)) != OK) return(EFAULT);
if (monitor_code[m_in.reboot_size] != 0) return(EINVAL);
break;
@ -60,7 +60,7 @@ PUBLIC int do_reboot()
check_sig(-1, SIGKILL); /* kill all processes except init */
tell_fs(REBOOT,0,0,0); /* tell FS to prepare for shutdown */
sys_abort(m_in.reboot_flag, MM_PROC_NR, monitor_code, m_in.reboot_size);
sys_abort(m_in.reboot_flag, PM_PROC_NR, monitor_code, m_in.reboot_size);
sys_exit(0);
}
@ -85,6 +85,9 @@ PUBLIC int do_svrctl()
/* Binary compatibility check. */
if (req == SYSGETENV) {
#if DEAD_CODE
printf("SYSGETENV by %d (fix!)\n", who);
#endif
req = MMGETPARAM;
}
@ -179,7 +182,7 @@ PUBLIC int do_svrctl()
if (mp->mp_effuid != SUPER_USER) return(EPERM);
if (sys_datacopy(who, (phys_bytes) ptr,
MM_PROC_NR, (phys_bytes) &swapon,
PM_PROC_NR, (phys_bytes) &swapon,
(phys_bytes) sizeof(swapon)) != OK) return(EFAULT);
return(swap_on(swapon.file, swapon.offset, swapon.size)); }

View file

@ -53,7 +53,7 @@ PUBLIC int do_sigaction()
if (m_in.sig_nr < 1 || m_in.sig_nr > _NSIG) return (EINVAL);
svp = &mp->mp_sigact[m_in.sig_nr];
if ((struct sigaction *) m_in.sig_osa != (struct sigaction *) NULL) {
r = sys_datacopy(MM_PROC_NR,(vir_bytes) svp,
r = sys_datacopy(PM_PROC_NR,(vir_bytes) svp,
who, (vir_bytes) m_in.sig_osa, (phys_bytes) sizeof(svec));
if (r != OK) return(r);
}
@ -63,7 +63,7 @@ PUBLIC int do_sigaction()
/* Read in the sigaction structure. */
r = sys_datacopy(who, (vir_bytes) m_in.sig_nsa,
MM_PROC_NR, (vir_bytes) &svec, (phys_bytes) sizeof(svec));
PM_PROC_NR, (vir_bytes) &svec, (phys_bytes) sizeof(svec));
if (r != OK) return(r);
if (svec.sa_handler == SIG_IGN) {
@ -433,7 +433,7 @@ int signo; /* signal to send to process (1 to _NSIG) */
rmp->mp_sigact[signo].sa_handler = SIG_DFL;
}
sys_sendsig(slot, &sm);
sys_sigsend(slot, &sm);
sigdelset(&rmp->mp_sigpending, signo);
/* If process is hanging on PAUSE, WAIT, SIGSUSPEND, tty, pipe, etc.,
* release it.

View file

@ -39,12 +39,12 @@ int mask; /* R_BIT, W_BIT, or X_BIT */
if (access(name_buf, mask) < 0) return(-errno);
/* The file is accessible but might not be readable. Make it readable. */
tell_fs(SETUID, MM_PROC_NR, (int) SUPER_USER, (int) SUPER_USER);
tell_fs(SETUID, PM_PROC_NR, (int) SUPER_USER, (int) SUPER_USER);
/* Open the file and fstat it. Restore the ids early to handle errors. */
fd = open(name_buf, O_RDONLY | O_NONBLOCK);
save_errno = errno; /* open might fail, e.g. from ENFILE */
tell_fs(SETUID, MM_PROC_NR, (int) mp->mp_effuid, (int) mp->mp_effuid);
tell_fs(SETUID, PM_PROC_NR, (int) mp->mp_effuid, (int) mp->mp_effuid);
if (fd < 0) return(-save_errno);
if (fstat(fd, s_buf) < 0) panic("allowed: fstat failed", NO_NUM);