From: Ben Gras Date: Wed, 18 Jul 2012 16:53:20 +0000 (+0200) Subject: kernel: facility for user-visible memory X-Git-Tag: v3.2.1~438 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/zpipe.c?a=commitdiff_plain;h=b6ea15115c4aba2518546741a7dd33c86380f24a;p=minix.git 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 --- diff --git a/drivers/log/diag.c b/drivers/log/diag.c index c9de05334..ac7841ba4 100644 --- a/drivers/log/diag.c +++ b/drivers/log/diag.c @@ -9,23 +9,24 @@ #include "log.h" +#include + +extern struct minix_kerninfo *_minix_kerninfo; + /*==========================================================================* * do_new_kmess * *==========================================================================*/ void do_new_kmess(void) { /* 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 */ int bytes; int i, r; static int prev_next = 0; - /* Try to get a fresh copy of the buffer with kernel messages. */ - if ((r=sys_getkmessages(&kmess)) != OK) { - printf("log: couldn't get copy of kmessages: %d\n", r); - return; - } + assert(_minix_kerninfo); + kmess = _minix_kerninfo->kmessages; /* 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 @@ -33,13 +34,13 @@ void do_new_kmess(void) * are new data; else we miss % KMESS_BUF_SIZE here. * Check for size being positive, the buffer might as well be emptied! */ - if (kmess.km_size > 0) { - bytes = ((kmess.km_next + _KMESS_BUF_SIZE) - prev_next) % + if (kmess->km_size > 0) { + bytes = ((kmess->km_next + _KMESS_BUF_SIZE) - prev_next) % _KMESS_BUF_SIZE; r= prev_next; /* start at previous old */ i=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 --; r ++; i ++; @@ -52,5 +53,5 @@ void do_new_kmess(void) /* Almost done, store 'next' so that we can determine what part of the * kernel messages buffer to print next time a notification arrives. */ - prev_next = kmess.km_next; + prev_next = kmess->km_next; } diff --git a/drivers/tty/console.c b/drivers/tty/console.c index 023c9449f..6ec7fb4eb 100644 --- a/drivers/tty/console.c +++ b/drivers/tty/console.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -1007,29 +1008,21 @@ tty_t *tp; cons_ioctl(tp, 0); } +extern struct minix_kerninfo *_minix_kerninfo; + /*===========================================================================* * do_new_kmess * *===========================================================================*/ void do_new_kmess() { /* 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 */ int bytes; int r; - /* Try to get a fresh copy of the buffer with kernel messages. */ -#if DEAD_CODE - /* 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); + assert(_minix_kerninfo); + kmess_ptr = _minix_kerninfo->kmessages; /* 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 @@ -1037,11 +1030,11 @@ void do_new_kmess() * is new data; else we miss % _KMESS_BUF_SIZE here. * Check for size being positive, the buffer might as well be emptied! */ - if (kmess.km_size > 0) { - bytes = ((kmess.km_next + _KMESS_BUF_SIZE) - prev_next) % _KMESS_BUF_SIZE; + if (kmess_ptr->km_size > 0) { + bytes = ((kmess_ptr->km_next + _KMESS_BUF_SIZE) - prev_next) % _KMESS_BUF_SIZE; r=prev_next; /* start at previous old */ while (bytes > 0) { - cons_putk( kmess.km_buf[(r%_KMESS_BUF_SIZE)] ); + cons_putk( kmess_ptr->km_buf[(r%_KMESS_BUF_SIZE)] ); bytes --; r ++; } @@ -1051,7 +1044,7 @@ void do_new_kmess() /* Almost done, store 'next' so that we can determine what part of the * kernel messages buffer to print next time a notification arrives. */ - prev_next = kmess.km_next; + prev_next = kmess_ptr->km_next; } /*===========================================================================* diff --git a/include/minix/com.h b/include/minix/com.h index d0f091fa6..2e99f1068 100644 --- a/include/minix/com.h +++ b/include/minix/com.h @@ -459,7 +459,6 @@ # define GET_MONPARAMS 4 /* get monitor parameters */ # define GET_KENV 5 /* get kernel environment string */ # 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_KADDRESSES 9 /* get various kernel addresses */ # define GET_SCHEDINFO 10 /* get scheduling queues */ @@ -611,6 +610,9 @@ #define SVMCTL_MAP_PHYS_LEN m2_l2 #define VMMF_UNCACHED (1L << 0) +#define VMMF_USER (1L << 1) +#define VMMF_WRITE (1L << 2) +#define VMMF_GLO (1L << 3) /* Values for SVMCTL_PARAM. */ #define VMCTL_CLEAR_PAGEFAULT 12 diff --git a/include/minix/ipc.h b/include/minix/ipc.h index c2ab47112..e07cdefb3 100644 --- a/include/minix/ipc.h +++ b/include/minix/ipc.h @@ -168,6 +168,7 @@ int receive(endpoint_t src, message *m_ptr, int *status_ptr); int send(endpoint_t dest, message *m_ptr); int sendnb(endpoint_t dest, message *m_ptr); int senda(asynmsg_t *table, size_t count); +int _minix_kernel_info_struct(struct minix_kerninfo **); int _do_kernel_call(message *m_ptr); diff --git a/include/minix/ipcconst.h b/include/minix/ipcconst.h index acbd7ab12..8dfddd93a 100644 --- a/include/minix/ipcconst.h +++ b/include/minix/ipcconst.h @@ -7,6 +7,7 @@ #define SENDREC 3 /* SEND + RECEIVE */ #define NOTIFY 4 /* asynchronous notify */ #define SENDNB 5 /* nonblocking send */ +#define MINIX_KERNINFO 6 /* request kernel info structure */ #define SENDA 16 /* asynchronous send */ #define IPCNO_HIGHEST SENDA diff --git a/include/minix/param.h b/include/minix/param.h index b4abbfc9c..9e48218e7 100644 --- a/include/minix/param.h +++ b/include/minix/param.h @@ -27,7 +27,7 @@ typedef struct kinfo { char param_buf[MULTIBOOT_PARAM_BUF_SIZE]; /* Minix stuff */ - struct kmessages *kmess; + struct kmessages *kmessages; int do_serial_debug; /* system serial output */ int serial_debug_baud; /* serial baud rate */ int minix_panicing; /* are we panicing? */ diff --git a/include/minix/syslib.h b/include/minix/syslib.h index 141201ac8..8aaf28715 100644 --- a/include/minix/syslib.h +++ b/include/minix/syslib.h @@ -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); /* 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_getloadinfo(dst) sys_getinfo(GET_LOADINFO, dst, 0,0,0) #define sys_getmachine(dst) sys_getinfo(GET_MACHINE, dst, 0,0,0) diff --git a/include/minix/type.h b/include/minix/type.h index c8ee62b26..0f3a27ac8 100644 --- a/include/minix/type.h +++ b/include/minix/type.h @@ -170,5 +170,23 @@ struct k_randomness { } 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 */ diff --git a/kernel/Makefile b/kernel/Makefile index 5801310e6..d385c26d4 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -6,7 +6,7 @@ PROG= kernel .include "arch/${MACHINE_ARCH}/Makefile.inc" 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 diff --git a/kernel/arch/i386/arch_system.c b/kernel/arch/i386/arch_system.c index fd706dd21..6dd62d2e9 100644 --- a/kernel/arch/i386/arch_system.c +++ b/kernel/arch/i386/arch_system.c @@ -182,6 +182,11 @@ void arch_proc_reset(struct proc *pr) 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 failed; diff --git a/kernel/arch/i386/kernel.lds b/kernel/arch/i386/kernel.lds index 98a543d1f..047484128 100644 --- a/kernel/arch/i386/kernel.lds +++ b/kernel/arch/i386/kernel.lds @@ -21,8 +21,14 @@ SECTIONS . += _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*) } .data ALIGN(4096) : AT(ADDR(.data) - _kern_offset) { *(.data .rodata* ) } + . = ALIGN(4096); .bss ALIGN(4096) : AT(ADDR(.bss) - _kern_offset) { *(.bss* COMMON) __k_unpaged__kern_size = . - _kern_vir_base; _kern_size = __k_unpaged__kern_size; diff --git a/kernel/arch/i386/memory.c b/kernel/arch/i386/memory.c index f4033c4f0..78bdb26a7 100644 --- a/kernel/arch/i386/memory.c +++ b/kernel/arch/i386/memory.c @@ -757,10 +757,14 @@ static int oxpcie_mapping_index = -1, lapic_mapping_index = -1, ioapic_first_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 usermapped_start, usermapped_end, usermapped_nonglo_start; + int arch_phys_map(const int index, phys_bytes *addr, phys_bytes *len, @@ -769,9 +773,19 @@ int arch_phys_map(const int index, static int first = 1; int freeidx = 0; static char *ser_var = NULL; + u32_t glo_len = (u32_t) &usermapped_nonglo_start - + (u32_t) &usermapped_start; if(first) { 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 if(lapic_addr) @@ -798,21 +812,34 @@ int arch_phys_map(const int index, first = 0; } -#ifdef USE_APIC - if (index == video_mem_mapping_index) { + if(index == usermapped_glo_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 */ *addr = MULTIBOOT_VIDEO_BUFFER; *len = I386_PAGE_SIZE; - *flags = 0; + *flags = VMMF_WRITE; return OK; } +#ifdef USE_APIC else if (index == lapic_mapping_index) { /* map the local APIC if enabled */ if (!lapic_addr) return EINVAL; *addr = lapic_addr; *len = 4 << 10 /* 4kB */; - *flags = VMMF_UNCACHED; + *flags = VMMF_UNCACHED | VMMF_WRITE; return OK; } 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; assert(*addr); *len = 4 << 10 /* 4kB */; - *flags = VMMF_UNCACHED; + *flags = VMMF_UNCACHED | VMMF_WRITE; printf("ioapic map: addr 0x%lx\n", *addr); return OK; } @@ -830,7 +857,7 @@ int arch_phys_map(const int index, if(index == oxpcie_mapping_index) { *addr = strtoul(ser_var+2, NULL, 16); *len = 0x4000; - *flags = VMMF_UNCACHED; + *flags = VMMF_UNCACHED | VMMF_WRITE; return OK; } #endif @@ -860,6 +887,31 @@ int arch_phys_map_reply(const int index, const vir_bytes addr) return OK; } #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) { video_mem_vaddr = addr; return OK; diff --git a/kernel/arch/i386/pre_init.c b/kernel/arch/i386/pre_init.c index 6dcb7763e..d776ea202 100644 --- a/kernel/arch/i386/pre_init.c +++ b/kernel/arch/i386/pre_init.c @@ -26,7 +26,7 @@ /* to-be-built kinfo struct, diagnostics buffer */ kinfo_t kinfo; -struct kmessages kmess; +struct kmessages kmessages; /* pg_utils.c uses this; in this phase, there is a 1:1 mapping. */ phys_bytes vir2phys(void *addr) { return (phys_bytes) addr; } diff --git a/kernel/glo.h b/kernel/glo.h index 52471c819..8664a0d1b 100644 --- a/kernel/glo.h +++ b/kernel/glo.h @@ -19,11 +19,18 @@ #include "debug.h" /* Kernel information structures. This groups vital kernel information. */ -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 k_randomness krandom; /* gather kernel random information */ -EXTERN struct loadinfo kloadinfo; /* status of load average */ +extern struct kinfo kinfo; /* kernel information for users */ +extern struct machine machine; /* machine information for users */ +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 */ + +vir_bytes minix_kerninfo_user; + +#define kmess kmessages +#define kloadinfo loadinfo /* Process scheduling information and the kernel reentry count. */ EXTERN struct proc *vmrequest; /* first process on vmrequest queue */ diff --git a/kernel/proc.c b/kernel/proc.c index 98bab162e..e89c6ffa8 100644 --- a/kernel/proc.c +++ b/kernel/proc.c @@ -608,6 +608,16 @@ int do_ipc(reg_t r1, reg_t r2, reg_t r3) return EDOM; 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: return EBADCALL; /* illegal system call */ } diff --git a/kernel/proto.h b/kernel/proto.h index 0159fbf71..68f2000eb 100644 --- a/kernel/proto.h +++ b/kernel/proto.h @@ -150,6 +150,7 @@ void stop_profile_clock(void); /* functions defined in architecture-dependent files. */ void prot_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 count); void phys_copy_fault(void); diff --git a/kernel/system/do_getinfo.c b/kernel/system/do_getinfo.c index bf87be9c0..19ab73c14 100644 --- a/kernel/system/do_getinfo.c +++ b/kernel/system/do_getinfo.c @@ -167,11 +167,6 @@ int do_getinfo(struct proc * caller, message * m_ptr) break; } - case GET_KMESSAGES: { - length = sizeof(struct kmessages); - src_vir = (vir_bytes) &kmess; - break; - } case GET_IRQACTIDS: { length = sizeof(irq_actids); src_vir = (vir_bytes) irq_actids; diff --git a/kernel/usermapped_data.c b/kernel/usermapped_data.c new file mode 100644 index 000000000..d95a085cc --- /dev/null +++ b/kernel/usermapped_data.c @@ -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 */ + diff --git a/lib/libc/arch/i386/sys-minix/_ipc.S b/lib/libc/arch/i386/sys-minix/_ipc.S index 5d5d77811..9bfa326f3 100644 --- a/lib/libc/arch/i386/sys-minix/_ipc.S +++ b/lib/libc/arch/i386/sys-minix/_ipc.S @@ -50,6 +50,20 @@ ENTRY(_sendrec) pop %ebp 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) push %ebp movl %esp, %ebp diff --git a/lib/libc/sys-minix/Makefile.inc b/lib/libc/sys-minix/Makefile.inc index 317eef5c7..6f5209701 100644 --- a/lib/libc/sys-minix/Makefile.inc +++ b/lib/libc/sys-minix/Makefile.inc @@ -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\ 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 \ - _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. SRCS+= cprofile.c lseek64.c sprofile.c _mcontext.c diff --git a/lib/libc/sys-minix/init.c b/lib/libc/sys-minix/init.c new file mode 100644 index 000000000..7b21078ca --- /dev/null +++ b/lib/libc/sys-minix/init.c @@ -0,0 +1,16 @@ + +#include +#include + +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; + } +} + diff --git a/lib/libminc/Makefile b/lib/libminc/Makefile index e93e76577..21d84275f 100644 --- a/lib/libminc/Makefile +++ b/lib/libminc/Makefile @@ -131,7 +131,7 @@ CPPFLAGS.${i}+= -I${LIBCSRCDIR}/include -I${LIBCSRCDIR}/locale link.c _mcontext.c mknod.c mmap.c nanosleep.c open.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 \ - 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.S: ${LIBCSRCDIR}/arch/${MACHINE}/sys-minix SRCS+= ${i} diff --git a/servers/is/dmp_kernel.c b/servers/is/dmp_kernel.c index 36f1116f5..e6ee1791f 100644 --- a/servers/is/dmp_kernel.c +++ b/servers/is/dmp_kernel.c @@ -2,6 +2,7 @@ #include "inc.h" #include +#include #include #include #include @@ -54,32 +55,33 @@ struct proc proc[NR_TASKS + NR_PROCS]; struct priv priv[NR_SYS_PROCS]; struct boot_image image[NR_BOOT_PROCS]; +extern struct minix_kerninfo *_minix_kerninfo; + /*===========================================================================* * 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 */ int start; /* calculate start of messages */ int r; + int size; - /* Try to get a copy of the kernel messages. */ - if ((r = sys_getkmessages(&kmess)) != OK) { - printf("IS: warning: couldn't get copy of kmessages: %d\n", r); - return; - } + assert(_minix_kerninfo); + kmess = _minix_kerninfo->kmessages; /* 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 * 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; - while (kmess.km_size > 0) { - print_buf[r] = kmess.km_buf[(start+r) % _KMESS_BUF_SIZE]; + size = kmess->km_size; + while (size > 0) { + print_buf[r] = kmess->km_buf[(start+r) % _KMESS_BUF_SIZE]; r ++; - kmess.km_size --; + size--; } print_buf[r] = 0; /* make sure it terminates */ printf("Dump of all messages generated by the kernel.\n\n"); diff --git a/servers/vm/arch/i386/pagetable.c b/servers/vm/arch/i386/pagetable.c index 00fc0e50a..6831ec3c2 100644 --- a/servers/vm/arch/i386/pagetable.c +++ b/servers/vm/arch/i386/pagetable.c @@ -936,9 +936,15 @@ void pt_init(void) kern_mappings[index].flags = flags; kern_mappings[index].vir_addr = offset; kern_mappings[index].flags = - I386_VM_PRESENT | I386_VM_USER | I386_VM_WRITE; + I386_VM_PRESENT; if(flags & VMMF_UNCACHED) 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) panic("VM: addr unaligned: %d", addr); if(len % I386_PAGE_SIZE) diff --git a/servers/vm/pagefaults.c b/servers/vm/pagefaults.c index 6b2f0ebab..ed789fca1 100644 --- a/servers/vm/pagefaults.c +++ b/servers/vm/pagefaults.c @@ -71,9 +71,14 @@ void do_pagefaults(message *m) /* See if address is valid at all. */ if(!(region = map_lookup(vmp, addr))) { - assert(PFERR_NOPAGE(err)); - printf("VM: pagefault: SIGSEGV %d bad addr 0x%x; %s\n", + 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)); + printf("VM: pagefault: SIGSEGV %d bad addr 0x%x; %s\n", + ep, addr, pf_errstr(err)); + } if((s=sys_kill(vmp->vm_endpoint, SIGSEGV)) != OK) panic("sys_kill failed: %d", s); if((s=sys_vmctl(ep, VMCTL_CLEAR_PAGEFAULT, 0 /*unused*/)) != OK)