kernel: facility for user-visible memory
. map all objects named usermapped_*.o with globally visible pages; usermapped_glo_*.o with the VM 'global' bit on, i.e. permanently in tlb (very scarce resource!) . added kinfo, machine, kmessages and loadinfo for a start . modified log, tty to make use of the shared messages struct
This commit is contained in:
parent
53a947167c
commit
b6ea15115c
25 changed files with 209 additions and 64 deletions
|
@ -9,23 +9,24 @@
|
||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
extern struct minix_kerninfo *_minix_kerninfo;
|
||||||
|
|
||||||
/*==========================================================================*
|
/*==========================================================================*
|
||||||
* do_new_kmess *
|
* do_new_kmess *
|
||||||
*==========================================================================*/
|
*==========================================================================*/
|
||||||
void do_new_kmess(void)
|
void do_new_kmess(void)
|
||||||
{
|
{
|
||||||
/* Notification for a new kernel message. */
|
/* Notification for a new kernel message. */
|
||||||
static struct kmessages kmess; /* entire kmess structure */
|
static struct kmessages *kmess; /* entire kmess structure */
|
||||||
static char print_buf[_KMESS_BUF_SIZE]; /* copy new message here */
|
static char print_buf[_KMESS_BUF_SIZE]; /* copy new message here */
|
||||||
int bytes;
|
int bytes;
|
||||||
int i, r;
|
int i, r;
|
||||||
static int prev_next = 0;
|
static int prev_next = 0;
|
||||||
|
|
||||||
/* Try to get a fresh copy of the buffer with kernel messages. */
|
assert(_minix_kerninfo);
|
||||||
if ((r=sys_getkmessages(&kmess)) != OK) {
|
kmess = _minix_kerninfo->kmessages;
|
||||||
printf("log: couldn't get copy of kmessages: %d\n", r);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Print only the new part. Determine how many new bytes there are with
|
/* Print only the new part. Determine how many new bytes there are with
|
||||||
* help of the current and previous 'next' index. Note that the kernel
|
* help of the current and previous 'next' index. Note that the kernel
|
||||||
|
@ -33,13 +34,13 @@ void do_new_kmess(void)
|
||||||
* are new data; else we miss % KMESS_BUF_SIZE here.
|
* are new data; else we miss % KMESS_BUF_SIZE here.
|
||||||
* Check for size being positive, the buffer might as well be emptied!
|
* Check for size being positive, the buffer might as well be emptied!
|
||||||
*/
|
*/
|
||||||
if (kmess.km_size > 0) {
|
if (kmess->km_size > 0) {
|
||||||
bytes = ((kmess.km_next + _KMESS_BUF_SIZE) - prev_next) %
|
bytes = ((kmess->km_next + _KMESS_BUF_SIZE) - prev_next) %
|
||||||
_KMESS_BUF_SIZE;
|
_KMESS_BUF_SIZE;
|
||||||
r= prev_next; /* start at previous old */
|
r= prev_next; /* start at previous old */
|
||||||
i=0;
|
i=0;
|
||||||
while (bytes > 0) {
|
while (bytes > 0) {
|
||||||
print_buf[i] = kmess.km_buf[(r%_KMESS_BUF_SIZE)];
|
print_buf[i] = kmess->km_buf[(r%_KMESS_BUF_SIZE)];
|
||||||
bytes --;
|
bytes --;
|
||||||
r ++;
|
r ++;
|
||||||
i ++;
|
i ++;
|
||||||
|
@ -52,5 +53,5 @@ void do_new_kmess(void)
|
||||||
/* Almost done, store 'next' so that we can determine what part of the
|
/* Almost done, store 'next' so that we can determine what part of the
|
||||||
* kernel messages buffer to print next time a notification arrives.
|
* kernel messages buffer to print next time a notification arrives.
|
||||||
*/
|
*/
|
||||||
prev_next = kmess.km_next;
|
prev_next = kmess->km_next;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#include <minix/drivers.h>
|
#include <minix/drivers.h>
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
|
#include <assert.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/vm.h>
|
#include <sys/vm.h>
|
||||||
#include <sys/video.h>
|
#include <sys/video.h>
|
||||||
|
@ -1007,29 +1008,21 @@ tty_t *tp;
|
||||||
cons_ioctl(tp, 0);
|
cons_ioctl(tp, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern struct minix_kerninfo *_minix_kerninfo;
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* do_new_kmess *
|
* do_new_kmess *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
void do_new_kmess()
|
void do_new_kmess()
|
||||||
{
|
{
|
||||||
/* Notification for a new kernel message. */
|
/* Notification for a new kernel message. */
|
||||||
static struct kmessages kmess; /* kmessages structure */
|
struct kmessages *kmess_ptr; /* kmessages structure */
|
||||||
static int prev_next = 0; /* previous next seen */
|
static int prev_next = 0; /* previous next seen */
|
||||||
int bytes;
|
int bytes;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
/* Try to get a fresh copy of the buffer with kernel messages. */
|
assert(_minix_kerninfo);
|
||||||
#if DEAD_CODE
|
kmess_ptr = _minix_kerninfo->kmessages;
|
||||||
/* During shutdown, the reply is garbled because new notifications arrive
|
|
||||||
* while the system task makes a copy of the kernel messages buffer.
|
|
||||||
* Hence, don't check the return value.
|
|
||||||
*/
|
|
||||||
if ((r=sys_getkmessages(&kmess)) != OK) {
|
|
||||||
printf("TTY: couldn't get copy of kmessages: %d, 0x%x\n", r,r);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
sys_getkmessages(&kmess);
|
|
||||||
|
|
||||||
/* Print only the new part. Determine how many new bytes there are with
|
/* Print only the new part. Determine how many new bytes there are with
|
||||||
* help of the current and previous 'next' index. Note that the kernel
|
* help of the current and previous 'next' index. Note that the kernel
|
||||||
|
@ -1037,11 +1030,11 @@ void do_new_kmess()
|
||||||
* is new data; else we miss % _KMESS_BUF_SIZE here.
|
* is new data; else we miss % _KMESS_BUF_SIZE here.
|
||||||
* Check for size being positive, the buffer might as well be emptied!
|
* Check for size being positive, the buffer might as well be emptied!
|
||||||
*/
|
*/
|
||||||
if (kmess.km_size > 0) {
|
if (kmess_ptr->km_size > 0) {
|
||||||
bytes = ((kmess.km_next + _KMESS_BUF_SIZE) - prev_next) % _KMESS_BUF_SIZE;
|
bytes = ((kmess_ptr->km_next + _KMESS_BUF_SIZE) - prev_next) % _KMESS_BUF_SIZE;
|
||||||
r=prev_next; /* start at previous old */
|
r=prev_next; /* start at previous old */
|
||||||
while (bytes > 0) {
|
while (bytes > 0) {
|
||||||
cons_putk( kmess.km_buf[(r%_KMESS_BUF_SIZE)] );
|
cons_putk( kmess_ptr->km_buf[(r%_KMESS_BUF_SIZE)] );
|
||||||
bytes --;
|
bytes --;
|
||||||
r ++;
|
r ++;
|
||||||
}
|
}
|
||||||
|
@ -1051,7 +1044,7 @@ void do_new_kmess()
|
||||||
/* Almost done, store 'next' so that we can determine what part of the
|
/* Almost done, store 'next' so that we can determine what part of the
|
||||||
* kernel messages buffer to print next time a notification arrives.
|
* kernel messages buffer to print next time a notification arrives.
|
||||||
*/
|
*/
|
||||||
prev_next = kmess.km_next;
|
prev_next = kmess_ptr->km_next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
|
|
|
@ -459,7 +459,6 @@
|
||||||
# define GET_MONPARAMS 4 /* get monitor parameters */
|
# define GET_MONPARAMS 4 /* get monitor parameters */
|
||||||
# define GET_KENV 5 /* get kernel environment string */
|
# define GET_KENV 5 /* get kernel environment string */
|
||||||
# define GET_IRQHOOKS 6 /* get the IRQ table */
|
# define GET_IRQHOOKS 6 /* get the IRQ table */
|
||||||
# define GET_KMESSAGES 7 /* get kernel messages */
|
|
||||||
# define GET_PRIVTAB 8 /* get kernel privileges table */
|
# define GET_PRIVTAB 8 /* get kernel privileges table */
|
||||||
# define GET_KADDRESSES 9 /* get various kernel addresses */
|
# define GET_KADDRESSES 9 /* get various kernel addresses */
|
||||||
# define GET_SCHEDINFO 10 /* get scheduling queues */
|
# define GET_SCHEDINFO 10 /* get scheduling queues */
|
||||||
|
@ -611,6 +610,9 @@
|
||||||
#define SVMCTL_MAP_PHYS_LEN m2_l2
|
#define SVMCTL_MAP_PHYS_LEN m2_l2
|
||||||
|
|
||||||
#define VMMF_UNCACHED (1L << 0)
|
#define VMMF_UNCACHED (1L << 0)
|
||||||
|
#define VMMF_USER (1L << 1)
|
||||||
|
#define VMMF_WRITE (1L << 2)
|
||||||
|
#define VMMF_GLO (1L << 3)
|
||||||
|
|
||||||
/* Values for SVMCTL_PARAM. */
|
/* Values for SVMCTL_PARAM. */
|
||||||
#define VMCTL_CLEAR_PAGEFAULT 12
|
#define VMCTL_CLEAR_PAGEFAULT 12
|
||||||
|
|
|
@ -168,6 +168,7 @@ int receive(endpoint_t src, message *m_ptr, int *status_ptr);
|
||||||
int send(endpoint_t dest, message *m_ptr);
|
int send(endpoint_t dest, message *m_ptr);
|
||||||
int sendnb(endpoint_t dest, message *m_ptr);
|
int sendnb(endpoint_t dest, message *m_ptr);
|
||||||
int senda(asynmsg_t *table, size_t count);
|
int senda(asynmsg_t *table, size_t count);
|
||||||
|
int _minix_kernel_info_struct(struct minix_kerninfo **);
|
||||||
|
|
||||||
int _do_kernel_call(message *m_ptr);
|
int _do_kernel_call(message *m_ptr);
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#define SENDREC 3 /* SEND + RECEIVE */
|
#define SENDREC 3 /* SEND + RECEIVE */
|
||||||
#define NOTIFY 4 /* asynchronous notify */
|
#define NOTIFY 4 /* asynchronous notify */
|
||||||
#define SENDNB 5 /* nonblocking send */
|
#define SENDNB 5 /* nonblocking send */
|
||||||
|
#define MINIX_KERNINFO 6 /* request kernel info structure */
|
||||||
#define SENDA 16 /* asynchronous send */
|
#define SENDA 16 /* asynchronous send */
|
||||||
#define IPCNO_HIGHEST SENDA
|
#define IPCNO_HIGHEST SENDA
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ typedef struct kinfo {
|
||||||
char param_buf[MULTIBOOT_PARAM_BUF_SIZE];
|
char param_buf[MULTIBOOT_PARAM_BUF_SIZE];
|
||||||
|
|
||||||
/* Minix stuff */
|
/* Minix stuff */
|
||||||
struct kmessages *kmess;
|
struct kmessages *kmessages;
|
||||||
int do_serial_debug; /* system serial output */
|
int do_serial_debug; /* system serial output */
|
||||||
int serial_debug_baud; /* serial baud rate */
|
int serial_debug_baud; /* serial baud rate */
|
||||||
int minix_panicing; /* are we panicing? */
|
int minix_panicing; /* are we panicing? */
|
||||||
|
|
|
@ -168,7 +168,6 @@ int sys_umap_remote(endpoint_t proc_ep, endpoint_t grantee, int seg,
|
||||||
vir_bytes vir_addr, vir_bytes bytes, phys_bytes *phys_addr);
|
vir_bytes vir_addr, vir_bytes bytes, phys_bytes *phys_addr);
|
||||||
|
|
||||||
/* Shorthands for sys_getinfo() system call. */
|
/* Shorthands for sys_getinfo() system call. */
|
||||||
#define sys_getkmessages(dst) sys_getinfo(GET_KMESSAGES, dst, 0,0,0)
|
|
||||||
#define sys_getkinfo(dst) sys_getinfo(GET_KINFO, dst, 0,0,0)
|
#define sys_getkinfo(dst) sys_getinfo(GET_KINFO, dst, 0,0,0)
|
||||||
#define sys_getloadinfo(dst) sys_getinfo(GET_LOADINFO, dst, 0,0,0)
|
#define sys_getloadinfo(dst) sys_getinfo(GET_LOADINFO, dst, 0,0,0)
|
||||||
#define sys_getmachine(dst) sys_getinfo(GET_MACHINE, dst, 0,0,0)
|
#define sys_getmachine(dst) sys_getinfo(GET_MACHINE, dst, 0,0,0)
|
||||||
|
|
|
@ -170,5 +170,23 @@ struct k_randomness {
|
||||||
} bin[RANDOM_SOURCES];
|
} bin[RANDOM_SOURCES];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct minix_kerninfo {
|
||||||
|
/* Binaries will depend on the offsets etc. in this
|
||||||
|
* structure, so it can't be changed willy-nilly. In
|
||||||
|
* other words, it is ABI-restricted.
|
||||||
|
*/
|
||||||
|
#define KERNINFO_MAGIC 0xfc3b84bf
|
||||||
|
u32_t kerninfo_magic;
|
||||||
|
u32_t minix_feature_flags;
|
||||||
|
u32_t flags_unused1;
|
||||||
|
u32_t flags_unused2;
|
||||||
|
u32_t flags_unused3;
|
||||||
|
u32_t flags_unused4;
|
||||||
|
struct kinfo *kinfo;
|
||||||
|
struct machine *machine;
|
||||||
|
struct kmessages *kmessages;
|
||||||
|
struct loadinfo *loadinfo;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
#endif /* _TYPE_H */
|
#endif /* _TYPE_H */
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ PROG= kernel
|
||||||
.include "arch/${MACHINE_ARCH}/Makefile.inc"
|
.include "arch/${MACHINE_ARCH}/Makefile.inc"
|
||||||
|
|
||||||
SRCS+= clock.c cpulocals.c interrupt.c main.c proc.c system.c \
|
SRCS+= clock.c cpulocals.c interrupt.c main.c proc.c system.c \
|
||||||
table.c utility.c
|
table.c utility.c usermapped_data.c
|
||||||
|
|
||||||
LINKERSCRIPT=${.CURDIR}/arch/${MACHINE_ARCH}/kernel.lds
|
LINKERSCRIPT=${.CURDIR}/arch/${MACHINE_ARCH}/kernel.lds
|
||||||
|
|
||||||
|
|
|
@ -182,6 +182,11 @@ void arch_proc_reset(struct proc *pr)
|
||||||
pr->p_reg.ds = USER_DS_SELECTOR;
|
pr->p_reg.ds = USER_DS_SELECTOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void arch_set_secondary_ipc_return(struct proc *p, u32_t val)
|
||||||
|
{
|
||||||
|
p->p_reg.bx = val;
|
||||||
|
}
|
||||||
|
|
||||||
int restore_fpu(struct proc *pr)
|
int restore_fpu(struct proc *pr)
|
||||||
{
|
{
|
||||||
int failed;
|
int failed;
|
||||||
|
|
|
@ -21,8 +21,14 @@ SECTIONS
|
||||||
|
|
||||||
. += _kern_offset;
|
. += _kern_offset;
|
||||||
|
|
||||||
|
. = ALIGN(4096); usermapped_start = .;
|
||||||
|
.usermapped_glo : AT(ADDR(.usermapped_glo) - _kern_offset) { usermapped_glo*.o }
|
||||||
|
. = ALIGN(4096); usermapped_nonglo_start = .;
|
||||||
|
.usermapped : AT(ADDR(.usermapped) - _kern_offset) { usermapped_*.o }
|
||||||
|
. = ALIGN(4096); usermapped_end = .;
|
||||||
.text : AT(ADDR(.text) - _kern_offset) { *(.text*) }
|
.text : AT(ADDR(.text) - _kern_offset) { *(.text*) }
|
||||||
.data ALIGN(4096) : AT(ADDR(.data) - _kern_offset) { *(.data .rodata* ) }
|
.data ALIGN(4096) : AT(ADDR(.data) - _kern_offset) { *(.data .rodata* ) }
|
||||||
|
. = ALIGN(4096);
|
||||||
.bss ALIGN(4096) : AT(ADDR(.bss) - _kern_offset) { *(.bss* COMMON)
|
.bss ALIGN(4096) : AT(ADDR(.bss) - _kern_offset) { *(.bss* COMMON)
|
||||||
__k_unpaged__kern_size = . - _kern_vir_base;
|
__k_unpaged__kern_size = . - _kern_vir_base;
|
||||||
_kern_size = __k_unpaged__kern_size;
|
_kern_size = __k_unpaged__kern_size;
|
||||||
|
|
|
@ -757,10 +757,14 @@ static int oxpcie_mapping_index = -1,
|
||||||
lapic_mapping_index = -1,
|
lapic_mapping_index = -1,
|
||||||
ioapic_first_index = -1,
|
ioapic_first_index = -1,
|
||||||
ioapic_last_index = -1,
|
ioapic_last_index = -1,
|
||||||
video_mem_mapping_index = -1;
|
video_mem_mapping_index = -1,
|
||||||
|
usermapped_glo_index = -1,
|
||||||
|
usermapped_index = -1, first_um_idx = -1;
|
||||||
|
|
||||||
extern char *video_mem;
|
extern char *video_mem;
|
||||||
|
|
||||||
|
extern char usermapped_start, usermapped_end, usermapped_nonglo_start;
|
||||||
|
|
||||||
int arch_phys_map(const int index,
|
int arch_phys_map(const int index,
|
||||||
phys_bytes *addr,
|
phys_bytes *addr,
|
||||||
phys_bytes *len,
|
phys_bytes *len,
|
||||||
|
@ -769,9 +773,19 @@ int arch_phys_map(const int index,
|
||||||
static int first = 1;
|
static int first = 1;
|
||||||
int freeidx = 0;
|
int freeidx = 0;
|
||||||
static char *ser_var = NULL;
|
static char *ser_var = NULL;
|
||||||
|
u32_t glo_len = (u32_t) &usermapped_nonglo_start -
|
||||||
|
(u32_t) &usermapped_start;
|
||||||
|
|
||||||
if(first) {
|
if(first) {
|
||||||
video_mem_mapping_index = freeidx++;
|
video_mem_mapping_index = freeidx++;
|
||||||
|
if(glo_len > 0) {
|
||||||
|
usermapped_glo_index = freeidx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
usermapped_index = freeidx++;
|
||||||
|
first_um_idx = usermapped_index;
|
||||||
|
if(usermapped_glo_index != -1)
|
||||||
|
first_um_idx = usermapped_glo_index;
|
||||||
|
|
||||||
#ifdef USE_APIC
|
#ifdef USE_APIC
|
||||||
if(lapic_addr)
|
if(lapic_addr)
|
||||||
|
@ -798,21 +812,34 @@ int arch_phys_map(const int index,
|
||||||
first = 0;
|
first = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_APIC
|
if(index == usermapped_glo_index) {
|
||||||
if (index == video_mem_mapping_index) {
|
*addr = vir2phys(&usermapped_start);
|
||||||
|
*len = glo_len;
|
||||||
|
*flags = VMMF_USER | VMMF_GLO;
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
else if(index == usermapped_index) {
|
||||||
|
*addr = vir2phys(&usermapped_nonglo_start);
|
||||||
|
*len = (u32_t) &usermapped_end -
|
||||||
|
(u32_t) &usermapped_nonglo_start;
|
||||||
|
*flags = VMMF_USER;
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
else if (index == video_mem_mapping_index) {
|
||||||
/* map video memory in so we can print panic messages */
|
/* map video memory in so we can print panic messages */
|
||||||
*addr = MULTIBOOT_VIDEO_BUFFER;
|
*addr = MULTIBOOT_VIDEO_BUFFER;
|
||||||
*len = I386_PAGE_SIZE;
|
*len = I386_PAGE_SIZE;
|
||||||
*flags = 0;
|
*flags = VMMF_WRITE;
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
#ifdef USE_APIC
|
||||||
else if (index == lapic_mapping_index) {
|
else if (index == lapic_mapping_index) {
|
||||||
/* map the local APIC if enabled */
|
/* map the local APIC if enabled */
|
||||||
if (!lapic_addr)
|
if (!lapic_addr)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
*addr = lapic_addr;
|
*addr = lapic_addr;
|
||||||
*len = 4 << 10 /* 4kB */;
|
*len = 4 << 10 /* 4kB */;
|
||||||
*flags = VMMF_UNCACHED;
|
*flags = VMMF_UNCACHED | VMMF_WRITE;
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
else if (ioapic_enabled && index >= ioapic_first_index && index <= ioapic_last_index) {
|
else if (ioapic_enabled && index >= ioapic_first_index && index <= ioapic_last_index) {
|
||||||
|
@ -820,7 +847,7 @@ int arch_phys_map(const int index,
|
||||||
*addr = io_apic[ioapic_idx].paddr;
|
*addr = io_apic[ioapic_idx].paddr;
|
||||||
assert(*addr);
|
assert(*addr);
|
||||||
*len = 4 << 10 /* 4kB */;
|
*len = 4 << 10 /* 4kB */;
|
||||||
*flags = VMMF_UNCACHED;
|
*flags = VMMF_UNCACHED | VMMF_WRITE;
|
||||||
printf("ioapic map: addr 0x%lx\n", *addr);
|
printf("ioapic map: addr 0x%lx\n", *addr);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
@ -830,7 +857,7 @@ int arch_phys_map(const int index,
|
||||||
if(index == oxpcie_mapping_index) {
|
if(index == oxpcie_mapping_index) {
|
||||||
*addr = strtoul(ser_var+2, NULL, 16);
|
*addr = strtoul(ser_var+2, NULL, 16);
|
||||||
*len = 0x4000;
|
*len = 0x4000;
|
||||||
*flags = VMMF_UNCACHED;
|
*flags = VMMF_UNCACHED | VMMF_WRITE;
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -860,6 +887,31 @@ int arch_phys_map_reply(const int index, const vir_bytes addr)
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if(index == first_um_idx) {
|
||||||
|
u32_t usermapped_offset;
|
||||||
|
assert(addr > (u32_t) &usermapped_start);
|
||||||
|
usermapped_offset = addr - (u32_t) &usermapped_start;
|
||||||
|
memset(&minix_kerninfo, 0, sizeof(minix_kerninfo));
|
||||||
|
#define FIXEDPTR(ptr) (void *) ((u32_t)ptr + usermapped_offset)
|
||||||
|
#define FIXPTR(ptr) ptr = FIXEDPTR(ptr)
|
||||||
|
#define ASSIGN(minixstruct) minix_kerninfo.minixstruct = FIXEDPTR(&minixstruct)
|
||||||
|
ASSIGN(kinfo);
|
||||||
|
ASSIGN(machine);
|
||||||
|
ASSIGN(kmessages);
|
||||||
|
ASSIGN(loadinfo);
|
||||||
|
|
||||||
|
/* adjust the pointers of the functions and the struct
|
||||||
|
* itself to the user-accessible mapping
|
||||||
|
*/
|
||||||
|
minix_kerninfo.kerninfo_magic = KERNINFO_MAGIC;
|
||||||
|
minix_kerninfo.minix_feature_flags = minix_feature_flags;
|
||||||
|
minix_kerninfo_user = (vir_bytes) FIXEDPTR(&minix_kerninfo);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(index == usermapped_index) return OK;
|
||||||
|
|
||||||
if (index == video_mem_mapping_index) {
|
if (index == video_mem_mapping_index) {
|
||||||
video_mem_vaddr = addr;
|
video_mem_vaddr = addr;
|
||||||
return OK;
|
return OK;
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
/* to-be-built kinfo struct, diagnostics buffer */
|
/* to-be-built kinfo struct, diagnostics buffer */
|
||||||
kinfo_t kinfo;
|
kinfo_t kinfo;
|
||||||
struct kmessages kmess;
|
struct kmessages kmessages;
|
||||||
|
|
||||||
/* pg_utils.c uses this; in this phase, there is a 1:1 mapping. */
|
/* pg_utils.c uses this; in this phase, there is a 1:1 mapping. */
|
||||||
phys_bytes vir2phys(void *addr) { return (phys_bytes) addr; }
|
phys_bytes vir2phys(void *addr) { return (phys_bytes) addr; }
|
||||||
|
|
15
kernel/glo.h
15
kernel/glo.h
|
@ -19,11 +19,18 @@
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
/* Kernel information structures. This groups vital kernel information. */
|
/* Kernel information structures. This groups vital kernel information. */
|
||||||
EXTERN struct kinfo kinfo; /* kernel information for users */
|
extern struct kinfo kinfo; /* kernel information for users */
|
||||||
EXTERN struct machine machine; /* machine information for users */
|
extern struct machine machine; /* machine information for users */
|
||||||
EXTERN struct kmessages kmess; /* diagnostic messages in kernel */
|
extern struct kmessages kmessages; /* diagnostic messages in kernel */
|
||||||
|
extern struct loadinfo loadinfo; /* status of load average */
|
||||||
|
extern struct minix_kerninfo minix_kerninfo;
|
||||||
|
|
||||||
EXTERN struct k_randomness krandom; /* gather kernel random information */
|
EXTERN struct k_randomness krandom; /* gather kernel random information */
|
||||||
EXTERN struct loadinfo kloadinfo; /* status of load average */
|
|
||||||
|
vir_bytes minix_kerninfo_user;
|
||||||
|
|
||||||
|
#define kmess kmessages
|
||||||
|
#define kloadinfo loadinfo
|
||||||
|
|
||||||
/* Process scheduling information and the kernel reentry count. */
|
/* Process scheduling information and the kernel reentry count. */
|
||||||
EXTERN struct proc *vmrequest; /* first process on vmrequest queue */
|
EXTERN struct proc *vmrequest; /* first process on vmrequest queue */
|
||||||
|
|
|
@ -608,6 +608,16 @@ int do_ipc(reg_t r1, reg_t r2, reg_t r3)
|
||||||
return EDOM;
|
return EDOM;
|
||||||
return mini_senda(caller_ptr, (asynmsg_t *) r3, msg_size);
|
return mini_senda(caller_ptr, (asynmsg_t *) r3, msg_size);
|
||||||
}
|
}
|
||||||
|
case MINIX_KERNINFO:
|
||||||
|
{
|
||||||
|
/* It might not be initialized yet. */
|
||||||
|
if(!minix_kerninfo_user) {
|
||||||
|
return EBADCALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
arch_set_secondary_ipc_return(caller_ptr, minix_kerninfo_user);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return EBADCALL; /* illegal system call */
|
return EBADCALL; /* illegal system call */
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,6 +150,7 @@ void stop_profile_clock(void);
|
||||||
/* functions defined in architecture-dependent files. */
|
/* functions defined in architecture-dependent files. */
|
||||||
void prot_init();
|
void prot_init();
|
||||||
void arch_post_init();
|
void arch_post_init();
|
||||||
|
void arch_set_secondary_ipc_return(struct proc *, u32_t val);
|
||||||
phys_bytes phys_copy(phys_bytes source, phys_bytes dest, phys_bytes
|
phys_bytes phys_copy(phys_bytes source, phys_bytes dest, phys_bytes
|
||||||
count);
|
count);
|
||||||
void phys_copy_fault(void);
|
void phys_copy_fault(void);
|
||||||
|
|
|
@ -167,11 +167,6 @@ int do_getinfo(struct proc * caller, message * m_ptr)
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GET_KMESSAGES: {
|
|
||||||
length = sizeof(struct kmessages);
|
|
||||||
src_vir = (vir_bytes) &kmess;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case GET_IRQACTIDS: {
|
case GET_IRQACTIDS: {
|
||||||
length = sizeof(irq_actids);
|
length = sizeof(irq_actids);
|
||||||
src_vir = (vir_bytes) irq_actids;
|
src_vir = (vir_bytes) irq_actids;
|
||||||
|
|
11
kernel/usermapped_data.c
Normal file
11
kernel/usermapped_data.c
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#include "kernel.h"
|
||||||
|
|
||||||
|
/* This is the user-visible struct that has pointers to other bits of data. */
|
||||||
|
struct minix_kerninfo minix_kerninfo;
|
||||||
|
|
||||||
|
/* Kernel information structures. */
|
||||||
|
struct kinfo kinfo; /* kernel information for users */
|
||||||
|
struct machine machine; /* machine information for users */
|
||||||
|
struct kmessages kmessages; /* diagnostic messages in kernel */
|
||||||
|
struct loadinfo loadinfo; /* status of load average */
|
||||||
|
|
|
@ -50,6 +50,20 @@ ENTRY(_sendrec)
|
||||||
pop %ebp
|
pop %ebp
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
ENTRY(_minix_kernel_info_struct)
|
||||||
|
push %ebp
|
||||||
|
movl %esp, %ebp
|
||||||
|
push %ebx
|
||||||
|
movl $0, %eax
|
||||||
|
movl $0, %ebx
|
||||||
|
movl $MINIX_KERNINFO, %ecx
|
||||||
|
int $IPCVEC /* trap to the kernel */
|
||||||
|
movl 8(%ebp), %ecx /* ecx = return struct ptr */
|
||||||
|
movl %ebx, (%ecx)
|
||||||
|
pop %ebx
|
||||||
|
pop %ebp
|
||||||
|
ret
|
||||||
|
|
||||||
ENTRY(_notify)
|
ENTRY(_notify)
|
||||||
push %ebp
|
push %ebp
|
||||||
movl %esp, %ebp
|
movl %esp, %ebp
|
||||||
|
|
|
@ -16,7 +16,7 @@ SRCS+= accept.c access.c bind.c brk.c sbrk.c m_closefrom.c getsid.c \
|
||||||
vectorio.c shutdown.c sigaction.c sigpending.c sigreturn.c sigsuspend.c\
|
vectorio.c shutdown.c sigaction.c sigpending.c sigreturn.c sigsuspend.c\
|
||||||
sigprocmask.c socket.c socketpair.c stat.c statvfs.c symlink.c \
|
sigprocmask.c socket.c socketpair.c stat.c statvfs.c symlink.c \
|
||||||
sync.c syscall.c sysuname.c truncate.c umask.c unlink.c write.c \
|
sync.c syscall.c sysuname.c truncate.c umask.c unlink.c write.c \
|
||||||
_exit.c _ucontext.c environ.c __getcwd.c vfork.c sizeup.c
|
_exit.c _ucontext.c environ.c __getcwd.c vfork.c sizeup.c init.c
|
||||||
|
|
||||||
# Minix specific syscalls.
|
# Minix specific syscalls.
|
||||||
SRCS+= cprofile.c lseek64.c sprofile.c _mcontext.c
|
SRCS+= cprofile.c lseek64.c sprofile.c _mcontext.c
|
||||||
|
|
16
lib/libc/sys-minix/init.c
Normal file
16
lib/libc/sys-minix/init.c
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <minix/ipc.h>
|
||||||
|
|
||||||
|
struct minix_kerninfo *_minix_kerninfo = NULL;
|
||||||
|
|
||||||
|
void __minix_init(void) __attribute__((__constructor__, __used__));
|
||||||
|
|
||||||
|
void __minix_init(void)
|
||||||
|
{
|
||||||
|
if((_minix_kernel_info_struct(&_minix_kerninfo)) != 0
|
||||||
|
|| _minix_kerninfo->kerninfo_magic != KERNINFO_MAGIC) {
|
||||||
|
_minix_kerninfo = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -131,7 +131,7 @@ CPPFLAGS.${i}+= -I${LIBCSRCDIR}/include -I${LIBCSRCDIR}/locale
|
||||||
link.c _mcontext.c mknod.c mmap.c nanosleep.c open.c \
|
link.c _mcontext.c mknod.c mmap.c nanosleep.c open.c \
|
||||||
read.c sbrk.c select.c setuid.c sigprocmask.c stat.c \
|
read.c sbrk.c select.c setuid.c sigprocmask.c stat.c \
|
||||||
stime.c syscall.c _ucontext.c umask.c unlink.c waitpid.c \
|
stime.c syscall.c _ucontext.c umask.c unlink.c waitpid.c \
|
||||||
brksize.S _ipc.S _senda.S ucontext.S mmap.c
|
brksize.S _ipc.S _senda.S ucontext.S mmap.c init.c
|
||||||
.PATH.c: ${LIBCSRCDIR}/sys-minix
|
.PATH.c: ${LIBCSRCDIR}/sys-minix
|
||||||
.PATH.S: ${LIBCSRCDIR}/arch/${MACHINE}/sys-minix
|
.PATH.S: ${LIBCSRCDIR}/arch/${MACHINE}/sys-minix
|
||||||
SRCS+= ${i}
|
SRCS+= ${i}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "inc.h"
|
#include "inc.h"
|
||||||
#include <timers.h>
|
#include <timers.h>
|
||||||
|
#include <assert.h>
|
||||||
#include <machine/interrupt.h>
|
#include <machine/interrupt.h>
|
||||||
#include <minix/endpoint.h>
|
#include <minix/endpoint.h>
|
||||||
#include <minix/sysutil.h>
|
#include <minix/sysutil.h>
|
||||||
|
@ -54,32 +55,33 @@ struct proc proc[NR_TASKS + NR_PROCS];
|
||||||
struct priv priv[NR_SYS_PROCS];
|
struct priv priv[NR_SYS_PROCS];
|
||||||
struct boot_image image[NR_BOOT_PROCS];
|
struct boot_image image[NR_BOOT_PROCS];
|
||||||
|
|
||||||
|
extern struct minix_kerninfo *_minix_kerninfo;
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* kmessages_dmp *
|
* kmessages_dmp *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
void kmessages_dmp()
|
void kmessages_dmp()
|
||||||
{
|
{
|
||||||
struct kmessages kmess; /* get copy of kernel messages */
|
struct kmessages *kmess; /* get copy of kernel messages */
|
||||||
char print_buf[_KMESS_BUF_SIZE+1]; /* this one is used to print */
|
char print_buf[_KMESS_BUF_SIZE+1]; /* this one is used to print */
|
||||||
int start; /* calculate start of messages */
|
int start; /* calculate start of messages */
|
||||||
int r;
|
int r;
|
||||||
|
int size;
|
||||||
|
|
||||||
/* Try to get a copy of the kernel messages. */
|
assert(_minix_kerninfo);
|
||||||
if ((r = sys_getkmessages(&kmess)) != OK) {
|
kmess = _minix_kerninfo->kmessages;
|
||||||
printf("IS: warning: couldn't get copy of kmessages: %d\n", r);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Try to print the kernel messages. First determine start and copy the
|
/* Try to print the kernel messages. First determine start and copy the
|
||||||
* buffer into a print-buffer. This is done because the messages in the
|
* buffer into a print-buffer. This is done because the messages in the
|
||||||
* copy may wrap (the kernel buffer is circular).
|
* copy may wrap (the kernel buffer is circular).
|
||||||
*/
|
*/
|
||||||
start = ((kmess.km_next + _KMESS_BUF_SIZE) - kmess.km_size) % _KMESS_BUF_SIZE;
|
start = ((kmess->km_next + _KMESS_BUF_SIZE) - kmess->km_size) % _KMESS_BUF_SIZE;
|
||||||
r = 0;
|
r = 0;
|
||||||
while (kmess.km_size > 0) {
|
size = kmess->km_size;
|
||||||
print_buf[r] = kmess.km_buf[(start+r) % _KMESS_BUF_SIZE];
|
while (size > 0) {
|
||||||
|
print_buf[r] = kmess->km_buf[(start+r) % _KMESS_BUF_SIZE];
|
||||||
r ++;
|
r ++;
|
||||||
kmess.km_size --;
|
size--;
|
||||||
}
|
}
|
||||||
print_buf[r] = 0; /* make sure it terminates */
|
print_buf[r] = 0; /* make sure it terminates */
|
||||||
printf("Dump of all messages generated by the kernel.\n\n");
|
printf("Dump of all messages generated by the kernel.\n\n");
|
||||||
|
|
|
@ -936,9 +936,15 @@ void pt_init(void)
|
||||||
kern_mappings[index].flags = flags;
|
kern_mappings[index].flags = flags;
|
||||||
kern_mappings[index].vir_addr = offset;
|
kern_mappings[index].vir_addr = offset;
|
||||||
kern_mappings[index].flags =
|
kern_mappings[index].flags =
|
||||||
I386_VM_PRESENT | I386_VM_USER | I386_VM_WRITE;
|
I386_VM_PRESENT;
|
||||||
if(flags & VMMF_UNCACHED)
|
if(flags & VMMF_UNCACHED)
|
||||||
kern_mappings[index].flags |= PTF_NOCACHE;
|
kern_mappings[index].flags |= PTF_NOCACHE;
|
||||||
|
if(flags & VMMF_USER)
|
||||||
|
kern_mappings[index].flags |= I386_VM_USER;
|
||||||
|
if(flags & VMMF_WRITE)
|
||||||
|
kern_mappings[index].flags |= I386_VM_WRITE;
|
||||||
|
if(flags & VMMF_GLO)
|
||||||
|
kern_mappings[index].flags |= I386_VM_GLOBAL;
|
||||||
if(addr % I386_PAGE_SIZE)
|
if(addr % I386_PAGE_SIZE)
|
||||||
panic("VM: addr unaligned: %d", addr);
|
panic("VM: addr unaligned: %d", addr);
|
||||||
if(len % I386_PAGE_SIZE)
|
if(len % I386_PAGE_SIZE)
|
||||||
|
|
|
@ -71,9 +71,14 @@ void do_pagefaults(message *m)
|
||||||
|
|
||||||
/* See if address is valid at all. */
|
/* See if address is valid at all. */
|
||||||
if(!(region = map_lookup(vmp, addr))) {
|
if(!(region = map_lookup(vmp, addr))) {
|
||||||
|
if(PFERR_PROT(err)) {
|
||||||
|
printf("VM: pagefault: SIGSEGV %d protected addr 0x%x; %s\n",
|
||||||
|
ep, addr, pf_errstr(err));
|
||||||
|
} else {
|
||||||
assert(PFERR_NOPAGE(err));
|
assert(PFERR_NOPAGE(err));
|
||||||
printf("VM: pagefault: SIGSEGV %d bad addr 0x%x; %s\n",
|
printf("VM: pagefault: SIGSEGV %d bad addr 0x%x; %s\n",
|
||||||
ep, addr, pf_errstr(err));
|
ep, addr, pf_errstr(err));
|
||||||
|
}
|
||||||
if((s=sys_kill(vmp->vm_endpoint, SIGSEGV)) != OK)
|
if((s=sys_kill(vmp->vm_endpoint, SIGSEGV)) != OK)
|
||||||
panic("sys_kill failed: %d", s);
|
panic("sys_kill failed: %d", s);
|
||||||
if((s=sys_vmctl(ep, VMCTL_CLEAR_PAGEFAULT, 0 /*unused*/)) != OK)
|
if((s=sys_vmctl(ep, VMCTL_CLEAR_PAGEFAULT, 0 /*unused*/)) != OK)
|
||||||
|
|
Loading…
Reference in a new issue