]> Zhao Yanbai Git Server - minix.git/commitdiff
No more intel/minix segments.
authorBen Gras <ben@minix3.org>
Mon, 7 May 2012 14:03:35 +0000 (16:03 +0200)
committerBen Gras <ben@minix3.org>
Sun, 15 Jul 2012 20:30:15 +0000 (22:30 +0200)
This commit removes all traces of Minix segments (the text/data/stack
memory map abstraction in the kernel) and significance of Intel segments
(hardware segments like CS, DS that add offsets to all addressing before
page table translation). This ultimately simplifies the memory layout
and addressing and makes the same layout possible on non-Intel
architectures.

There are only two types of addresses in the world now: virtual
and physical; even the kernel and processes have the same virtual
address space. Kernel and user processes can be distinguished at a
glance as processes won't use 0xF0000000 and above.

No static pre-allocated memory sizes exist any more.

Changes to booting:
        . The pre_init.c leaves the kernel and modules exactly as
          they were left by the bootloader in physical memory
        . The kernel starts running using physical addressing,
          loaded at a fixed location given in its linker script by the
          bootloader.  All code and data in this phase are linked to
          this fixed low location.
        . It makes a bootstrap pagetable to map itself to a
          fixed high location (also in linker script) and jumps to
          the high address. All code and data then use this high addressing.
        . All code/data symbols linked at the low addresses is prefixed by
          an objcopy step with __k_unpaged_*, so that that code cannot
          reference highly-linked symbols (which aren't valid yet) or vice
          versa (symbols that aren't valid any more).
        . The two addressing modes are separated in the linker script by
          collecting the unpaged_*.o objects and linking them with low
          addresses, and linking the rest high. Some objects are linked
          twice, once low and once high.
        . The bootstrap phase passes a lot of information (e.g. free memory
          list, physical location of the modules, etc.) using the kinfo
          struct.
        . After this bootstrap the low-linked part is freed.
        . The kernel maps in VM into the bootstrap page table so that VM can
          begin executing. Its first job is to make page tables for all other
          boot processes. So VM runs before RS, and RS gets a fully dynamic,
          VM-managed address space. VM gets its privilege info from RS as usual
          but that happens after RS starts running.
        . Both the kernel loading VM and VM organizing boot processes happen
  using the libexec logic. This removes the last reason for VM to
  still know much about exec() and vm/exec.c is gone.

Further Implementation:
        . All segments are based at 0 and have a 4 GB limit.
        . The kernel is mapped in at the top of the virtual address
          space so as not to constrain the user processes.
        . Processes do not use segments from the LDT at all; there are
          no segments in the LDT any more, so no LLDT is needed.
        . The Minix segments T/D/S are gone and so none of the
          user-space or in-kernel copy functions use them. The copy
          functions use a process endpoint of NONE to realize it's
          a physical address, virtual otherwise.
        . The umap call only makes sense to translate a virtual address
          to a physical address now.
        . Segments-related calls like newmap and alloc_segments are gone.
        . All segments-related translation in VM is gone (vir2map etc).
        . Initialization in VM is simpler as no moving around is necessary.
        . VM and all other boot processes can be linked wherever they wish
          and will be mapped in at the right location by the kernel and VM
          respectively.

Other changes:
        . The multiboot code is less special: it does not use mb_print
          for its diagnostics any more but uses printf() as normal, saving
          the output into the diagnostics buffer, only printing to the
          screen using the direct print functions if a panic() occurs.
        . The multiboot code uses the flexible 'free memory map list'
          style to receive the list of free memory if available.
        . The kernel determines the memory layout of the processes to
          a degree: it tells VM where the kernel starts and ends and
          where the kernel wants the top of the process to be. VM then
          uses this entire range, i.e. the stack is right at the top,
          and mmap()ped bits of memory are placed below that downwards,
          and the break grows upwards.

Other Consequences:
        . Every process gets its own page table as address spaces
          can't be separated any more by segments.
        . As all segments are 0-based, there is no distinction between
          virtual and linear addresses, nor between userspace and
          kernel addresses.
        . Less work is done when context switching, leading to a net
          performance increase. (8% faster on my machine for 'make servers'.)
. The layout and configuration of the GDT makes sysenter and syscall
  possible.

139 files changed:
commands/Makefile
drivers/pci/pci.c
drivers/tty/console.c
include/arch/i386/include/archtypes.h
include/arch/i386/include/interrupt.h
include/arch/i386/include/multiboot.h
include/arch/i386/include/vmparam.h
include/minix/com.h
include/minix/const.h
include/minix/profile.h
include/minix/syslib.h
include/minix/type.h
include/minix/vm.h
kernel/Makefile
kernel/arch/i386/Makefile.inc
kernel/arch/i386/apic.c
kernel/arch/i386/arch_do_vmctl.c
kernel/arch/i386/arch_reset.c [new file with mode: 0644]
kernel/arch/i386/arch_smp.c
kernel/arch/i386/arch_system.c
kernel/arch/i386/direct_tty_utils.c [new file with mode: 0644]
kernel/arch/i386/do_readbios.c
kernel/arch/i386/do_sdevio.c
kernel/arch/i386/exception.c
kernel/arch/i386/head.S [new file with mode: 0644]
kernel/arch/i386/i8259.c
kernel/arch/i386/include/arch_proto.h
kernel/arch/i386/include/arch_watchdog.h
kernel/arch/i386/include/archconst.h
kernel/arch/i386/include/direct_utils.h [new file with mode: 0644]
kernel/arch/i386/kernel.lds
kernel/arch/i386/klib.S
kernel/arch/i386/mb_utils.h [deleted file]
kernel/arch/i386/memory.c
kernel/arch/i386/mpx.S
kernel/arch/i386/multiboot.S [deleted file]
kernel/arch/i386/pg_utils.c [new file with mode: 0644]
kernel/arch/i386/pre_init.c
kernel/arch/i386/procoffsets.cf
kernel/arch/i386/protect.c
kernel/arch/i386/sconst.h
kernel/arch/i386/trampoline.S
kernel/clock.c
kernel/config.h
kernel/const.h
kernel/debug.c
kernel/glo.h
kernel/main.c
kernel/perf.h
kernel/proc.c
kernel/proc.h
kernel/profile.c
kernel/proto.h
kernel/start.c [deleted file]
kernel/system.c
kernel/system.h
kernel/system/Makefile.inc
kernel/system/do_abort.c
kernel/system/do_copy.c
kernel/system/do_exec.c
kernel/system/do_fork.c
kernel/system/do_getinfo.c
kernel/system/do_newmap.c [deleted file]
kernel/system/do_safecopy.c
kernel/system/do_safemap.c
kernel/system/do_trace.c
kernel/system/do_umap_remote.c
kernel/system/do_update.c
kernel/system/do_vmctl.c
kernel/system/do_vumap.c
kernel/table.c
kernel/type.h
kernel/utility.c
lib/libasyn/asyn.h
lib/libaudiodriver/audio_fw.c
lib/libexec/exec_elf.c
lib/libexec/exec_general.c
lib/libexec/libexec.h
lib/libminlib/i386/_cpufeature.c
lib/libsys/Makefile
lib/libsys/alloc_util.c
lib/libsys/env_get_prm.c
lib/libsys/env_parse.c
lib/libsys/kputc.c
lib/libsys/sef.c
lib/libsys/sys_fork.c
lib/libsys/sys_newmap.c [deleted file]
lib/libsys/sys_physcopy.c
lib/libsys/sys_safecopy.c
lib/libsys/sys_safemap.c
lib/libsys/sys_vircopy.c
lib/libsys/sys_vmctl.c
lib/libvassert/vassert.c
servers/init/Makefile
servers/is/dmp.c
servers/is/dmp_kernel.c
servers/is/dmp_vm.c
servers/is/proto.h
servers/pm/exec.c
servers/pm/glo.h
servers/pm/main.c
servers/pm/misc.c
servers/procfs/pid.c
servers/rs/const.h
servers/rs/exec.c
servers/rs/glo.h
servers/rs/main.c
servers/rs/manager.c
servers/vfs/exec.c
servers/vfs/glo.h
servers/vfs/main.c
servers/vfs/table.c
servers/vm/Makefile
servers/vm/alloc.c
servers/vm/arch/i386/Makefile.inc
servers/vm/arch/i386/arch_vmproc.h [deleted file]
servers/vm/arch/i386/memory.h
servers/vm/arch/i386/pagetable.c
servers/vm/arch/i386/vm.c [deleted file]
servers/vm/break.c
servers/vm/exec.c [deleted file]
servers/vm/exit.c
servers/vm/fork.c
servers/vm/glo.h
servers/vm/main.c
servers/vm/mmap.c
servers/vm/pagefaults.c
servers/vm/proto.h
servers/vm/region.c
servers/vm/rs.c
servers/vm/sanitycheck.h
servers/vm/slaballoc.c
servers/vm/utility.c
servers/vm/vmproc.h
share/mk/bsd.prog.mk
share/mk/minix.bootprog.mk
usr.bin/Makefile
usr.bin/mkimage/Makefile [deleted file]
usr.bin/mkimage/mkimage.c [deleted file]

index b4bd668ef93fa8bc918c9462b03dc6437b980b33..6092e6a7f963d39f94592b731f531e01fe5792e9 100644 (file)
@@ -17,7 +17,7 @@ SUBDIR=       add_route arp ash at \
        intr ipcrm ipcs irdpd isoread join kill last \
        less loadkeys loadramdisk logger look lp \
        lpd ls lspci mail MAKEDEV \
-       mdb  mesg mined mkfifo mknod \
+       mesg mined mkfifo mknod \
        mkproto mount mt netconf nice acknm nohup \
        nonamed od paste patch pax \
        ping postinstall poweroff pr prep printf printroot \
index d753faf36c6f038bcc8c3a6899c1504924356fa1..09e64b91c73d2c1e63c011aaa9570d7dc0b65feb 100644 (file)
@@ -1448,38 +1448,16 @@ static void complete_bridges()
  *===========================================================================*/
 static void complete_bars(void)
 {
-       int i, j, r, bar_nr, reg;
+       int i, j, bar_nr, reg;
        u32_t memgap_low, memgap_high, iogap_low, iogap_high, io_high,
                base, size, v32, diff1, diff2;
-       char *cp, *next;
-       char memstr[256];
+       kinfo_t kinfo;
 
-       r= env_get_param("memory", memstr, sizeof(memstr));
-       if (r != OK)
-               panic("env_get_param failed: %d", r);
-       
-       /* Set memgap_low to just above physical memory */
-       memgap_low= 0;
-       cp= memstr;
-       while (*cp != '\0')
-       {
-               base= strtoul(cp, &next, 16);
-               if (!(*next) || next == cp || *next != ':')
-                       goto bad_mem_string;
-               cp= next+1;
-               size= strtoul(cp, &next, 16);
-               if (next == cp || (*next != ',' && *next != '\0'))
-               if (!*next)
-                       goto bad_mem_string;
-               if (base+size > memgap_low)
-                       memgap_low= base+size;
-
-               if (*next)
-                       cp= next+1;
-               else
-                       break;
-       }
+       if(OK != sys_getkinfo(&kinfo))
+               panic("can't get kinfo");
 
+       /* Set memgap_low to just above physical memory */
+       memgap_low= kinfo.mem_high_phys;
        memgap_high= 0xfe000000;        /* Leave space for the CPU (APIC) */
 
        if (debug)
@@ -1661,10 +1639,6 @@ static void complete_bars(void)
                }
        }
        return;
-
-bad_mem_string:
-       printf("PCI: bad memory environment string '%s'\n", memstr);
-       panic(NULL);
 }
 
 /*===========================================================================*
index 05971f634efacdb47d9573a4e0f47cdcc421ecee..023c9449f81cb4036f67b69cb81182c4371e9293 100644 (file)
@@ -971,7 +971,6 @@ tty_t *tp;
        if(font_memory == MAP_FAILED) 
                panic("Console couldn't map font memory");
 
-
        vid_size >>= 1;         /* word count */
        vid_mask = vid_size - 1;
 
@@ -983,6 +982,7 @@ tty_t *tp;
 
        if (nr_cons > NR_CONS) nr_cons = NR_CONS;
        if (nr_cons > 1) wrap = 0;
+       if (nr_cons < 1) panic("no consoles");
        page_size = vid_size / nr_cons;
   }
 
index 75e0f1eea2eceb52125039479fff02f52c6cb62f..62bc5aaaecf15b5fd7fa9f27c18f6df5eece96aa 100644 (file)
@@ -14,24 +14,19 @@ struct segdesc_s {          /* segment descriptor for protected mode */
   u8_t access;         /* |P|DL|1|X|E|R|A| */
   u8_t granularity;    /* |G|X|0|A|LIMT| */
   u8_t base_high;
-};
+} __attribute__((packed));
 
-#define LDT_SIZE 2        /* CS and DS */
-
-/* Fixed local descriptors. */
-#define CS_LDT_INDEX         0  /* process CS */
-#define DS_LDT_INDEX         1  /* process DS=ES=FS=GS=SS */
+struct desctableptr_s {
+  u16_t limit;
+  u32_t base;
+} __attribute__((packed));
 
 typedef struct segframe {
-       reg_t p_ldt_sel;    /* selector in gdt with ldt base and limit */
        reg_t   p_cr3;          /* page table root */
        u32_t   *p_cr3_v;
        char    *fpu_state;
-       struct segdesc_s p_ldt[LDT_SIZE]; /* CS, DS and remote */
 } segframe_t;
 
-#define INMEMORY(p) (!p->p_seg.p_cr3 || get_cpulocal_var(ptproc) == p)
-
 typedef u32_t atomic_t;        /* access to an aligned 32bit value is atomic on i386 */
 
 #endif /* #ifndef _I386_TYPES_H */
index c13a1e422352d43299ca894269b50be30acc0e06..649cc084ab0b9fc38feb2b6c6b7970ee7d240dee 100644 (file)
@@ -14,6 +14,9 @@
 /* Magic numbers for interrupt controller. */
 #define END_OF_INT      0x20   /* code used to re-enable after an interrupt */
 
+#define IRQ0_VECTOR     0x50   /* nice vectors to relocate IRQ0-7 to */
+#define IRQ8_VECTOR     0x70   /* no need to move IRQ8-15 */
+
 /* Interrupt vectors defined/reserved by processor. */
 #define DIVIDE_VECTOR      0   /* divide error */
 #define DEBUG_VECTOR       1   /* single step (trace) */
 #define KERN_CALL_VECTOR  32   /* system calls are made with int SYSVEC */
 #define IPC_VECTOR        33   /* interrupt vector for ipc */
 
-/* Suitable irq bases for hardware interrupts.  Reprogram the 8259(s) from
- * the PC BIOS defaults since the BIOS doesn't respect all the processor's
- * reserved vectors (0 to 31).
- */
-#define BIOS_IRQ0_VEC   0x08   /* base of IRQ0-7 vectors used by BIOS */
-#define BIOS_IRQ8_VEC   0x70   /* base of IRQ8-15 vectors used by BIOS */
-#define IRQ0_VECTOR     0x50   /* nice vectors to relocate IRQ0-7 to */
-#define IRQ8_VECTOR     0x70   /* no need to move IRQ8-15 */
-
 /* Hardware interrupt numbers. */
 #ifndef USE_APIC
 #define NR_IRQ_VECTORS    16
 #define AT_WINI_0_IRQ     14   /* at winchester controller 0 */
 #define AT_WINI_1_IRQ     15   /* at winchester controller 1 */
 
-/* Interrupt number to hardware vector. */
-#define BIOS_VECTOR(irq)       \
-       (((irq) < 8 ? BIOS_IRQ0_VEC : BIOS_IRQ8_VEC) + ((irq) & 0x07))
-#define VECTOR(irq)    \
-       (((irq) < 8 ? IRQ0_VECTOR : IRQ8_VECTOR) + ((irq) & 0x07))
+#define VECTOR(irq)    \
+       (((irq) < 8 ? IRQ0_VECTOR : IRQ8_VECTOR) + ((irq) & 0x07))
 
 #endif /* (CHIP == INTEL) */
 
index df2bafa372606df5dd2d4129f35961bfd30b2ac2..751c5cdba3ae3900873833924d7c53731b31aec4 100644 (file)
@@ -14,8 +14,6 @@
 
 #define MULTIBOOT_AOUT_KLUDGE 0x00010000
 
-#define MULTIBOOT_FLAGS (MULTIBOOT_MEMORY_INFO | MULTIBOOT_PAGE_ALIGN)
-
 /* consts used for Multiboot pre-init */
 
 #define MULTIBOOT_VIDEO_MODE_EGA 1
 #define MULTIBOOT_CONSOLE_LINES 25
 #define MULTIBOOT_CONSOLE_COLS 80
 
+#define MULTIBOOT_VIDEO_BUFFER_BYTES \
+       (MULTIBOOT_CONSOLE_LINES*MULTIBOOT_CONSOLE_COLS*2)
 
 #define MULTIBOOT_STACK_SIZE 4096
 #define MULTIBOOT_PARAM_BUF_SIZE 1024
 
+#define MULTIBOOT_MAX_MODS     20
+
 /* Flags to be set in the â€™flags’ member of the multiboot info structure. */
 
 #define MULTIBOOT_INFO_MEMORY 0x00000001
+#define MULTIBOOT_INFO_MEM_MAP 0x00000040
 
 /* Is there a boot device set? */
 #define MULTIBOOT_INFO_BOOTDEV 0x00000002
@@ -45,6 +48,8 @@
 /* Are there modules to do something with? */
 #define MULTIBOOT_INFO_MODS 0x00000008
 
+#define MULTIBOOT_HIGH_MEM_BASE 0x100000
+
 #ifndef __ASSEMBLY__
 
 #include <minix/types.h>
@@ -73,8 +78,8 @@ struct multiboot_info
        /* Multiboot info version number */
        u32_t flags;
        /* Available memory from BIOS */
-       u32_t mem_lower;
-       u32_t mem_upper;
+       u32_t mem_lower_unused; /* minix uses memmap instead */
+       u32_t mem_upper_unused;
        /* "root" partition */
        u32_t boot_device;
        /* Kernel command line */
@@ -121,8 +126,18 @@ struct multiboot_mod_list
 };
 typedef struct multiboot_mod_list multiboot_module_t;
 
-/* Buffer for multiboot parameters */
-extern char multiboot_param_buf[];
+#define MULTIBOOT_MEMORY_AVAILABLE              1
+#define MULTIBOOT_MEMORY_RESERVED               2
+struct multiboot_mmap_entry
+{
+       u32_t size;
+       u64_t addr;
+       u64_t len;
+#define MULTIBOOT_MEMORY_AVAILABLE              1
+#define MULTIBOOT_MEMORY_RESERVED               2
+       u32_t type;
+} __attribute__((packed));
+typedef struct multiboot_mmap_entry multiboot_memory_map_t;
 
 #endif /* __ASSEMBLY__ */
 #endif /* __MULTIBOOT_H__ */
index a8e217d49fcda850b58c282de6dc53a863ebd690..63aef5c2c0e0c7dc818b3b0d62184b5329908cb6 100644 (file)
@@ -49,9 +49,4 @@
 #define        PAGE_SIZE       (1 << PAGE_SHIFT)
 #define        PAGE_MASK       (PAGE_SIZE - 1)
 
-/* As visible from the user space process, where is the top of the
- * stack (first non-stack byte), when in paged mode?
- */
-#define VM_STACKTOP     0x80000000
-
 #endif /* _I386_VMPARAM_H_ */
index 46242b16e3b734cdcf326d56082dad93e45b9858..d0f091fa681a7b80285ea8a19e2880ff23cdea73 100644 (file)
@@ -89,9 +89,6 @@
 #define ROOT_SYS_PROC_NR  RS_PROC_NR
 #define ROOT_USR_PROC_NR  INIT_PROC_NR
 
-/* Number of processes contained in the system image. */
-#define NR_BOOT_PROCS  (NR_TASKS + LAST_SPECIAL_PROC_NR + 1)
-
 /*===========================================================================*
  *                        Kernel notification types                         *
  *===========================================================================*/
 #  define SYS_SIGSEND    (KERNEL_CALL + 9)     /* sys_sigsend() */
 #  define SYS_SIGRETURN  (KERNEL_CALL + 10)    /* sys_sigreturn() */
 
-#  define SYS_NEWMAP     (KERNEL_CALL + 11)    /* sys_newmap() */
 #  define SYS_MEMSET     (KERNEL_CALL + 13)    /* sys_memset() */
 
 #  define SYS_UMAP       (KERNEL_CALL + 14)    /* sys_umap() */
 #define SIG_MAP        m2_l1   /* used by kernel to pass signal bit map */
 #define SIG_CTXT_PTR   m2_p1   /* pointer to info to restore signal context */
 
-/* Field names for SYS_FORK, _EXEC, _EXIT, _NEWMAP, GETMCONTEXT, SETMCONTEXT.*/
+/* Field names for SYS_FORK, _EXEC, _EXIT, GETMCONTEXT, SETMCONTEXT.*/
 #define PR_ENDPT        m1_i1  /* indicates a process */
 #define PR_PRIORITY     m1_i2  /* process priority */
 #define PR_SLOT         m1_i2  /* indicates a process slot */
 #define PR_STACK_PTR    m1_p1  /* used for stack ptr in sys_exec, sys_getsp */
 #define PR_NAME_PTR     m1_p2  /* tells where program name is for dmp */
 #define PR_IP_PTR       m1_p3  /* initial value for ip after exec */
-#define PR_MEM_PTR      m1_p1  /* tells where memory map is for sys_newmap
-                                * and sys_fork
-                                */
 #define PR_FORK_FLAGS  m1_i3   /* optional flags for fork operation */
 #define PR_FORK_MSGADDR m1_p1  /* reply message address of forked child */
 #define PR_CTX_PTR     m1_p1   /* pointer to mcontext_t structure */
 #define VMCTL_I386_GETCR3      13
 #define VMCTL_MEMREQ_GET       14
 #define VMCTL_MEMREQ_REPLY     15
-#define VMCTL_INCSP            16
 #define VMCTL_NOPAGEZERO       18
 #define VMCTL_I386_KERNELLIMIT 19
-#define VMCTL_I386_FREEPDE     23
-#define VMCTL_ENABLE_PAGING    24
 #define VMCTL_I386_INVLPG      25
 #define VMCTL_FLUSHTLB         26
 #define VMCTL_KERN_PHYSMAP     27
 #define VMCTL_SETADDRSPACE     29
 #define VMCTL_VMINHIBIT_SET    30
 #define VMCTL_VMINHIBIT_CLEAR  31
+#define VMCTL_CLEARMAPCACHE    32
 
 /* Codes and field names for SYS_SYSCTL. */
 #define SYSCTL_CODE            m1_i1   /* SYSCTL_CODE_* below */
 
 /* Parameters for the EXEC_NEWMEM call */
 #define EXC_NM_PROC    m1_i1           /* process that needs new map */
-#define EXC_NM_PTR     m1_p1           /* parameters in struct exec_newmem */
+#define EXC_NM_PTR     m1_p1           /* parameters in struct exec_info */
 /* Results:
  * the status will be in m_type.
  * the top of the stack will be in m1_i1.
index 2342645e5dfc697a665f60c017dd7f8039429531..b52f94e94452d18818ed861d2a5ab87020f78c24 100644 (file)
 #define SEGMENT_TYPE  0xFF00   /* bit mask to get segment type */
 #define SEGMENT_INDEX 0x00FF   /* bit mask to get segment index */
 
-#define LOCAL_SEG     0x0000   /* flags indicating local memory segment */
-#define NR_LOCAL_SEGS      3   /* # local segments per process (fixed) */
-#define T                  0   /* proc[i].mem_map[T] is for text */
-#define D                  1   /* proc[i].mem_map[D] is for data */
-#define S                  2   /* proc[i].mem_map[S] is for stack */
+#define D_OBSOLETE         1   /* proc[i].mem_map[D] is for data */
 
 #define PHYS_SEG      0x0400   /* flag indicating entire physical memory */
 
 #define LOCAL_VM_SEG  0x1000   /* same as LOCAL_SEG, but with vm lookup */
-#define VM_D           (LOCAL_VM_SEG | D)
-#define VM_T           (LOCAL_VM_SEG | T)
 #define MEM_GRANT      3
+#define VIR_ADDR       1
+#define VM_D           (LOCAL_VM_SEG | VIR_ADDR)
 #define VM_GRANT       (LOCAL_VM_SEG | MEM_GRANT)
 
 /* Labels used to disable code sections for different reasons. */
@@ -76,6 +72,9 @@
 #define FUTURE_CODE       0    /* new code to be activated + tested later */
 #define TEMP_CODE         1    /* active code to be removed later */
 
+/* Number of processes contained in the system image. */
+#define NR_BOOT_PROCS   (NR_TASKS + LAST_SPECIAL_PROC_NR + 1)
+
 /* Process name length in the PM process table, including '\0'. */
 #define PROC_NAME_LEN  16
 
 #define SERVARNAME             "cttyline"
 #define SERBAUDVARNAME         "cttybaud"
 
-/* Bits for the system property flags in boot image processes. */
-#define PROC_FULLVM    0x100    /* VM sets and manages full pagetable */
-
 /* Bits for s_flags in the privilege structure. */
 #define PREEMPTIBLE     0x002   /* kernel tasks are not preemptible */
 #define BILLABLE        0x004   /* some processes are not billable */
index aa94dd567946e0e45182936edfa32cae73d4d3ea..c3f5eed4692bfba1bade8689f055e5931663b6c7 100644 (file)
@@ -31,7 +31,7 @@ struct sprof_sample {
 
 struct sprof_proc {
        endpoint_t      proc;
-       char            name[8];
+       char            name[PROC_NAME_LEN];
 };
 
 #include <minix/types.h>
index 90b172934e914bc336090012380e43409f978f2b..141201ac8566f0be43f340c1c9d711b4ca669fcb 100644 (file)
@@ -37,9 +37,8 @@ int sys_abort(int how, ...);
 int sys_enable_iop(endpoint_t proc_ep);
 int sys_exec(endpoint_t proc_ep, char *ptr, char *aout, vir_bytes
        initpc);
-int sys_fork(endpoint_t parent, endpoint_t child, endpoint_t *, struct
-       mem_map *ptr, u32_t vm, vir_bytes *);
-int sys_newmap(endpoint_t proc_ep, struct mem_map *ptr);
+int sys_fork(endpoint_t parent, endpoint_t child, endpoint_t *, 
+       u32_t vm, vir_bytes *);
 int sys_clear(endpoint_t proc_ep);
 int sys_exit(void);
 int sys_trace(int req, endpoint_t proc_ep, long addr, long *data_p);
index 3ed23852e219f7b380c8e14c6a5084a22f99d7c8..094cd50c6ba919d7dc414da9d78dd7d01343960d 100644 (file)
@@ -1,5 +1,6 @@
 #ifndef _TYPE_H
 #define _TYPE_H
+#include <machine/multiboot.h>
 
 #ifndef _MINIX_SYS_CONFIG_H
 #include <minix/sys_config.h>
@@ -9,6 +10,9 @@
 #include <minix/types.h>
 #endif
 
+#include <minix/const.h>
+#include <minix/com.h>
+
 #include <stdint.h>
 
 /* Type definitions. */
@@ -16,39 +20,12 @@ typedef unsigned int vir_clicks;    /*  virtual addr/length in clicks */
 typedef unsigned long phys_bytes;      /* physical addr/length in bytes */
 typedef unsigned int phys_clicks;      /* physical addr/length in clicks */
 typedef int endpoint_t;                        /* process identifier */
-
 typedef int32_t cp_grant_id_t;         /* A grant ID. */
-
-#if (_MINIX_CHIP == _CHIP_INTEL)
 typedef long unsigned int vir_bytes;   /* virtual addresses/lengths in bytes */
-#endif
-
-#if (_MINIX_CHIP == _CHIP_M68000)
-typedef unsigned long vir_bytes;/* virtual addresses and lengths in bytes */
-#endif
-
-#if (_MINIX_CHIP == _CHIP_SPARC)
-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 {
-  endpoint_t proc_nr_e;
-  int segment;
+  endpoint_t proc_nr_e; /* NONE for phys, otherwise process endpoint */
   vir_bytes offset;
 };
 
@@ -99,27 +76,6 @@ struct sigmsg {
   vir_bytes sm_stkptr;         /* user stack pointer */
 };
 
-/* This is used to obtain system information through SYS_GETINFO. */
-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 ramdev_base;      /* boot device from boot image (/dev/boot) */
-  phys_bytes ramdev_size;
-  phys_bytes _params_base;     /* parameters passed by boot monitor */
-  phys_bytes _params_size;
-  int nr_procs;                        /* number of user processes */
-  int nr_tasks;                        /* number of kernel tasks */
-  char release[6];             /* kernel release number */
-  char version[6];             /* kernel version number */
-};
-
 /* Load data accounted every this no. of seconds. */
 #define _LOAD_UNIT_SECS                 6      /* Changing this breaks ABI. */
 
@@ -166,12 +122,55 @@ struct mem_range
        phys_bytes mr_limit;    /* Highest memory address in range */
 };
 
+/* List of boot-time processes set in kernel/table.c. */
+struct boot_image {
+  int proc_nr;                         /* process number to use */
+  char proc_name[PROC_NAME_LEN];        /* name in process table */
+  endpoint_t endpoint;                  /* endpoint number when started */
+  phys_bytes start_addr;               /* Where it's in memory */
+  phys_bytes len;
+};
+
 /* Memory chunks. */
 struct memory {
        phys_bytes      base;
        phys_bytes      size;
 };
 
+/* This is used to obtain system information through SYS_GETINFO. */
+#define MAXMEMMAP 40
+typedef struct kinfo {
+       /* Straight multiboot-provided info */
+        multiboot_info_t        mbi;
+        multiboot_module_t      module_list[MULTIBOOT_MAX_MODS];
+       multiboot_memory_map_t  memmap[MAXMEMMAP]; /* free mem list */
+       phys_bytes              mem_high_phys;
+       int                     mmap_size;
+
+       /* Multiboot-derived */
+        int                     mods_with_kernel; /* no. of mods incl kernel */
+        int                     kern_mod; /* which one is kernel */
+
+       /* Minix stuff, started at bootstrap phase */
+       int                     freepde_start;  /* lowest pde unused kernel pde */
+        char                    param_buf[MULTIBOOT_PARAM_BUF_SIZE];
+
+       /* Minix stuff */
+       struct kmessages *kmess;
+       int do_serial_debug;    /* system serial output */
+       int serial_debug_baud;  /* serial baud rate */
+       int minix_panicing;     /* are we panicing? */
+        vir_bytes               user_sp; /* where does kernel want stack set */
+        vir_bytes               user_end; /* upper proc limit */
+        vir_bytes               vir_kern_start; /* kernel addrspace starts */
+       vir_bytes               bootstrap_start, bootstrap_len;
+       struct boot_image       boot_procs[NR_BOOT_PROCS];
+       int nr_procs;           /* number of user processes */
+       int nr_tasks;           /* number of kernel tasks */
+       char release[6];        /* kernel release number */
+       char version[6];        /* kernel version number */
+} kinfo_t;
+
 #define STATICINIT(v, n) \
        if(!(v)) {      \
                if(!((v) = alloc_contig(sizeof(*(v)) * (n), 0, NULL))) { \
@@ -184,6 +183,8 @@ struct kmessages {
   int km_next;                          /* next index to write */
   int km_size;                          /* current size in buffer */
   char km_buf[_KMESS_BUF_SIZE];          /* buffer for messages */
+  char kmess_buf[80*25];           /* printable copy of message buffer */
+  int blpos;                           /* kmess_buf position */
 };
 
 #include <minix/config.h>
index 4f0978c1b0d6c0058ed8ce34ebab45e12492a2a5..b12e6f2ecbac85c89297c3cec0bf41223cf51200 100644 (file)
@@ -55,7 +55,6 @@ struct vm_usage_info {
 };
 
 struct vm_region_info {
-  int vri_seg;                 /* segment of virtual region (T or D) */
   vir_bytes vri_addr;          /* base address of region */
   vir_bytes vri_length;                /* length of region */
   int vri_prot;                        /* protection flags (PROT_) */
index fb3c22ee07ffb6b264adea8c05c3c1d3c6412352..b46a65efd7a451e8005e9a2e08f1f1e527238939 100644 (file)
@@ -5,16 +5,18 @@ PROG= kernel
 
 .include "arch/${MACHINE_ARCH}/Makefile.inc"
 
-SRCS+= clock.c cpulocals.c interrupt.c main.c proc.c start.c system.c \
+SRCS+= clock.c cpulocals.c interrupt.c main.c proc.c system.c \
        table.c utility.c 
 
-DPADD+=        ${LIBTIMERS} ${LIBSYS} ${LIBEXEC}
+LINKERSCRIPT=${.CURDIR}/arch/${ARCH}/kernel.lds
+
+DPADD+=        ${LIBTIMERS} ${LIBSYS} ${LIBEXEC} $(LINKERSCRIPT)
 LDADD+=        -ltimers -lsys -lexec
 
-CFLAGS += -D__kernel__
+CFLAGS += -D__kernel__ 
 
 CPPFLAGS+= -fno-stack-protector -D_NETBSD_SOURCE
-LDFLAGS+= -T ${.CURDIR}/arch/${MACHINE_ARCH}/kernel.lds
+LDFLAGS+= -T $(LINKERSCRIPT)
 LDFLAGS+= -nostdlib -L${DESTDIR}/${LIBDIR}
 LDADD+= -lminlib
 DPADD+= ${LIBMINLIB}
@@ -87,3 +89,5 @@ extracted-mtype.h: extract-mtype.sh ../include/minix/com.h
 
 clean:
        rm -f extracted-errno.h extracted-mfield.h extracted-mtype.h
+
+
index 172803a195ba95af4a4f645ff956b81a1541d58e..18fbc399a64f6ec712e46979945e2912e25d4729 100644 (file)
@@ -4,10 +4,37 @@
 
 HERE=${.CURDIR}/arch/${MACHINE_ARCH}
 .PATH: ${HERE}
+
+# objects we want unpaged from -lminlib, -lminc
+MINLIB_OBJS_UNPAGED=_cpufeature.o _cpuid.o get_bp.o
+MINC_OBJS_UNPAGED=strcat.o strlen.o memcpy.o strcpy.o strncmp.o memset.o \
+       memmove.o strcmp.o atoi.o ctype_.o _stdfile.o strtol.o _errno.o errno.o
+SYS_OBJS_UNPAGED=kprintf.o vprintf.o assert.o stacktrace.o
+
+# some object files we give a symbol prefix (or namespace) of __k_unpaged_
+# that must live in their own unique namespace.
+#
+.for UNPAGED_OBJ in head.o pre_init.o direct_tty_utils.o io_outb.o \
+       io_inb.o pg_utils.o klib.o utility.o arch_reset.o \
+       $(MINLIB_OBJS_UNPAGED) $(MINC_OBJS_UNPAGED) $(SYS_OBJS_UNPAGED)
+unpaged_${UNPAGED_OBJ}: ${UNPAGED_OBJ}
+       objcopy --prefix-symbols=__k_unpaged_ ${UNPAGED_OBJ} unpaged_${UNPAGED_OBJ}
+UNPAGED_OBJS += unpaged_${UNPAGED_OBJ}
+.endfor
+
+# we have to extract some object files from libminc.a and libminlib.a
+$(MINLIB_OBJS_UNPAGED) $(MINC_OBJS_UNPAGED) $(SYS_OBJS_UNPAGED): $(LIBMINLIB) $(LIBMINC) $(LIBSYS)
+       ar x $(LIBMINLIB) $(MINLIB_OBJS_UNPAGED)
+       ar x $(LIBMINC) $(MINC_OBJS_UNPAGED)
+       ar x $(LIBSYS) $(SYS_OBJS_UNPAGED)
+
 SRCS+= mpx.S arch_clock.c arch_do_vmctl.c arch_system.c \
        do_iopenable.c do_readbios.c do_sdevio.c exception.c i8259.c io_inb.S \
-       io_inl.S io_intr.S io_inw.S io_outb.S io_outl.S io_outw.S klib.S klib16.S memory.c multiboot.S \
-       oxpcie.c pre_init.c protect.c
+       io_inl.S io_intr.S io_inw.S io_outb.S io_outl.S io_outw.S klib.S klib16.S memory.c \
+       oxpcie.c protect.c direct_tty_utils.c arch_reset.c \
+       pg_utils.c
+
+OBJS.kernel+=  ${UNPAGED_OBJS}
 
 .if ${USE_ACPI} != "no"
 SRCS+= acpi.c
@@ -28,7 +55,7 @@ SRCS+= arch_watchdog.c
 CPPFLAGS+= -DUSE_WATCHDOG
 .endif
 
-apic_asm.d klib.d mpx.d: procoffsets.h
+apic_asm.d klib.d mpx.d head.d: procoffsets.h
 
 # It's OK to hardcode the arch as i386 here as this and procoffsets.cf
 # are i386-specific.
index 69f7c4d94f48c23c0f5b3c8fb4616b904dded336..bb342c4b3dae2491c814f94f2fbacdb823b6a809 100644 (file)
@@ -361,8 +361,6 @@ void ioapic_disable_all(void)
 
        apic_idt_init(TRUE); /* reset */
        idt_reload();
-
-       intr_init(INTS_ORIG, 0); /* no auto eoi */
 }
 
 static void ioapic_disable_irq(unsigned irq)
@@ -649,12 +647,12 @@ static int lapic_enable_in_msr(void)
         * update it
         */
        addr = (msr_lo >> 12) | ((msr_hi & 0xf) << 20);
-       if (phys2vir(addr) != (lapic_addr >> 12)) {
+       if (addr != (lapic_addr >> 12)) {
                if (msr_hi & 0xf) {
                        printf("ERROR : APIC address needs more then 32 bits\n");
                        return 0;
                }
-               lapic_addr = phys2vir(msr_lo & ~((1 << 12) - 1));
+               lapic_addr = msr_lo & ~((1 << 12) - 1);
        }
 #endif
 
@@ -848,7 +846,7 @@ static void lapic_set_dummy_handlers(void)
        handler += vect * LAPIC_INTR_DUMMY_HANDLER_SIZE;
        for(; handler < &lapic_intr_dummy_handles_end;
                        handler += LAPIC_INTR_DUMMY_HANDLER_SIZE) {
-               int_gate(vect++, (vir_bytes) handler,
+               int_gate_idt(vect++, (vir_bytes) handler,
                                PRESENT | INT_GATE_TYPE |
                                (INTR_PRIVILEGE << DPL_SHIFT));
        }
@@ -862,14 +860,16 @@ void apic_idt_init(const int reset)
 
        /* Set up idt tables for smp mode.
         */
-       int is_bsp = is_boot_apic(apicid());
+       int is_bsp;
 
        if (reset) {
-               idt_copy_vectors(gate_table_pic);
+               idt_copy_vectors_pic();
                idt_copy_vectors(gate_table_common);
                return;
        }
 
+       is_bsp = is_boot_apic(apicid());
+
 #ifdef APIC_DEBUG
        if (is_bsp)
                printf("APIC debugging is enabled\n");
@@ -880,7 +880,7 @@ void apic_idt_init(const int reset)
        if (ioapic_enabled)
                idt_copy_vectors(gate_table_ioapic);
        else
-               idt_copy_vectors(gate_table_pic);
+               idt_copy_vectors_pic();
 
        idt_copy_vectors(gate_table_common);
 
@@ -899,7 +899,7 @@ void apic_idt_init(const int reset)
        if (is_bsp) {
                BOOT_VERBOSE(printf("Initiating APIC timer handler\n"));
                /* register the timer interrupt handler for this CPU */
-               int_gate(APIC_TIMER_INT_VECTOR, (vir_bytes) lapic_timer_int_handler,
+               int_gate_idt(APIC_TIMER_INT_VECTOR, (vir_bytes) lapic_timer_int_handler,
                                PRESENT | INT_GATE_TYPE | (INTR_PRIVILEGE << DPL_SHIFT));
        }
 
@@ -916,7 +916,7 @@ static int acpi_get_ioapics(struct io_apic * ioa, unsigned * nioa, unsigned max)
                        break;
 
                ioa[n].id = acpi_ioa->id;
-               ioa[n].addr = phys2vir(acpi_ioa->address);
+               ioa[n].addr = acpi_ioa->address;
                ioa[n].paddr = (phys_bytes) acpi_ioa->address;
                ioa[n].gsi_base = acpi_ioa->global_int_base;
                ioa[n].pins = ((ioapic_read(ioa[n].addr,
@@ -936,13 +936,15 @@ int detect_ioapics(void)
 {
        int status;
 
-       if (machine.acpi_rsdp)
+       if (machine.acpi_rsdp) {
                status = acpi_get_ioapics(io_apic, &nioapics, MAX_NR_IOAPICS);
-       else
+       } else {
                status = 0;
+       }
        if (!status) {
                /* try something different like MPS */
        }
+
        return status;
 }
 
@@ -1113,7 +1115,7 @@ int apic_single_cpu_init(void)
        if (!cpu_feature_apic_on_chip())
                return 0;
 
-       lapic_addr = phys2vir(LOCAL_APIC_DEF_ADDR);
+       lapic_addr = LOCAL_APIC_DEF_ADDR;
        ioapic_enabled = 0;
 
        if (!lapic_enable(0)) {
@@ -1234,8 +1236,6 @@ void ioapic_reset_pic(void)
         * master and slave.  */
                outb(0x22, 0x70);
                outb(0x23, 0x00);
-       
-       intr_init(INTS_ORIG, 0); /* no auto eoi */
 }
 
 static void irq_lapic_status(int irq)
index 7a90bf6a75c49a85d6709311b518f666deba1e49..bb134c680a2eb3b1696e348df9a1ceba6eab1967 100644 (file)
@@ -8,10 +8,31 @@
  */
 
 #include "kernel/system.h"
+#include <assert.h>
 #include <minix/type.h>
 
 #include "arch_proto.h"
 
+extern phys_bytes video_mem_vaddr;
+
+extern char *video_mem;
+
+static void setcr3(struct proc *p, u32_t cr3, u32_t *v)
+{
+       /* Set process CR3. */
+       p->p_seg.p_cr3 = cr3;
+       assert(p->p_seg.p_cr3);
+       p->p_seg.p_cr3_v = v; 
+       if(p == get_cpulocal_var(ptproc)) {
+               write_cr3(p->p_seg.p_cr3);
+       }
+       if(p->p_nr == VM_PROC_NR) {
+               if (arch_enable_paging(p) != OK)
+                       panic("arch_enable_paging failed");
+       }
+       RTS_UNSET(p, RTS_VMINHIBIT);
+}
+
 /*===========================================================================*
  *                             arch_do_vmctl                                *
  *===========================================================================*/
@@ -25,37 +46,8 @@ struct proc *p;
                m_ptr->SVMCTL_VALUE = p->p_seg.p_cr3;
                return OK;
        case VMCTL_SETADDRSPACE:
-               /* Set process CR3. */
-               if(m_ptr->SVMCTL_PTROOT) {
-                       p->p_seg.p_cr3 = m_ptr->SVMCTL_PTROOT;
-                       p->p_seg.p_cr3_v = (u32_t *) m_ptr->SVMCTL_PTROOT_V;
-                       p->p_misc_flags |= MF_FULLVM;
-                       if(p == get_cpulocal_var(ptproc)) {
-                               write_cr3(p->p_seg.p_cr3);
-                       }
-               } else {
-                       p->p_seg.p_cr3 = 0;
-                       p->p_seg.p_cr3_v = NULL;
-                       p->p_misc_flags &= ~MF_FULLVM;
-               }
-               RTS_UNSET(p, RTS_VMINHIBIT);
+               setcr3(p, m_ptr->SVMCTL_PTROOT, (u32_t *) m_ptr->SVMCTL_PTROOT_V);
                return OK;
-       case VMCTL_INCSP:
-               /* Increase process SP. */
-               p->p_reg.sp += m_ptr->SVMCTL_VALUE;
-               return OK;
-       case VMCTL_I386_KERNELLIMIT:
-       {
-               int r;
-               /* VM wants kernel to increase its segment. */
-               r = prot_set_kern_seg_limit(m_ptr->SVMCTL_VALUE);
-               return r;
-       }
-       case VMCTL_I386_FREEPDE:
-       {
-               i386_freepde(m_ptr->SVMCTL_VALUE);
-               return OK;
-       }
        case VMCTL_FLUSHTLB:
        {
                reload_cr3();
@@ -66,7 +58,6 @@ struct proc *p;
                i386_invlpg(m_ptr->SVMCTL_VALUE);
                return OK;
        }
-
   }
 
 
diff --git a/kernel/arch/i386/arch_reset.c b/kernel/arch/i386/arch_reset.c
new file mode 100644 (file)
index 0000000..7891abe
--- /dev/null
@@ -0,0 +1,154 @@
+
+#include "kernel/kernel.h"
+
+#include <unistd.h>
+#include <ctype.h>
+#include <string.h>
+#include <machine/cmos.h>
+#include <machine/bios.h>
+#include <machine/cpu.h>
+#include <minix/portio.h>
+#include <minix/cpufeature.h>
+#include <assert.h>
+#include <signal.h>
+#include <machine/vm.h>
+
+#include <minix/u64.h>
+
+#include "archconst.h"
+#include "arch_proto.h"
+#include "serial.h"
+#include "oxpcie.h"
+#include "kernel/proc.h"
+#include "kernel/debug.h"
+#include "direct_utils.h"
+#include <machine/multiboot.h>
+
+#define     KBCMDP          4       /* kbd controller port (O) */
+#define      KBC_PULSE0     0xfe    /* pulse output bit 0 */
+#define      IO_KBD          0x060           /* 8042 Keyboard */
+
+int cpu_has_tsc;
+
+void
+reset(void)
+{
+        uint8_t b;
+        /*
+         * The keyboard controller has 4 random output pins, one of which is
+         * connected to the RESET pin on the CPU in many PCs.  We tell the
+         * keyboard controller to pulse this line a couple of times.
+         */
+        outb(IO_KBD + KBCMDP, KBC_PULSE0);
+        busy_delay_ms(100);
+        outb(IO_KBD + KBCMDP, KBC_PULSE0);
+        busy_delay_ms(100);
+
+        /*
+         * Attempt to force a reset via the Reset Control register at
+         * I/O port 0xcf9.  Bit 2 forces a system reset when it
+         * transitions from 0 to 1.  Bit 1 selects the type of reset
+         * to attempt: 0 selects a "soft" reset, and 1 selects a
+         * "hard" reset.  We try a "hard" reset.  The first write sets
+         * bit 1 to select a "hard" reset and clears bit 2.  The
+         * second write forces a 0 -> 1 transition in bit 2 to trigger
+         * a reset.
+         */
+        outb(0xcf9, 0x2);
+        outb(0xcf9, 0x6);
+        busy_delay_ms(500);  /* wait 0.5 sec to see if that did it */
+
+        /*
+         * Attempt to force a reset via the Fast A20 and Init register
+         * at I/O port 0x92.  Bit 1 serves as an alternate A20 gate.
+         * Bit 0 asserts INIT# when set to 1.  We are careful to only
+         * preserve bit 1 while setting bit 0.  We also must clear bit
+         * 0 before setting it if it isn't already clear.
+         */
+        b = inb(0x92);
+        if (b != 0xff) {
+                if ((b & 0x1) != 0)
+                        outb(0x92, b & 0xfe);
+                outb(0x92, b | 0x1);
+                busy_delay_ms(500);  /* wait 0.5 sec to see if that did it */
+        }
+
+       /* Triple fault */
+       x86_triplefault();
+
+       /* Give up on resetting */
+       while(1) {
+               ;
+       }
+}
+
+__dead void arch_shutdown(int how)
+{
+       unsigned char unused_ch;
+       /* Mask all interrupts, including the clock. */
+       outb( INT_CTLMASK, ~0);
+
+       /* Empty buffer */
+       while(direct_read_char(&unused_ch))
+               ;
+
+       if(kinfo.minix_panicing) {
+               /* Printing is done synchronously over serial. */
+               if (kinfo.do_serial_debug)
+                       reset();
+
+               /* Print accumulated diagnostics buffer and reset. */
+               direct_cls();
+               direct_print("Minix panic. System diagnostics buffer:\n\n");
+               direct_print(kmess.kmess_buf);
+               direct_print("\nSystem has panicked, press any key to reboot");
+               while (!direct_read_char(&unused_ch))
+                       ;
+               reset();
+       }
+
+       if (how == RBT_DEFAULT) {
+               how = RBT_RESET;
+       }
+
+       switch (how) {
+               case RBT_HALT:
+                       /* Stop */
+                       for (; ; ) halt_cpu();
+                       NOT_REACHABLE;
+
+               default:        
+               case RBT_REBOOT:
+               case RBT_RESET:
+                       /* Reset the system by forcing a processor shutdown. 
+                        * First stop the BIOS memory test by setting a soft
+                        * reset flag.
+                        */
+                       reset();
+                       NOT_REACHABLE;
+       }
+
+       NOT_REACHABLE;
+}
+
+#ifdef DEBUG_SERIAL
+void ser_putc(char c)
+{
+        int i;
+        int lsr, thr;
+
+#if CONFIG_OXPCIE
+        oxpcie_putc(c);
+#else
+        lsr= COM1_LSR;
+        thr= COM1_THR;
+        for (i= 0; i<100000; i++)
+        {
+                if (inb( lsr) & LSR_THRE)
+                        break;
+        }
+        outb( thr, c);
+#endif
+}
+
+#endif
index 3cb9aed714417163cc65f0ce0878d30733b9f23b..83a3b0b7e9688feb57a4907e4788c4df561209f7 100644 (file)
@@ -32,7 +32,7 @@ void trampoline(void);
  * 16-bit mode
  */
 extern volatile u32_t __ap_id;
-extern volatile struct segdesc_s __ap_gdt, __ap_idt;
+extern volatile struct desctableptr_s __ap_gdt, __ap_idt;
 extern void * __trampoline_end;
 
 extern u32_t busclock[CONFIG_MAX_CPUS];
@@ -93,6 +93,8 @@ static phys_bytes copy_trampoline(void)
        return tramp_base;
 }
 
+extern struct desctableptr_s gdt_desc, idt_desc;
+
 static void smp_start_aps(void)
 {
        /* 
@@ -111,8 +113,8 @@ static void smp_start_aps(void)
        outb(RTC_IO, 0xA);
 
        /* prepare gdt and idt for the new cpus */
-       __ap_gdt = gdt[GDT_INDEX];
-       __ap_idt = gdt[IDT_INDEX];
+       __ap_gdt = gdt_desc;
+       __ap_idt = idt_desc;
 
        if (!(trampoline_base = copy_trampoline())) {
                printf("Copying trampoline code failed, cannot boot SMP\n");
@@ -136,7 +138,8 @@ static void smp_start_aps(void)
                }
 
                __ap_id = cpu;
-               phys_copy(vir2phys(__ap_id), __ap_id_phys, sizeof(__ap_id));
+               phys_copy(vir2phys((void *) &__ap_id),
+                       __ap_id_phys, sizeof(__ap_id));
                mfence();
                if (apic_send_init_ipi(cpu, trampoline_base) ||
                                apic_send_startup_ipi(cpu, trampoline_base)) {
@@ -216,7 +219,7 @@ static void ap_finish_booting(void)
        /* inform the world of our presence. */
        ap_cpu_ready = cpu;
 
-       while(!i386_paging_enabled)
+       while(!bootstrap_pagetable_done)
                arch_pause();
 
        /*
@@ -232,7 +235,8 @@ static void ap_finish_booting(void)
         * we must load some page tables befre we turn paging on. As VM is
         * always present we use those
         */
-       segmentation2paging(proc_addr(VM_PROC_NR));
+       pg_load();              /* load bootstrap pagetable built by BSP */
+       vm_enable_paging();
        
        printf("CPU %d paging is on\n", cpu);
 
@@ -301,7 +305,7 @@ void smp_init (void)
                goto uniproc_fallback;
        }
 
-       lapic_addr = phys2vir(LOCAL_APIC_DEF_ADDR);
+       lapic_addr = LOCAL_APIC_DEF_ADDR;
        ioapic_enabled = 0;
 
        tss_init_all();
@@ -347,7 +351,7 @@ uniproc_fallback:
        apic_idt_init(1); /* Reset to PIC idt ! */
        idt_reload();
        smp_reinit_vars (); /* revert to a single proc system. */
-       intr_init (INTS_MINIX, 0); /* no auto eoi */
+       intr_init(0); /* no auto eoi */
        printf("WARNING : SMP initialization failed\n");
 }
        
index 0f3e1cf140f1c51a149846e0eabb14608457b5a8..fd706dd212197df80e25af27fbaaf4de34d7eade 100644 (file)
@@ -21,7 +21,7 @@
 #include "oxpcie.h"
 #include "kernel/proc.h"
 #include "kernel/debug.h"
-#include "mb_utils.h"
+#include "direct_utils.h"
 #include <machine/multiboot.h>
 
 #include "glo.h"
 
 static int osfxsr_feature; /* FXSAVE/FXRSTOR instructions support (SSEx) */
 
-extern __dead void poweroff_jmp();
-extern void poweroff16();
-extern void poweroff16_end();
-
 /* set MP and NE flags to handle FPU exceptions in native mode. */
 #define CR0_MP_NE      0x0022
 /* set CR4.OSFXSR[bit 9] if FXSR is supported. */
@@ -57,142 +53,6 @@ static void ser_dump_proc_cpu(void);
 static void ser_init(void);
 #endif
 
-#define     KBCMDP          4       /* kbd controller port (O) */
-#define      KBC_PULSE0     0xfe    /* pulse output bit 0 */
-#define      IO_KBD          0x060           /* 8042 Keyboard */
-
-void
-reset(void)
-{
-        uint8_t b;
-        /*
-         * The keyboard controller has 4 random output pins, one of which is
-         * connected to the RESET pin on the CPU in many PCs.  We tell the
-         * keyboard controller to pulse this line a couple of times.
-         */
-        outb(IO_KBD + KBCMDP, KBC_PULSE0);
-        busy_delay_ms(100);
-        outb(IO_KBD + KBCMDP, KBC_PULSE0);
-        busy_delay_ms(100);
-
-        /*
-         * Attempt to force a reset via the Reset Control register at
-         * I/O port 0xcf9.  Bit 2 forces a system reset when it
-         * transitions from 0 to 1.  Bit 1 selects the type of reset
-         * to attempt: 0 selects a "soft" reset, and 1 selects a
-         * "hard" reset.  We try a "hard" reset.  The first write sets
-         * bit 1 to select a "hard" reset and clears bit 2.  The
-         * second write forces a 0 -> 1 transition in bit 2 to trigger
-         * a reset.
-         */
-        outb(0xcf9, 0x2);
-        outb(0xcf9, 0x6);
-        busy_delay_ms(500);  /* wait 0.5 sec to see if that did it */
-
-        /*
-         * Attempt to force a reset via the Fast A20 and Init register
-         * at I/O port 0x92.  Bit 1 serves as an alternate A20 gate.
-         * Bit 0 asserts INIT# when set to 1.  We are careful to only
-         * preserve bit 1 while setting bit 0.  We also must clear bit
-         * 0 before setting it if it isn't already clear.
-         */
-        b = inb(0x92);
-        if (b != 0xff) {
-                if ((b & 0x1) != 0)
-                        outb(0x92, b & 0xfe);
-                outb(0x92, b | 0x1);
-                busy_delay_ms(500);  /* wait 0.5 sec to see if that did it */
-        }
-
-       /* Triple fault */
-       x86_triplefault();
-
-       /* Give up on resetting */
-       while(1) {
-               ;
-       }
-}
-
-static __dead void arch_bios_poweroff(void)
-{
-       u32_t cr0;
-       
-       /* Disable paging */
-       cr0 = read_cr0();
-       cr0 &= ~I386_CR0_PG;
-       write_cr0(cr0);
-       /* Copy 16-bit poweroff code to below 1M */
-       phys_copy(
-               (u32_t)&poweroff16,
-               BIOS_POWEROFF_ENTRY,
-               (u32_t)&poweroff16_end-(u32_t)&poweroff16);
-       poweroff_jmp();
-}
-
-int cpu_has_tsc;
-
-__dead void arch_shutdown(int how)
-{
-       vm_stop();
-
-       /* Mask all interrupts, including the clock. */
-       outb( INT_CTLMASK, ~0);
-
-       if(minix_panicing) {
-               unsigned char unused_ch;
-               /* We're panicing? Then retrieve and decode currently
-                * loaded segment selectors.
-                */
-               printseg("cs: ", 1, get_cpulocal_var(proc_ptr), read_cs());
-               printseg("ds: ", 0, get_cpulocal_var(proc_ptr), read_ds());
-               if(read_ds() != read_ss()) {
-                       printseg("ss: ", 0, NULL, read_ss());
-               }
-
-               /* Printing is done synchronously over serial. */
-               if (do_serial_debug)
-                       reset();
-
-               /* Print accumulated diagnostics buffer and reset. */
-               mb_cls();
-               mb_print("Minix panic. System diagnostics buffer:\n\n");
-               mb_print(kmess_buf);
-               mb_print("\nSystem has panicked, press any key to reboot");
-               while (!mb_read_char(&unused_ch))
-                       ;
-               reset();
-       }
-
-       if (how == RBT_DEFAULT) {
-               how = RBT_RESET;
-       }
-
-       switch (how) {
-
-               case RBT_HALT:
-                       /* Poweroff without boot monitor */
-                       arch_bios_poweroff();
-                       NOT_REACHABLE;
-
-               case RBT_PANIC:
-                       /* Allow user to read panic message */
-                       for (; ; ) halt_cpu();
-                       NOT_REACHABLE;
-
-               default:        
-               case RBT_REBOOT:
-               case RBT_RESET:
-                       /* Reset the system by forcing a processor shutdown. 
-                        * First stop the BIOS memory test by setting a soft
-                        * reset flag.
-                        */
-                       reset();
-                       NOT_REACHABLE;
-       }
-
-       NOT_REACHABLE;
-}
-
 void fpu_init(void)
 {
        unsigned short cw, sw;
@@ -288,19 +148,38 @@ void save_fpu(struct proc *pr)
  */
 static char fpu_state[NR_PROCS][FPU_XFP_SIZE] __aligned(FPUALIGN);
 
-void arch_proc_init(int nr, struct proc *pr)
+void arch_proc_reset(struct proc *pr)
 {
-       if(nr < 0) return;
-       char *v;
+       char *v = NULL;
 
-       assert(nr < NR_PROCS);
+       assert(pr->p_nr < NR_PROCS);
 
-       v = fpu_state[nr];
+       if(pr->p_nr >= 0) {
+               v = fpu_state[pr->p_nr];
+               /* verify alignment */
+               assert(!((vir_bytes)v % FPUALIGN));
+               /* initialize state */
+               memset(v, 0, FPU_XFP_SIZE);
+       }
+
+       /* Clear process state. */
+        memset(&pr->p_reg, 0, sizeof(pr->p_reg));
+        if(iskerneln(pr->p_nr))
+               pr->p_reg.psw = INIT_TASK_PSW;
+        else
+               pr->p_reg.psw = INIT_PSW;
 
-       /* verify alignment */
-       assert(!((vir_bytes)v % FPUALIGN));
-       
        pr->p_seg.fpu_state = v;
+
+       /* Initialize the fundamentals that are (initially) the same for all
+        * processes - the segment selectors it gets to use.
+        */
+       pr->p_reg.cs = USER_CS_SELECTOR;
+       pr->p_reg.gs = 
+       pr->p_reg.fs = 
+       pr->p_reg.ss = 
+       pr->p_reg.es = 
+       pr->p_reg.ds = USER_DS_SELECTOR;
 }
 
 int restore_fpu(struct proc *pr)
@@ -362,18 +241,6 @@ void cpu_identify(void)
 
 void arch_init(void)
 {
-#ifdef USE_APIC
-       /*
-        * this is setting kernel segments to cover most of the phys memory. The
-        * value is high enough to reach local APIC nad IOAPICs before paging is
-        * turned on.
-        */
-       prot_set_kern_seg_limit(0xfff00000);
-       reload_ds();
-#endif
-
-       idt_init();
-
        /* FIXME stupid a.out
         * align the stacks in the stack are to the K_STACK_SIZE which is a
         * power of 2
@@ -405,29 +272,12 @@ void arch_init(void)
                BOOT_VERBOSE(printf("APIC not present, using legacy PIC\n"));
        }
 #endif
-}
 
-#ifdef DEBUG_SERIAL
-void ser_putc(char c)
-{
-        int i;
-        int lsr, thr;
-
-#if CONFIG_OXPCIE
-       oxpcie_putc(c);
-#else
-        lsr= COM1_LSR;
-        thr= COM1_THR;
-        for (i= 0; i<100000; i++)
-        {
-                if (inb( lsr) & LSR_THRE)
-                        break;
-        }
-        outb( thr, c);
-#endif
+       /* Reserve some BIOS ranges */
+       cut_memmap(&kinfo, BIOS_MEM_BEGIN, BIOS_MEM_END);
+       cut_memmap(&kinfo, BASE_MEM_TOP, UPPER_MEM_END);
 }
 
-
 /*===========================================================================*
  *                             do_ser_debug                                 * 
  *===========================================================================*/
@@ -484,22 +334,6 @@ static void ser_dump_queues(void)
 #endif
 }
 
-static void ser_dump_segs(void)
-{
-       struct proc *pp;
-       for (pp= BEG_PROC_ADDR; pp < END_PROC_ADDR; pp++)
-       {
-               if (isemptyp(pp))
-                       continue;
-               printf("%d: %s ep %d\n", proc_nr(pp), pp->p_name, pp->p_endpoint);
-               printseg("cs: ", 1, pp, pp->p_reg.cs);
-               printseg("ds: ", 0, pp, pp->p_reg.ds);
-               if(pp->p_reg.ss != pp->p_reg.ds) {
-                       printseg("ss: ", 0, pp, pp->p_reg.ss);
-               }
-       }
-}
-
 #ifdef CONFIG_SMP
 static void dump_bkl_usage(void)
 {
@@ -548,9 +382,6 @@ static void ser_debug(const int c)
        case '2':
                ser_dump_queues();
                break;
-       case '3':
-               ser_dump_segs();
-               break;
 #ifdef CONFIG_SMP
        case '4':
                ser_dump_proc_cpu();
@@ -580,6 +411,7 @@ static void ser_debug(const int c)
        serial_debug_active = 0;
 }
 
+#if DEBUG_SERIAL
 void ser_dump_proc()
 {
        struct proc *pp;
@@ -650,25 +482,6 @@ void arch_ack_profile_clock(void)
 
 #endif
 
-/* Saved by mpx386.s into these variables. */
-u32_t params_size, params_offset, mon_ds;
-
-int arch_get_params(char *params, int maxsize)
-{
-       phys_copy(seg2phys(mon_ds) + params_offset, vir2phys(params),
-               MIN(maxsize, params_size));
-       params[maxsize-1] = '\0';
-       return OK;
-}
-
-int arch_set_params(char *params, int size)
-{
-       if(size > params_size)
-               return E2BIG;
-       phys_copy(vir2phys(params), seg2phys(mon_ds) + params_offset, size);
-       return OK;
-}
-
 void arch_do_syscall(struct proc *proc)
 {
   /* do_ipc assumes that it's running because of the current process */
@@ -691,6 +504,12 @@ struct proc * arch_finish_switch_to_user(void)
        /* set pointer to the process to run on the stack */
        p = get_cpulocal_var(proc_ptr);
        *((reg_t *)stk) = (reg_t) p;
+
+       /* make sure IF is on in FLAGS so that interrupts won't be disabled
+        * once p's context is restored. this should not be possible.
+        */
+        assert(p->p_reg.psw & (1L << 9));
+
        return p;
 }
 
@@ -734,14 +553,14 @@ static void ser_init(void)
        unsigned divisor;
 
        /* keep BIOS settings if cttybaud is not set */
-       if (serial_debug_baud <= 0) return;
+       if (kinfo.serial_debug_baud <= 0) return;
 
        /* set DLAB to make baud accessible */
        lcr = LCR_8BIT | LCR_1STOP | LCR_NPAR;
        outb(COM1_LCR, lcr | LCR_DLAB);
 
        /* set baud rate */
-       divisor = UART_BASE_FREQ / serial_debug_baud;
+       divisor = UART_BASE_FREQ / kinfo.serial_debug_baud;
        if (divisor < 1) divisor = 1;
        if (divisor > 65535) divisor = 65535;
        
diff --git a/kernel/arch/i386/direct_tty_utils.c b/kernel/arch/i386/direct_tty_utils.c
new file mode 100644 (file)
index 0000000..873cfa7
--- /dev/null
@@ -0,0 +1,140 @@
+
+#include "kernel.h"
+#include <minix/minlib.h>
+#include <minix/const.h>
+#include <minix/cpufeature.h>
+#include <minix/types.h>
+#include <minix/type.h>
+#include <minix/com.h>
+#include <sys/param.h>
+#include <machine/partition.h>
+#include <libexec.h>
+#include "string.h"
+#include "arch_proto.h"
+#include "libexec.h"
+#include "direct_utils.h"
+#include "serial.h"
+#include "glo.h"
+#include <machine/multiboot.h>
+
+/* Give non-zero values to avoid them in BSS */
+static int print_line = 1, print_col = 1;
+
+#include <sys/video.h>
+
+extern char *video_mem;
+#define VIDOFFSET(line, col) ((line) * MULTIBOOT_CONSOLE_COLS * 2 + (col) * 2)
+#define VIDSIZE VIDOFFSET(MULTIBOOT_CONSOLE_LINES-1,MULTIBOOT_CONSOLE_COLS-1)
+
+void direct_put_char(char c, int line, int col) 
+{
+       int offset = VIDOFFSET(line, col);
+       video_mem[offset] = c;
+       video_mem[offset+1] = 0x07;     /* grey-on-black */
+}
+
+static char direct_get_char(int line, int col) 
+{
+       return video_mem[VIDOFFSET(line, col)];
+}
+
+void direct_cls(void)
+{
+       /* Clear screen */
+       int i,j;
+
+       for(i = 0; i < MULTIBOOT_CONSOLE_COLS; i++)
+               for(j = 0; j < MULTIBOOT_CONSOLE_LINES; j++)
+                       direct_put_char(' ', j, i);
+
+       print_line = print_col = 0;
+
+       /* Tell video hardware origin is 0. */
+       outb(C_6845+INDEX, VID_ORG);
+       outb(C_6845+DATA, 0);
+       outb(C_6845+INDEX, VID_ORG+1);
+       outb(C_6845+DATA, 0);
+}
+
+static void direct_scroll_up(int lines) 
+{
+       int i, j;
+       for (i = 0; i < MULTIBOOT_CONSOLE_LINES; i++ ) {
+               for (j = 0; j < MULTIBOOT_CONSOLE_COLS; j++ ) {
+                       char c = 0;
+                       if(i < MULTIBOOT_CONSOLE_LINES-lines)
+                               c = direct_get_char(i + lines, j);
+                       direct_put_char(c, i, j);
+               }
+       }
+       print_line-= lines;
+}
+
+void direct_print_char(char c)
+{
+       while (print_line >= MULTIBOOT_CONSOLE_LINES)
+               direct_scroll_up(1);
+
+#define TABWIDTH 8
+       if(c == '\t') {
+               if(print_col >= MULTIBOOT_CONSOLE_COLS - TABWIDTH) {
+                       c = '\n';
+               } else {
+                       do {
+                               direct_put_char(' ', print_line, print_col++);
+                       } while(print_col % TABWIDTH);
+                       return;
+               }
+       }
+
+       if (c == '\n') {
+               while (print_col < MULTIBOOT_CONSOLE_COLS)
+                       direct_put_char(' ', print_line, print_col++);
+               print_line++;
+               print_col = 0;
+               return;
+       }
+
+       direct_put_char(c, print_line, print_col++);
+
+       if (print_col >= MULTIBOOT_CONSOLE_COLS) {
+               print_line++;
+               print_col = 0;
+       }
+
+       while (print_line >= MULTIBOOT_CONSOLE_LINES)
+               direct_scroll_up(1);
+}
+
+void direct_print(const char *str)
+{
+       while (*str) {
+               direct_print_char(*str);
+               str++;
+       }
+}
+
+/* Standard and AT keyboard.  (PS/2 MCA implies AT throughout.) */
+#define KEYBD          0x60    /* I/O port for keyboard data */
+#define KB_STATUS      0x64    /* I/O port for status on AT */
+#define KB_OUT_FULL    0x01    /* status bit set when keypress char pending */
+#define KB_AUX_BYTE    0x20    /* Auxiliary Device Output Buffer Full */
+
+int direct_read_char(unsigned char *ch)
+{
+       unsigned long b, sb;
+
+       sb = inb(KB_STATUS);
+
+       if (!(sb & KB_OUT_FULL)) {
+               return 0;
+       }
+
+       b = inb(KEYBD);
+
+       if (!(sb & KB_AUX_BYTE))
+               return 1;
+
+       return 0;
+}
+
index e8cb08725e57908767b8c421fc2380ac73d28916..3f162570fe44ff691dfdfb547720dd84634151f6 100644 (file)
@@ -18,8 +18,6 @@ int do_readbios(struct proc * caller, message * m_ptr)
   struct vir_addr src, dst;
   vir_bytes len = m_ptr->RDB_SIZE, limit;
 
-  src.segment = PHYS_SEG;
-  dst.segment = D;
   src.offset = m_ptr->RDB_ADDR;
   dst.offset = (vir_bytes) m_ptr->RDB_BUF;
   src.proc_nr_e = NONE;
index 2f3e0822ddd7d06dbbecb64cf4babf10499a2db2..d71056bea77ec3fd5451a3cd76da430fa4dd3227 100644 (file)
@@ -29,7 +29,7 @@ int do_sdevio(struct proc * caller, message *m_ptr)
   endpoint_t proc_nr_e = m_ptr->DIO_VEC_ENDPT;
   vir_bytes count = m_ptr->DIO_VEC_SIZE;
   long port = m_ptr->DIO_PORT;
-  phys_bytes phys_buf;
+  phys_bytes vir_buf;
   int i, req_type, req_dir, size, nr_io_range;
   struct priv *privp;
   struct io_range *iorp;
@@ -79,11 +79,7 @@ int do_sdevio(struct proc * caller, message *m_ptr)
        if(!isokendpt(newep, &proc_nr))
                return(EINVAL);
      destproc = proc_addr(proc_nr);
-     if ((phys_buf = umap_local(destproc, D,
-        (vir_bytes) newoffset, count)) == 0) {
-       printf("do_sdevio: umap_local failed\n");
-         return(EFAULT);
-     }
+     vir_buf = newoffset;
   } else {
      if(proc_nr != _ENDPOINT_P(caller->p_endpoint))
      {
@@ -92,9 +88,7 @@ int do_sdevio(struct proc * caller, message *m_ptr)
        return EPERM;
      }
      /* Get and check physical address. */
-     if ((phys_buf = umap_local(proc_addr(proc_nr), D,
-        (vir_bytes) m_ptr->DIO_VEC_ADDR, count)) == 0)
-         return(EFAULT);
+     vir_buf = (phys_bytes) m_ptr->DIO_VEC_ADDR;
      destproc = proc_addr(proc_nr);
   }
      /* current process must be target for phys_* to be OK */
@@ -139,16 +133,16 @@ int do_sdevio(struct proc * caller, message *m_ptr)
   /* Perform device I/O for bytes and words. Longs are not supported. */
   if (req_dir == _DIO_INPUT) { 
       switch (req_type) {
-      case _DIO_BYTE: phys_insb(port, phys_buf, count); break; 
-      case _DIO_WORD: phys_insw(port, phys_buf, count); break; 
+      case _DIO_BYTE: phys_insb(port, vir_buf, count); break; 
+      case _DIO_WORD: phys_insw(port, vir_buf, count); break; 
       default:
                retval = EINVAL;
                goto return_error;
       } 
   } else if (req_dir == _DIO_OUTPUT) { 
       switch (req_type) {
-      case _DIO_BYTE: phys_outsb(port, phys_buf, count); break; 
-      case _DIO_WORD: phys_outsw(port, phys_buf, count); break; 
+      case _DIO_BYTE: phys_outsb(port, vir_buf, count); break; 
+      case _DIO_WORD: phys_outsw(port, vir_buf, count); break; 
       default:
                retval = EINVAL;
                goto return_error;
index e0a8fae26982cc62db8c86eab7ebe512564a1af9..8611c81ce2c08c18e5717bebbfa96c2df1be0ce4 100644 (file)
@@ -98,27 +98,18 @@ static void pagefault( struct proc *pr,
                inkernel_disaster(pr, frame, NULL, is_nested);
        }
 
-       /* System processes that don't have their own page table can't
-        * have page faults. VM does have its own page table but also
-        * can't have page faults (because VM has to handle them).
-        */
-       if((pr->p_endpoint <= INIT_PROC_NR &&
-        !(pr->p_misc_flags & MF_FULLVM)) || pr->p_endpoint == VM_PROC_NR) {
+       /* VM can't handle page faults. */
+       if(pr->p_endpoint == VM_PROC_NR) {
                /* Page fault we can't / don't want to
                 * handle.
                 */
-               printf("pagefault for process %d ('%s') on CPU %d, "
+               printf("pagefault for VM on CPU %d, "
                        "pc = 0x%x, addr = 0x%x, flags = 0x%x, is_nested %d\n",
-                       pr->p_endpoint, pr->p_name, cpuid, pr->p_reg.pc,
-                       pagefaultcr2, frame->errcode, is_nested);
-               if(!is_nested) {
-                       printf("process vir addr of pagefault is 0x%lx\n",
-                               pagefaultcr2 -
-                                 (pr->p_memmap[D].mem_phys << CLICK_SHIFT));
-               }
+                       cpuid, pr->p_reg.pc, pagefaultcr2, frame->errcode,
+                       is_nested);
                proc_stacktrace(pr);
                printf("pc of pagefault: 0x%lx\n", frame->eip);
-               cause_sig(proc_nr(pr), SIGSEGV);
+               panic("pagefault in VM");
 
                return;
        }
@@ -172,13 +163,9 @@ static void inkernel_disaster(struct proc *saved_proc,
        proc_stacktrace_execute(proc_addr(SYSTEM), k_ebp, frame->eip);
   }
 
-  printseg("ker cs: ", 1, NULL, frame->cs);
-  printseg("ker ds: ", 0, NULL, DS_SELECTOR);
-
   if (saved_proc) {
          printf("scheduled was: process %d (%s), ", saved_proc->p_endpoint, saved_proc->p_name);
-         printf("pc = %u:0x%x\n", (unsigned) saved_proc->p_reg.cs,
-                         (unsigned) saved_proc->p_reg.pc);
+         printf("pc = 0x%x\n", (unsigned) saved_proc->p_reg.pc);
          proc_stacktrace(saved_proc);
 
          panic("Unhandled kernel exception");
diff --git a/kernel/arch/i386/head.S b/kernel/arch/i386/head.S
new file mode 100644 (file)
index 0000000..c019ab1
--- /dev/null
@@ -0,0 +1,98 @@
+#include "kernel/kernel.h" /* configures the kernel */
+
+/* sections */
+
+#include <machine/vm.h>
+#include "../../kernel.h"
+#include <minix/config.h>
+#include <minix/const.h>
+#include <minix/com.h>
+#include <machine/asm.h>
+#include <machine/interrupt.h>
+#include "archconst.h"
+#include "kernel/const.h"
+#include "kernel/proc.h"
+#include "sconst.h"
+#include <machine/multiboot.h>
+
+#include "arch_proto.h" /* K_STACK_SIZE */
+
+#ifdef CONFIG_SMP
+#include "kernel/smp.h"
+#endif
+
+/* Selected 386 tss offsets. */
+#define TSS3_S_SP0     4
+
+IMPORT(copr_not_available_handler)
+IMPORT(params_size)
+IMPORT(params_offset)
+IMPORT(mon_ds)
+IMPORT(switch_to_user)
+IMPORT(multiboot_init)
+
+.text
+/*===========================================================================*/
+/*                             MINIX                                */
+/*===========================================================================*/
+.global MINIX
+MINIX:
+/* this is the entry point for the MINIX kernel */
+       jmp multiboot_init
+
+/* Multiboot header here*/
+
+.balign 8
+
+#define MULTIBOOT_FLAGS (MULTIBOOT_MEMORY_INFO | MULTIBOOT_PAGE_ALIGN)
+
+multiboot_magic:
+       .long MULTIBOOT_HEADER_MAGIC
+multiboot_flags:
+       .long MULTIBOOT_FLAGS
+multiboot_checksum:
+       .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_FLAGS)
+       .long 0
+       .long 0
+       .long 0
+       .long 0
+       .long 0
+/* Video mode */
+multiboot_mode_type:
+       .long MULTIBOOT_VIDEO_MODE_EGA
+multiboot_width:
+       .long MULTIBOOT_CONSOLE_COLS
+multiboot_height:
+       .long MULTIBOOT_CONSOLE_LINES
+multiboot_depth:
+       .long 0
+
+multiboot_init:
+       mov     $load_stack_start, %esp /* make usable stack */
+       mov     $0, %ebp
+       push    $0      /* set flags to known good state */
+       popf    /* esp, clear nested task and int enable */
+       push    $0
+
+        push    %ebx   /* multiboot information struct */
+       push    %eax    /* multiboot magic number */
+        call    _C_LABEL(pre_init)
+
+       /* Kernel is mapped high now and ready to go, with
+        * the boot info pointer returnd in %eax. Set the
+        * highly mapped stack, initialize it, push the boot
+        * info pointer and jump to the highly mapped kernel.
+        */
+       mov     $k_initial_stktop, %esp
+       push    $0      /* Terminate stack */
+       push    %eax
+        call    _C_LABEL(kmain)
+
+       /* not reached */
+hang:
+       jmp hang
+
+.data
+load_stack:
+       .space 4096
+load_stack_start:
index ca3eac6423653bda92e2a57e029346f00ea522b1..65e0021bd4a8ce6003947fc63dc06793ab7ff7da 100644 (file)
 /*===========================================================================*
  *                             intr_init                                    *
  *===========================================================================*/
-int intr_init(const int mine, const int auto_eoi)
+int intr_init(const int auto_eoi)
 {
-/* Initialize the 8259s, finishing with all interrupts disabled.  This is
- * only done in protected mode, in real mode we don't touch the 8259s, but
- * use the BIOS locations instead.  The flag "mine" is set if the 8259s are
- * to be programmed for MINIX, or to be reset to what the BIOS expects.
- */
-
-      /* 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.)
-       */
+/* Initialize the 8259s, finishing with all interrupts disabled.  */
       outb( INT_CTL, ICW1_AT);
-      outb( INT_CTLMASK, mine == INTS_MINIX ? IRQ0_VECTOR : BIOS_IRQ0_VEC);
+      outb( INT_CTLMASK, IRQ0_VECTOR);
                                        /* ICW2 for master */
       outb( INT_CTLMASK, (1 << CASCADE_IRQ));
                                        /* ICW3 tells slaves */
@@ -50,7 +41,7 @@ int intr_init(const int mine, const int auto_eoi)
           outb( INT_CTLMASK, ICW4_AT_MASTER);
       outb( INT_CTLMASK, ~(1 << CASCADE_IRQ)); /* IRQ 0-7 mask */
       outb( INT2_CTL, ICW1_AT);
-      outb( INT2_CTLMASK, mine == INTS_MINIX ? IRQ8_VECTOR : BIOS_IRQ8_VEC);
+      outb( INT2_CTLMASK, IRQ8_VECTOR);
                                                /* ICW2 for slave */
       outb( INT2_CTLMASK, CASCADE_IRQ);        /* ICW3 is slave nr */
       if (auto_eoi)
@@ -59,16 +50,6 @@ int intr_init(const int mine, const int auto_eoi)
          outb( INT2_CTLMASK, ICW4_AT_SLAVE);
       outb( INT2_CTLMASK, ~0);         /* IRQ 8-15 mask */
 
-      /* Copy the BIOS vectors from the BIOS to the Minix location, so we
-       * can still make BIOS calls without reprogramming the i8259s.
-       */
-#if IRQ0_VECTOR != BIOS_IRQ0_VEC
-      phys_copy(BIOS_VECTOR(0) * 4L, VECTOR(0) * 4L, 8 * 4L);
-#endif
-#if IRQ8_VECTOR != BIOS_IRQ8_VEC
-      phys_copy(BIOS_VECTOR(8) * 4L, VECTOR(8) * 4L, 8 * 4L);
-#endif
-
   return OK;
 }
 
index 2f03715fe209411d23124d26ce878292c9064abd..d6519151a6f1b615d1021e0808276e3017ad7b2e 100644 (file)
@@ -53,12 +53,6 @@ void ipc_entry(void);
 void kernel_call_entry(void);
 void level0_call(void);
 
-/* memory.c */
-void segmentation2paging(struct proc * current);
-void i386_freepde(int pde);
-void getcr3val(void);
-
-
 /* exception.c */
 struct exception_frame {
        reg_t   vector;         /* which interrupt vector was triggered */
@@ -83,6 +77,7 @@ unsigned long read_cr4(void);
 void write_cr4(unsigned long value);
 void write_cr3(unsigned long value);
 unsigned long read_cpu_flags(void);
+phys_bytes vir2phys(void *);
 void phys_insb(u16_t port, phys_bytes buf, size_t count);
 void phys_insw(u16_t port, phys_bytes buf, size_t count);
 void phys_outsb(u16_t port, phys_bytes buf, size_t count);
@@ -105,6 +100,17 @@ int __frstor_end(void *);
 int __frstor_failure(void *);
 unsigned short fnstsw(void);
 void fnstcw(unsigned short* cw);
+void x86_lgdt(void *);
+void x86_lldt(u32_t);
+void x86_ltr(u32_t);
+void x86_lidt(void *);
+void x86_load_kerncs(void);
+void x86_load_ds(u32_t);
+void x86_load_ss(u32_t);
+void x86_load_es(u32_t);
+void x86_load_fs(u32_t);
+void x86_load_gs(u32_t);
+
 
 void switch_k_stack(void * esp, void (* continuation)(void));
 
@@ -147,19 +153,25 @@ struct tss_s {
   u16_t trap;
   u16_t iobase;
 /* u8_t iomap[0]; */
-};
+} __attribute__((packed));
 
-void prot_init(void);
-void idt_init(void);
-void init_dataseg(struct segdesc_s *segdp, phys_bytes base, vir_bytes
-       size, int privilege);
 void enable_iop(struct proc *pp);
-int prot_set_kern_seg_limit(vir_bytes limit);
-void printseg(char *banner, int iscs, struct proc *pr, u32_t selector);
 u32_t read_cs(void);
 u32_t read_ds(void);
 u32_t read_ss(void);
 
+void add_memmap(kinfo_t *cbi, u64_t addr, u64_t len);
+void vm_enable_paging(void);
+void cut_memmap(kinfo_t *cbi, phys_bytes start, phys_bytes end);
+phys_bytes pg_roundup(phys_bytes b);
+void pg_info(reg_t *, u32_t **);
+void pg_clear(void);
+void pg_identity(void);
+phys_bytes pg_load(void);
+void pg_map(phys_bytes phys, vir_bytes vaddr, vir_bytes vaddr_end, kinfo_t *cbi);
+int pg_mapkernel(void);
+void pg_mapproc(struct proc *p, struct boot_image *ip, kinfo_t *cbi);
+
 /* prototype of an interrupt vector table entry */
 struct gate_table_s {
  void(*gate) (void);
@@ -167,13 +179,11 @@ struct gate_table_s {
        unsigned char privilege;
 };
 
-extern struct gate_table_s gate_table_pic[];
-
 /* copies an array of vectors to the IDT. The last vector must be zero filled */
 void idt_copy_vectors(struct gate_table_s * first);
+void idt_copy_vectors_pic(void);
 void idt_reload(void);
 
-EXTERN void * k_boot_stktop;
 EXTERN void * k_stacks_start;
 extern void * k_stacks;
 
@@ -196,9 +206,9 @@ reg_t read_ebp(void);
 /*
  * sets up TSS for a cpu and assigns kernel stack and cpu id
  */
-void tss_init(unsigned cpu, void * kernel_stack);
+int tss_init(unsigned cpu, void * kernel_stack);
 
-void int_gate(unsigned vec_nr, vir_bytes offset, unsigned dpl_type);
+void int_gate_idt(unsigned vec_nr, vir_bytes offset, unsigned dpl_type);
 
 void __copy_msg_from_user_end(void);
 void __copy_msg_to_user_end(void);
@@ -210,6 +220,7 @@ int platform_tbl_ptr(phys_bytes start, phys_bytes end, unsigned
        cmp_f)(void *)));
 
 /* breakpoints.c */
+int breakpoint_set(phys_bytes linaddr, int bp, const int flags);
 #define BREAKPOINT_COUNT               4
 #define BREAKPOINT_FLAG_RW_MASK                (3 << 0)
 #define BREAKPOINT_FLAG_RW_EXEC                (0 << 0)
index 00b47c174f8ed7891cfea1df03b6cb0507caca4f..80dd1fb0b8dbff5181715b821b62b8598d29863a 100644 (file)
@@ -23,6 +23,6 @@ struct nmi_frame {
 
 int i386_watchdog_start(void);
 
-#define nmi_in_kernel(f)       ((f)->cs == CS_SELECTOR)
+#define nmi_in_kernel(f)       ((f)->cs == KERN_CS_SELECTOR)
 
 #endif /* __I386_WATCHDOG_H__ */
index 2e124ac82b287986bf77f9c626aec161851b4d7b..123bc4768ce57024ae2cee322b7e1ba4c8dc1daa 100644 (file)
@@ -8,44 +8,25 @@
 /* Constants for protected mode. */
 
 /* Table sizes. */
-#define GDT_SIZE (FIRST_LDT_INDEX + NR_TASKS + NR_PROCS) 
-                                       /* spec. and LDT's */
 #define IDT_SIZE 256   /* the table is set to it's maximal size */
 
-/* Fixed global descriptors.  1 to 7 are prescribed by the BIOS. */
-#define GDT_INDEX            1 /* GDT descriptor */
-#define IDT_INDEX            2 /* IDT descriptor */
-#define DS_INDEX             3 /* kernel DS */
-#define ES_INDEX             4 /* kernel ES (386: flag 4 Gb at startup) */
-#define SS_INDEX             5 /* kernel SS (386: monitor SS at startup) */
-#define CS_INDEX             6 /* kernel CS */
-#define MON_CS_INDEX         7 /* temp for BIOS (386: monitor CS at startup) */
-#define TSS_INDEX_FIRST      8 /* first kernel TSS */
-#define TSS_INDEX_BOOT     TSS_INDEX_FIRST
-#define TSS_INDEX(cpu)      (TSS_INDEX_FIRST + (cpu)) /* per cpu kernel tss */
-#define FIRST_LDT_INDEX     TSS_INDEX(CONFIG_MAX_CPUS) /* rest of descriptors are LDT's */
-
-/* Descriptor structure offsets. */
-#define DESC_BASE            2 /* to base_low */
-#define DESC_BASE_MIDDLE     4 /* to base_middle */
-#define DESC_ACCESS          5 /* to access byte */
-#define DESC_SIZE            8 /* sizeof (struct segdesc_s) */
-
-/*
- * WARNING no () around the macros, be careful. This is because of ACK assembler
- * and will be fixed after switching to GAS
- */
-#define GDT_SELECTOR           GDT_INDEX * DESC_SIZE
-#define IDT_SELECTOR           IDT_INDEX * DESC_SIZE
-#define DS_SELECTOR            DS_INDEX * DESC_SIZE
-#define ES_SELECTOR            ES_INDEX * DESC_SIZE
-/* flat DS is less privileged ES */
-#define FLAT_DS_SELECTOR       ES_SELECTOR
-#define SS_SELECTOR            SS_INDEX * DESC_SIZE
-#define CS_SELECTOR            CS_INDEX * DESC_SIZE
-#define MON_CS_SELECTOR                MON_CS_INDEX * DESC_SIZE
-#define TSS_SELECTOR(cpu)      (TSS_INDEX(cpu) * DESC_SIZE)
-#define TSS_SELECTOR_BOOT      (TSS_INDEX_BOOT * DESC_SIZE)
+/* GDT layout (SYSENTER/SYSEXIT compliant) */
+#define KERN_CS_INDEX        1
+#define KERN_DS_INDEX        2
+#define USER_CS_INDEX        3
+#define USER_DS_INDEX        4
+#define LDT_INDEX            5
+#define TSS_INDEX_FIRST      6
+#define TSS_INDEX(cpu)       (TSS_INDEX_FIRST + (cpu)) /* per cpu kernel tss */
+#define GDT_SIZE             (TSS_INDEX(CONFIG_MAX_CPUS))      /* LDT descriptor */
+
+#define SEG_SELECTOR(i)          ((i)*8)
+#define KERN_CS_SELECTOR SEG_SELECTOR(KERN_CS_INDEX)
+#define KERN_DS_SELECTOR SEG_SELECTOR(KERN_DS_INDEX)
+#define USER_CS_SELECTOR (SEG_SELECTOR(USER_CS_INDEX) | USER_PRIVILEGE)
+#define USER_DS_SELECTOR (SEG_SELECTOR(USER_DS_INDEX) | USER_PRIVILEGE)
+#define LDT_SELECTOR SEG_SELECTOR(LDT_INDEX)
+#define TSS_SELECTOR(cpu)      SEG_SELECTOR(TSS_INDEX(cpu))
 
 /* Privileges. */
 #define INTR_PRIVILEGE       0 /* kernel and interrupt handlers */
 #define IF_MASK 0x00000200
 #define IOPL_MASK 0x003000
 
-#define vir2phys(vir)   ((phys_bytes)((kinfo.data_base + (vir_bytes) (vir))))
-#define phys2vir(ph)   ((vir_bytes)((vir_bytes) (ph) - kinfo.data_base))
-
 #define INTEL_CPUID_GEN_EBX    0x756e6547 /* ASCII value of "Genu" */
 #define INTEL_CPUID_GEN_EDX    0x49656e69 /* ASCII value of "ineI" */
 #define INTEL_CPUID_GEN_ECX    0x6c65746e /* ASCII value of "ntel" */
  */
 #define X86_STACK_TOP_RESERVED (2 * sizeof(reg_t))
 
+#define PG_ALLOCATEME ((phys_bytes)-1)
+
 #endif /* _I386_ACONST_H */
diff --git a/kernel/arch/i386/include/direct_utils.h b/kernel/arch/i386/include/direct_utils.h
new file mode 100644 (file)
index 0000000..5b7943d
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef MB_UTILS_H
+#define MB_UTILS_H
+
+#include "kernel/kernel.h"
+
+void direct_cls(void);
+void direct_print(const char*);
+void direct_print_char(char);
+int direct_read_char(unsigned char*);
+
+#endif
index cdc5380fb9b953b7ca6ec304f2d438af69acaffb..98a543d1f379f33de8bcd6bbef3ba1c3e6f4d644 100644 (file)
@@ -1,44 +1,30 @@
 OUTPUT_ARCH("i386")
-ENTRY(MINIX)
+ENTRY(__k_unpaged_MINIX)
+
+_kern_phys_base = 0x00400000;  /* phys 4MB aligned for convenient remapping */
+_kern_vir_base =  0xF0400000;  /* map kernel high for max. user vir space */
+_kern_offset = (_kern_vir_base - _kern_phys_base);
+
+__k_unpaged__kern_offset = _kern_offset;
+__k_unpaged__kern_vir_base = _kern_vir_base;
+__k_unpaged__kern_phys_base = _kern_phys_base;
+
 SECTIONS
 {
-       . = 0x200000 + SIZEOF_HEADERS;
-       .text . : AT (ADDR(.text) - 0x0000) {
-               *(.text)
-               *(.text.*)
-       }
-       _etext = .;
-       etext = .;
-       . = ALIGN(4096);
+       . = _kern_phys_base;
+       __k_unpaged__kern_unpaged_start = .;
 
-       .data . : AT (ADDR(.data) - 0x0000) {
-               _rodata = .;
-               /* kernel data starts with this magic number */
-               SHORT(0x526f);
-               *(.rodata)
-               *(.rodata.*)
-               _erodata = .;
-               *(.data)
-               *(.data.*)
-               . = ALIGN(4096);
-       }
-       _edata = .;
+       .unpaged_text : { unpaged_*.o(.text) }
+       .unpaged_data ALIGN(4096) : { unpaged_*.o(.data .rodata*) }
+       .unpaged_bss  ALIGN(4096) : { unpaged_*.o(.bss COMMON) } 
+       __k_unpaged__kern_unpaged_end = .;
 
-       .bss . : AT (ADDR(.bss) - 0x0000) {
-               *(.bss)
-               *(.bss.*)
-               *(COMMON)
-       }
-       _end = .;
-       end = .;
+       . += _kern_offset;
 
-       /DISCARD/ :
-       {
-               *(.eh_frame)
-               *(.comment)
-               *(.comment.*)
-               *(.note)
-               *(.note.*)
-               *(.ident)
+       .text             : AT(ADDR(.text) - _kern_offset) { *(.text*) }
+       .data ALIGN(4096) : AT(ADDR(.data) - _kern_offset) { *(.data .rodata* ) }
+       .bss ALIGN(4096)  : AT(ADDR(.bss) - _kern_offset) { *(.bss* COMMON)
+               __k_unpaged__kern_size = . - _kern_vir_base;
+               _kern_size = __k_unpaged__kern_size;
        }
 }
index 4b2eebf40aa657ff484a3e20215efc5661522cd7..b10595ec17be455bc7599488cb7d31bbba328205 100644 (file)
@@ -80,16 +80,12 @@ ENTRY(phys_insw)
        mov     %esp, %ebp
        cld
        push    %edi
-       push    %es
 
-       mov     $FLAT_DS_SELECTOR, %ecx
-       mov     %cx, %es
        mov     8(%ebp), %edx   /* port to read from */
        mov     12(%ebp), %edi  /* destination addr */
        mov     16(%ebp), %ecx  /* byte count */
        shr     $1, %ecx        /* word count */
        rep insw        /* input many words */
-       pop     %es
        pop     %edi
        pop     %ebp
        ret
@@ -108,15 +104,11 @@ ENTRY(phys_insb)
        mov     %esp, %ebp
        cld
        push    %edi
-       push    %es
 
-       mov     $FLAT_DS_SELECTOR, %ecx
-       mov     %cx, %es
        mov     8(%ebp), %edx   /* port to read from */
        mov     12(%ebp), %edi  /* destination addr */
        mov     16(%ebp), %ecx  /* byte count */
        rep insb        /* input many bytes */
-       pop     %es
        pop     %edi
        pop     %ebp
        ret
@@ -135,16 +127,12 @@ ENTRY(phys_outsw)
        mov     %esp, %ebp
        cld
        push    %esi
-       push    %ds
 
-       mov     $FLAT_DS_SELECTOR, %ecx
-       mov     %cx, %ds
        mov     8(%ebp), %edx   /* port to write to */
        mov     12(%ebp), %esi  /* source addr */
        mov     16(%ebp), %ecx  /* byte count */
        shr     $1, %ecx        /* word count */
        rep outsw       /* output many words */
-       pop     %ds
        pop     %esi
        pop     %ebp
        ret
@@ -163,15 +151,11 @@ ENTRY(phys_outsb)
        mov     %esp, %ebp
        cld
        push    %esi
-       push    %ds
 
-       mov     $FLAT_DS_SELECTOR, %ecx
-       mov     %cx, %ds
        mov     8(%ebp), %edx   /* port to write to */
        mov     12(%ebp), %esi  /* source addr */
        mov     16(%ebp), %ecx  /* byte count */
        rep outsb       /* output many bytes */
-       pop     %ds
        pop     %esi
        pop     %ebp
        ret
@@ -185,20 +169,18 @@ ENTRY(phys_outsb)
  *                     phys_bytes bytecount); 
  * Copy a block of data from anywhere to anywhere in physical memory.
  */
-       PC_ARGS = 4+4+4+4       /* 4 + 4 + 4 */
 /*             es edi esi eip   src dst len */
 ENTRY(phys_copy)
+       push    %ebp
+       mov     %esp, %ebp
+
        cld
        push    %esi
        push    %edi
-       push    %es
 
-       mov     $FLAT_DS_SELECTOR, %eax
-       mov     %ax, %es
-
-       mov     PC_ARGS(%esp), %esi
-       mov     PC_ARGS+4(%esp), %edi
-       mov     PC_ARGS+4+4(%esp), %eax
+       mov     8(%ebp), %esi
+       mov     12(%ebp), %edi
+       mov     16(%ebp), %eax
 
        cmp     $10, %eax       /* avoid align overhead for small counts */
        jb      pc_small
@@ -207,43 +189,40 @@ ENTRY(phys_copy)
        and     $3, %ecx        /* count for alignment */
        sub     %ecx, %eax
 
-       rep     movsb %es:(%esi), %es:(%edi)
+       rep     movsb (%esi), (%edi)
        mov     %eax, %ecx
        shr     $2, %ecx        /* count of dwords */
 
-       rep     movsl %es:(%esi), %es:(%edi)
+       rep     movsl (%esi), (%edi)
        and     $3, %eax
 pc_small:
        xchg    %eax, %ecx      /* remainder */
 
-       rep     movsb %es:(%esi), %es:(%edi)
+       rep     movsb (%esi), (%edi)
 
        mov     $0, %eax                /* 0 means: no fault */
 LABEL(phys_copy_fault)         /* kernel can send us here */
-       pop     %es
        pop     %edi
        pop     %esi
+       pop     %ebp
        ret
 
 LABEL(phys_copy_fault_in_kernel)       /* kernel can send us here */
-       pop     %es
        pop     %edi
        pop     %esi
+       pop     %ebp
        mov     %cr2, %eax
        ret
 
+
 /*===========================================================================*/
 /*                             copy_msg_from_user                           */
 /*===========================================================================*/
 /*
- * int copy_msg_from_user(struct proc * p, message * user_mbuf, message * dst);
+ * int copy_msg_from_user(message * user_mbuf, message * dst);
  *
  * Copies a message of 36 bytes from user process space to a kernel buffer. This
- * function assumes that the process address space is installed (cr3 loaded) and
- * the local descriptor table of this process is loaded too.
- *
- * The %gs segment register is used to access the userspace memory. We load the
- * process' data segment in this register.
+ * function assumes that the process address space is installed (cr3 loaded).
  *
  * This function from the callers point of view either succeeds or returns an
  * error which gives the caller a chance to respond accordingly. In fact it
@@ -255,39 +234,31 @@ LABEL(phys_copy_fault_in_kernel)  /* kernel can send us here */
  * userspace as if wrong values or request were passed to the kernel
  */
 ENTRY(copy_msg_from_user)
-       push    %gs
-
-       mov     8(%esp), %eax
-       movw    DSREG(%eax), %gs
-
        /* load the source pointer */
-       mov     12(%esp), %ecx
+       mov     4(%esp), %ecx
        /* load the destination pointer */
-       mov     16(%esp), %edx
+       mov     8(%esp), %edx
 
-       mov     %gs:0*4(%ecx), %eax
-       mov     %eax, 0*4(%edx)
-       mov     %gs:1*4(%ecx), %eax
+/*     mov     0*4(%ecx), %eax
+       mov     %eax, 0*4(%edx) */ 
+       mov     1*4(%ecx), %eax
        mov     %eax, 1*4(%edx)
-       mov     %gs:2*4(%ecx), %eax
+       mov     2*4(%ecx), %eax
        mov     %eax, 2*4(%edx)
-       mov     %gs:3*4(%ecx), %eax
+       mov     3*4(%ecx), %eax
        mov     %eax, 3*4(%edx)
-       mov     %gs:4*4(%ecx), %eax
+       mov     4*4(%ecx), %eax
        mov     %eax, 4*4(%edx)
-       mov     %gs:5*4(%ecx), %eax
+       mov     5*4(%ecx), %eax
        mov     %eax, 5*4(%edx)
-       mov     %gs:6*4(%ecx), %eax
+       mov     6*4(%ecx), %eax
        mov     %eax, 6*4(%edx)
-       mov     %gs:7*4(%ecx), %eax
+       mov     7*4(%ecx), %eax
        mov     %eax, 7*4(%edx)
-       mov     %gs:8*4(%ecx), %eax
+       mov     8*4(%ecx), %eax
        mov     %eax, 8*4(%edx)
 
 LABEL(__copy_msg_from_user_end)
-
-       pop     %gs
-
        movl    $0, %eax
        ret
 
@@ -295,48 +266,38 @@ LABEL(__copy_msg_from_user_end)
 /*                             copy_msg_to_user                             */
 /*===========================================================================*/
 /*
- * void copy_msg_to_user(struct proc * p, message * src, message * user_mbuf);
+ * void copy_msg_to_user(message * src, message * user_mbuf);
  *
- * Copies a message of 36 bytes to user process space from a kernel buffer. This
- * function assumes that the process address space is installed (cr3 loaded) and
- * the local descriptor table of this process is loaded too.
+ * Copies a message of 36 bytes to user process space from a kernel buffer.
  *
  * All the other copy_msg_from_user() comments apply here as well!
  */
 ENTRY(copy_msg_to_user)
-       push    %gs
-
-       mov     8(%esp), %eax
-       movw    DSREG(%eax), %gs
-
        /* load the source pointer */
-       mov     12(%esp), %ecx
+       mov     4(%esp), %ecx
        /* load the destination pointer */
-       mov     16(%esp), %edx
+       mov     8(%esp), %edx
 
        mov     0*4(%ecx), %eax
-       mov     %eax, %gs:0*4(%edx)
+       mov     %eax, 0*4(%edx)
        mov     1*4(%ecx), %eax
-       mov     %eax, %gs:1*4(%edx)
+       mov     %eax, 1*4(%edx)
        mov     2*4(%ecx), %eax
-       mov     %eax, %gs:2*4(%edx)
+       mov     %eax, 2*4(%edx)
        mov     3*4(%ecx), %eax
-       mov     %eax, %gs:3*4(%edx)
+       mov     %eax, 3*4(%edx)
        mov     4*4(%ecx), %eax
-       mov     %eax, %gs:4*4(%edx)
+       mov     %eax, 4*4(%edx)
        mov     5*4(%ecx), %eax
-       mov     %eax, %gs:5*4(%edx)
+       mov     %eax, 5*4(%edx)
        mov     6*4(%ecx), %eax
-       mov     %eax, %gs:6*4(%edx)
+       mov     %eax, 6*4(%edx)
        mov     7*4(%ecx), %eax
-       mov     %eax, %gs:7*4(%edx)
+       mov     %eax, 7*4(%edx)
        mov     8*4(%ecx), %eax
-       mov     %eax, %gs:8*4(%edx)
+       mov     %eax, 8*4(%edx)
 
 LABEL(__copy_msg_to_user_end)
-
-       pop     %gs
-
        movl    $0, %eax
        ret
 
@@ -348,8 +309,6 @@ LABEL(__copy_msg_to_user_end)
  * here to continue, clean up and report the error
  */
 ENTRY(__user_copy_msg_pointer_failure)
-       pop     %gs
-
        movl    $-1, %eax
        ret
 
@@ -366,12 +325,9 @@ ENTRY(phys_memset)
        mov     %esp, %ebp
        push    %esi
        push    %ebx
-       push    %ds
 
        mov     8(%ebp), %esi
        mov     16(%ebp), %eax
-       mov     $FLAT_DS_SELECTOR, %ebx
-       mov     %bx, %ds
        mov     12(%ebp), %ebx
        shr     $2, %eax
 fill_start:
@@ -395,37 +351,18 @@ remain_fill:
 fill_done:
 LABEL(memset_fault)            /* kernel can send us here */
        mov     $0, %eax                /* 0 means: no fault */
-       pop     %ds
        pop     %ebx
        pop     %esi
        pop     %ebp
        ret
 
 LABEL(memset_fault_in_kernel)          /* kernel can send us here */
-       pop     %ds
        pop     %ebx
        pop     %esi
        pop     %ebp
        mov     %cr2, %eax
        ret
 
-
-/*===========================================================================*/
-/*                             mem_rdw                                      */
-/*===========================================================================*/
-/* 
- * PUBLIC u16_t mem_rdw(U16_t segment, u16_t *offset); 
- * Load and return word at far pointer segment:offset. 
- */
-ENTRY(mem_rdw)
-       mov     %ds, %cx
-       mov     4(%esp), %ds
-       mov     4+4(%esp), %eax /* offset */
-       movzwl  (%eax), %eax    /* word to return */
-       mov     %cx, %ds
-       ret
-
-
 /*===========================================================================*/
 /*                             x86_triplefault                              */
 /*===========================================================================*/
@@ -565,12 +502,13 @@ ARG_EAX_ACTION(fnstcw, fnstcw (%eax));
 /* invlpg */
 ARG_EAX_ACTION(i386_invlpg, invlpg (%eax));
 
-/*===========================================================================*/
-/*                             getcr3val                                    */
-/*===========================================================================*/
-/* PUBLIC unsigned long getcr3val(void); */
-ENTRY(getcr3val)
-       mov     %cr3, %eax
+ENTRY(x86_load_kerncs)
+       push    %ebp
+       mov     %esp, %ebp
+       mov     8(%ebp), %eax
+       jmp     $KERN_CS_SELECTOR, $newcs
+newcs:
+       pop     %ebp
        ret
 
 /*
@@ -609,27 +547,6 @@ ENTRY(ia32_msr_write)
        pop     %ebp
        ret
 
-/*===========================================================================*/
-/*                           idt_reload                                     */
-/*===========================================================================*/
-/*  PUBLIC void idt_reload (void); */
-/* reload idt when returning to monitor. */
-ENTRY(idt_reload)
-       lidt    _C_LABEL(gdt)+IDT_SELECTOR /*  reload interrupt descriptor table */
-       ret
-
-/*
- * void reload_segment_regs(void)
- */
-
-#define RELOAD_SEG_REG(reg)    \
-       mov     reg, %ax        ;\
-       mov     %ax, reg        ;
-
-ENTRY(reload_ds)
-       RELOAD_SEG_REG(%ds)
-       ret
-
 /*===========================================================================*/
 /*                           __switch_address_space                         */
 /*===========================================================================*/
@@ -642,8 +559,6 @@ ENTRY(reload_ds)
 ENTRY(__switch_address_space)
        /* read the process pointer */
        mov     4(%esp), %edx
-       /* enable process' segment descriptors  */
-       lldt    P_LDT_SEL(%edx)
        /* get the new cr3 value */
        movl    P_CR3(%edx), %eax
        /* test if the new cr3 != NULL */
@@ -664,52 +579,6 @@ ENTRY(__switch_address_space)
 0:
        ret
 
-/*===========================================================================*/
-/*                             poweroff                                             */
-/*===========================================================================*/
-/* PUBLIC void poweroff(); */
-/* Jump to 16-bit poweroff code */
-ENTRY(poweroff_jmp)
-       cli
-       /* Make real mode descriptor */
-       mov     $(_C_LABEL(gdt) + SS_SELECTOR), %edi
-       mov     $0x100, %eax
-       movw %ax, 2(%edi)
-       shr     $16, %eax
-       movb    %al, 4(%edi)
-       and     $0xff00, %ax
-       andw    $0xff, 6(%edi)
-       or      %ax, 6(%edi)
-       mov     $0xffff, %eax
-       movw    %ax, (%edi)
-       shr     $16, %eax
-       and     $0xf, %ax
-       andb    $0xf0, 6(%edi)
-       or      %ax, 6(%edi)
-       
-       /* Flush TLB */
-       xor     %eax, %eax
-       mov     %eax, %cr3
-       
-       xor     %esp, %esp /* clear esp for real mode*/
-       
-       /* Reset IDTR */
-       lidt    idt_ptr
-       
-       mov     $SS_SELECTOR, %ax
-       mov     %ax, %ds
-       mov     %ax, %es
-       mov     %ax, %fs
-       mov     %ax, %gs
-       mov     %ax, %ss
-       
-       /* Save real mode cr0 in eax */
-       mov     %cr0, %eax
-       andl    $~I386_CR0_PE, %eax
-       
-       /* Jump to 16-bit code that is copied to below 1MB */
-       ljmp    $MON_CS_SELECTOR, $0
-
 /* acknowledge just the master PIC */
 ENTRY(eoi_8259_master)
        movb    $END_OF_INT, %al
@@ -909,3 +778,6 @@ ENTRY(switch_k_stack)
 idt_ptr:
        .short 0x3ff
        .long 0x0
+
+ldtsel:
+       .long LDT_SELECTOR
diff --git a/kernel/arch/i386/mb_utils.h b/kernel/arch/i386/mb_utils.h
deleted file mode 100644 (file)
index f45a27c..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef MB_UTILS_H
-#define MB_UTILS_H
-
-#include "kernel/kernel.h"
-
-void mb_cls(void);
-void mb_print(char*);
-void mb_print_char(char);
-int mb_read_char(unsigned char*);
-
-
-#endif
index b3dbe8c22de96f48cc02eed20fef86b99c9a486b..c780776017e16d2f802a5c9d89631ab4ca9dd71c 100644 (file)
 #endif
 #endif
 
-int i386_paging_enabled = 0;
-
-static int psok = 0;
-
-#define MAX_FREEPDES   2
-static int nfreepdes = 0, freepdes[MAX_FREEPDES];
+phys_bytes video_mem_vaddr = 0;
 
 #define HASPT(procptr) ((procptr)->p_seg.p_cr3 != 0)
+static int nfreepdes = 0;
+#define MAXFREEPDES    2
+static int freepdes[MAXFREEPDES];
 
 static u32_t phys_get32(phys_bytes v);
-static void vm_enable_paging(void);
 
-       
-void segmentation2paging(struct proc * current)
+void mem_clear_mapcache(void)
 {
-       /* switch to the current process page tables before turning paging on */
-       switch_address_space(current);
-       vm_enable_paging();
+       int i;
+       for(i = 0; i < nfreepdes; i++) {
+               struct proc *ptproc = get_cpulocal_var(ptproc);
+               int pde = freepdes[i];
+               u32_t *ptv;
+               assert(ptproc);
+               ptv = ptproc->p_seg.p_cr3_v;
+               assert(ptv);
+               ptv[pde] = 0;
+       }
 }
 
 /* This function sets up a mapping from within the kernel's address
@@ -65,7 +68,7 @@ void segmentation2paging(struct proc * current)
  *
  * The logical number supplied by the caller is translated into an actual
  * pde number to be used, and a pointer to it (linear address) is returned
- * for actual use by phys_copy or phys_memset.
+ * for actual use by phys_copy or memset.
  */
 static phys_bytes createpde(
        const struct proc *pr,  /* Requested process, NULL for physical. */
@@ -83,10 +86,10 @@ static phys_bytes createpde(
        pde = freepdes[free_pde_idx];
        assert(pde >= 0 && pde < 1024);
 
-       if(pr && ((pr == get_cpulocal_var(ptproc)) || !HASPT(pr))) {
+       if(pr && ((pr == get_cpulocal_var(ptproc)) || iskernelp(pr))) {
                /* Process memory is requested, and
                 * it's a process that is already in current page table, or
-                * a process that is in every page table.
+                * the kernel, which is always there.
                 * Therefore linaddr is valid directly, with the requested
                 * size.
                 */
@@ -138,9 +141,6 @@ static int lin_lin_copy(struct proc *srcproc, vir_bytes srclinaddr,
        u32_t addr;
        proc_nr_t procslot;
 
-       assert(vm_running);
-       assert(nfreepdes >= MAX_FREEPDES);
-
        assert(get_cpulocal_var(ptproc));
        assert(get_cpulocal_var(proc_ptr));
        assert(read_cr3() == get_cpulocal_var(ptproc)->p_seg.p_cr3);
@@ -219,13 +219,8 @@ static u32_t phys_get32(phys_bytes addr)
        const u32_t v;
        int r;
 
-       if(!vm_running) {
-               phys_copy(addr, vir2phys(&v), sizeof(v));
-               return v;
-       }
-
        if((r=lin_lin_copy(NULL, addr, 
-               proc_addr(SYSTEM), vir2phys(&v), sizeof(v))) != OK) {
+               proc_addr(SYSTEM), (phys_bytes) &v, sizeof(v))) != OK) {
                panic("lin_lin_copy for phys_get32 failed: %d",  r);
        }
 
@@ -266,87 +261,6 @@ static char *cr4_str(u32_t e)
 }
 #endif
 
-void vm_stop(void)
-{
-       write_cr0(read_cr0() & ~I386_CR0_PG);
-}
-
-static void vm_enable_paging(void)
-{
-       u32_t cr0, cr4;
-       int pgeok;
-
-       psok = _cpufeature(_CPUF_I386_PSE);
-       pgeok = _cpufeature(_CPUF_I386_PGE);
-
-       cr0= read_cr0();
-       cr4= read_cr4();
-
-       /* First clear PG and PGE flag, as PGE must be enabled after PG. */
-       write_cr0(cr0 & ~I386_CR0_PG);
-       write_cr4(cr4 & ~(I386_CR4_PGE | I386_CR4_PSE));
-
-       cr0= read_cr0();
-       cr4= read_cr4();
-
-       /* Our first page table contains 4MB entries. */
-       if(psok)
-               cr4 |= I386_CR4_PSE;
-
-       write_cr4(cr4);
-
-       /* First enable paging, then enable global page flag. */
-       cr0 |= I386_CR0_PG;
-       write_cr0(cr0 );
-       cr0 |= I386_CR0_WP;
-       write_cr0(cr0);
-
-       /* May we enable these features? */
-       if(pgeok)
-               cr4 |= I386_CR4_PGE;
-
-       write_cr4(cr4);
-}
-
-/*===========================================================================*
- *                              umap_local                                   *
- *===========================================================================*/
-phys_bytes umap_local(rp, seg, vir_addr, bytes)
-register struct proc *rp;       /* pointer to proc table entry for process */
-int seg;                        /* T, D, or S segment */
-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. */
-  vir_clicks vc;                /* the virtual address in clicks */
-  phys_bytes pa;                /* intermediate variables as phys_bytes */
-  phys_bytes seg_base;
-
-  if(seg != T && seg != D && seg != S)
-       panic("umap_local: wrong seg: %d",  seg);
-
-  if (bytes <= 0) return( (phys_bytes) 0);
-  if (vir_addr + bytes <= vir_addr) return 0;   /* overflow */
-  vc = (vir_addr + bytes - 1) >> CLICK_SHIFT;   /* last click of data */
-  if (seg != T)
-        seg = (vc < rp->p_memmap[D].mem_vir + rp->p_memmap[D].mem_len ? D : S);
-  else if (rp->p_memmap[T].mem_len == 0)       /* common I&D? */
-        seg = D;                               /* ptrace needs this */
-  if ((vir_addr>>CLICK_SHIFT) >= rp->p_memmap[seg].mem_vir +
-        rp->p_memmap[seg].mem_len) return( (phys_bytes) 0 );
-  if (vc >= rp->p_memmap[seg].mem_vir +
-        rp->p_memmap[seg].mem_len) return( (phys_bytes) 0 );
-  
-  seg_base = (phys_bytes) rp->p_memmap[seg].mem_phys;
-  seg_base = seg_base << CLICK_SHIFT;   /* segment origin in bytes */
-  pa = (phys_bytes) vir_addr;
-  pa -= rp->p_memmap[seg].mem_vir << CLICK_SHIFT;
-  return(seg_base + pa);
-}
-
 /*===========================================================================*
  *                              umap_virtual                                 *
  *===========================================================================*/
@@ -356,22 +270,15 @@ int seg;                        /* T, D, or S segment */
 vir_bytes vir_addr;             /* virtual address in bytes within the seg */
 vir_bytes bytes;                /* # of bytes to be copied */
 {
-       vir_bytes linear;
        phys_bytes phys = 0;
 
-       if(!(linear = umap_local(rp, seg, vir_addr, bytes))) {
-                       printf("SYSTEM:umap_virtual: umap_local failed\n");
-                       phys = 0;
-               } else {
-                       if(vm_lookup(rp, linear, &phys, NULL) != OK) {
-                               printf("SYSTEM:umap_virtual: vm_lookup of %s: seg 0x%x: 0x%lx failed\n", rp->p_name, seg, vir_addr);
-                               phys = 0;
-                       } else {
-                               if(phys == 0)
-                                       panic("vm_lookup returned phys: %d",  phys);
-                       }
-               }
-       
+       if(vm_lookup(rp, vir_addr, &phys, NULL) != OK) {
+               printf("SYSTEM:umap_virtual: vm_lookup of %s: seg 0x%x: 0x%lx failed\n", rp->p_name, seg, vir_addr);
+               phys = 0;
+       } else {
+               if(phys == 0)
+                       panic("vm_lookup returned phys: %d",  phys);
+       }
 
        if(phys == 0) {
                printf("SYSTEM:umap_virtual: lookup failed\n");
@@ -381,9 +288,9 @@ vir_bytes bytes;                /* # of bytes to be copied */
        /* Now make sure addresses are contiguous in physical memory
         * so that the umap makes sense.
         */
-       if(bytes > 0 && vm_lookup_range(rp, linear, NULL, bytes) != bytes) {
+       if(bytes > 0 && vm_lookup_range(rp, vir_addr, NULL, bytes) != bytes) {
                printf("umap_virtual: %s: %lu at 0x%lx (vir 0x%lx) not contiguous\n",
-                       rp->p_name, bytes, linear, vir_addr);
+                       rp->p_name, bytes, vir_addr, vir_addr);
                return 0;
        }
 
@@ -409,11 +316,7 @@ int vm_lookup(const struct proc *proc, const vir_bytes virtual,
        assert(proc);
        assert(physical);
        assert(!isemptyp(proc));
-
-       if(!HASPT(proc)) {
-               *physical = virtual;
-               return OK;
-       }
+       assert(HASPT(proc));
 
        /* Retrieve page directory entry. */
        root = (u32_t *) proc->p_seg.p_cr3;
@@ -472,9 +375,7 @@ size_t vm_lookup_range(const struct proc *proc, vir_bytes vir_addr,
 
        assert(proc);
        assert(bytes > 0);
-
-       if (!HASPT(proc))
-               return bytes;
+       assert(HASPT(proc));
 
        /* Look up the first page. */
        if (vm_lookup(proc, vir_addr, &phys, NULL) != OK)
@@ -548,9 +449,6 @@ int vm_check_range(struct proc *caller, struct proc *target,
         */
        int r;
 
-       if (!vm_running)
-               return EFAULT;
-
        if ((caller->p_misc_flags & MF_KCALL_RESUME) &&
                        (r = caller->p_vmrequest.vmresult) != OK)
                return r;
@@ -570,7 +468,7 @@ void delivermsg(struct proc *rp)
        assert(rp->p_misc_flags & MF_DELIVERMSG);
        assert(rp->p_delivermsg.m_source != NONE);
 
-       if (copy_msg_to_user(rp, &rp->p_delivermsg,
+       if (copy_msg_to_user(&rp->p_delivermsg,
                                (message *) rp->p_delivermsg_vir)) {
                printf("WARNING wrong user pointer 0x%08lx from "
                                "process %s / %d\n",
@@ -671,24 +569,12 @@ int vm_memset(endpoint_t who, phys_bytes ph, const u8_t c, phys_bytes bytes)
        /* NONE for physical, otherwise virtual */
        if(who != NONE) {
                int n;
-               vir_bytes lin;
-               assert(vm_running);
                if(!isokendpt(who, &n)) return ESRCH;
                whoptr = proc_addr(n);
-               if(!(lin = umap_local(whoptr, D, ph, bytes))) return EFAULT;
-               ph = lin;
        } 
        
        p = c | (c << 8) | (c << 16) | (c << 24);
 
-       if(!vm_running) {
-               if(who != NONE) panic("can't vm_memset without vm running");
-               phys_memset(ph, p, bytes);
-               return OK;
-       }
-
-       assert(nfreepdes >= MAX_FREEPDES);
-
        assert(get_cpulocal_var(ptproc)->p_seg.p_cr3_v);
 
        assert(!catch_pagefaults);
@@ -736,9 +622,7 @@ int vmcheck;                        /* if nonzero, can return VMSUSPEND */
 {
 /* Copy bytes from virtual address src_addr to virtual address dst_addr. */
   struct vir_addr *vir_addr[2];        /* virtual source and destination address */
-  phys_bytes phys_addr[2];     /* absolute source and destination */ 
-  int seg_index;
-  int i;
+  int i, r;
   struct proc *procs[2];
 
   assert((vmcheck && caller) || (!vmcheck && !caller));
@@ -751,111 +635,57 @@ int vmcheck;                     /* if nonzero, can return VMSUSPEND */
   vir_addr[_DST_] = dst_addr;
 
   for (i=_SRC_; i<=_DST_; i++) {
-       int proc_nr, type;
+       endpoint_t proc_e = vir_addr[i]->proc_nr_e;
+       int proc_nr;
        struct proc *p;
 
-       type = vir_addr[i]->segment & SEGMENT_TYPE;
-       if((type != PHYS_SEG) && isokendpt(vir_addr[i]->proc_nr_e, &proc_nr))
-               p = proc_addr(proc_nr);
-       else 
+       if(proc_e == NONE) {
                p = NULL;
-
-       procs[i] = p;
-
-      /* Get physical address. */
-      switch(type) {
-      case LOCAL_SEG:
-      case LOCAL_VM_SEG:
-         if(!p) {
-               return EDEADSRCDST;
-         }
-          seg_index = vir_addr[i]->segment & SEGMENT_INDEX;
-         if(type == LOCAL_SEG)
-                 phys_addr[i] = umap_local(p, seg_index, vir_addr[i]->offset,
-                       bytes);
-         else
-               phys_addr[i] = umap_virtual(p, seg_index,
-                               vir_addr[i]->offset, bytes);
-         if(phys_addr[i] == 0) {
-               printf("virtual_copy: map 0x%x failed for %s seg %d, "
-                       "offset %lx, len %lu, i %d\n",
-                       type, p->p_name, seg_index, vir_addr[i]->offset,
-                       bytes, i);
-         }
-          break;
-      case PHYS_SEG:
-          phys_addr[i] = vir_addr[i]->offset;
-          break;
-      default:
-         printf("virtual_copy: strange type 0x%x\n", type);
-         return EINVAL;
-      }
-
-      /* Check if mapping succeeded. */
-      if (phys_addr[i] <= 0 && vir_addr[i]->segment != PHYS_SEG)  {
-      printf("virtual_copy EFAULT\n");
-         return EFAULT;
-      }
-  }
-
-  if(vm_running) {
-       int r;
-
-       if(caller && (caller->p_misc_flags & MF_KCALL_RESUME)) {
-               assert(caller->p_vmrequest.vmresult != VMSUSPEND);
-               if(caller->p_vmrequest.vmresult != OK) {
-                       return caller->p_vmrequest.vmresult;
-               }
-       }
-
-       if((r=lin_lin_copy(procs[_SRC_], phys_addr[_SRC_],
-               procs[_DST_], phys_addr[_DST_], bytes)) != OK) {
-               struct proc *target = NULL;
-               phys_bytes lin;
-               if(r != EFAULT_SRC && r != EFAULT_DST)
-                       panic("lin_lin_copy failed: %d",  r);
-               if(!vmcheck || !caller) {
-                       return r;
-               }
-
-               if(r == EFAULT_SRC) {
-                       lin = phys_addr[_SRC_];
-                       target = procs[_SRC_];
-               } else if(r == EFAULT_DST) {
-                       lin = phys_addr[_DST_];
-                       target = procs[_DST_];
-               } else {
-                       panic("r strange: %d",  r);
+       } else {
+               if(!isokendpt(proc_e, &proc_nr)) {
+                       printf("virtual_copy: no reasonable endpoint\n");
+                       return ESRCH;
                }
-
-               assert(caller);
-               assert(target);
-
-               vm_suspend(caller, target, lin, bytes, VMSTYPE_KERNELCALL);
-               return VMSUSPEND;
+               p = proc_addr(proc_nr);
        }
 
-       return OK;
+       procs[i] = p;
   }
 
-  assert(!vm_running);
+  if(caller && (caller->p_misc_flags & MF_KCALL_RESUME)) {
+       assert(caller->p_vmrequest.vmresult != VMSUSPEND);
+       if(caller->p_vmrequest.vmresult != OK) {
+               return caller->p_vmrequest.vmresult;
+       }
+  }
 
-  /* can't copy to/from process with PT without VM */
-#define NOPT(p) (!(p) || !HASPT(p))
-  if(!NOPT(procs[_SRC_])) {
-       printf("ignoring page table src: %s / %d at 0x%x\n",
-               procs[_SRC_]->p_name, procs[_SRC_]->p_endpoint, procs[_SRC_]->p_seg.p_cr3);
-}
-  if(!NOPT(procs[_DST_])) {
-       printf("ignoring page table dst: %s / %d at 0x%x\n",
-               procs[_DST_]->p_name, procs[_DST_]->p_endpoint,
-               procs[_DST_]->p_seg.p_cr3);
+  if((r=lin_lin_copy(procs[_SRC_], vir_addr[_SRC_]->offset,
+       procs[_DST_], vir_addr[_DST_]->offset, bytes)) != OK) {
+       struct proc *target = NULL;
+       phys_bytes lin;
+       if(r != EFAULT_SRC && r != EFAULT_DST)
+               panic("lin_lin_copy failed: %d",  r);
+       if(!vmcheck || !caller) {
+               return r;
+       }
+
+       if(r == EFAULT_SRC) {
+               lin = vir_addr[_SRC_]->offset;
+               target = procs[_SRC_];
+       } else if(r == EFAULT_DST) {
+               lin = vir_addr[_DST_]->offset;
+               target = procs[_DST_];
+       } else {
+               panic("r strange: %d",  r);
+       }
+
+       assert(caller);
+       assert(target);
+
+       vm_suspend(caller, target, lin, bytes, VMSTYPE_KERNELCALL);
+       return VMSUSPEND;
   }
 
-  /* Now copy bytes between physical addresseses. */
-  if(phys_copy(phys_addr[_SRC_], phys_addr[_DST_], (phys_bytes) bytes))
-       return EFAULT;
   return OK;
 }
 
@@ -868,11 +698,12 @@ int data_copy(const endpoint_t from_proc, const vir_bytes from_addr,
 {
   struct vir_addr src, dst;
 
-  src.segment = dst.segment = D;
   src.offset = from_addr;
   dst.offset = to_addr;
   src.proc_nr_e = from_proc;
   dst.proc_nr_e = to_proc;
+  assert(src.proc_nr_e != NONE);
+  assert(dst.proc_nr_e != NONE);
 
   return virtual_copy(&src, &dst, bytes);
 }
@@ -887,37 +718,48 @@ int data_copy_vmcheck(struct proc * caller,
 {
   struct vir_addr src, dst;
 
-  src.segment = dst.segment = D;
   src.offset = from_addr;
   dst.offset = to_addr;
   src.proc_nr_e = from_proc;
   dst.proc_nr_e = to_proc;
+  assert(src.proc_nr_e != NONE);
+  assert(dst.proc_nr_e != NONE);
 
   return virtual_copy_vmcheck(caller, &src, &dst, bytes);
 }
 
+void memory_init(void)
+{
+       assert(nfreepdes == 0);
+
+       freepdes[nfreepdes++] = kinfo.freepde_start++;
+       freepdes[nfreepdes++] = kinfo.freepde_start++;
+
+       assert(kinfo.freepde_start < I386_VM_DIR_ENTRIES);
+       assert(nfreepdes == 2);
+       assert(nfreepdes <= MAXFREEPDES);
+}
+
 /*===========================================================================*
- *                             arch_pre_exec                                *
+ *                             arch_proc_init                               *
  *===========================================================================*/
-void arch_pre_exec(struct proc *pr, const u32_t ip, const u32_t sp)
+void arch_proc_init(struct proc *pr, const u32_t ip, const u32_t sp, char *name)
 {
-/* set program counter and stack pointer. */
+       arch_proc_reset(pr);
+       strcpy(pr->p_name, name);
+
+       /* set custom state we know */
        pr->p_reg.pc = ip;
        pr->p_reg.sp = sp;
 }
 
-/* VM reports page directory slot we're allowed to use freely. */
-void i386_freepde(const int pde)
-{
-       if(nfreepdes >= MAX_FREEPDES)
-               return;
-       freepdes[nfreepdes++] = pde;
-}
-
 static int oxpcie_mapping_index = -1,
        lapic_mapping_index = -1,
        ioapic_first_index = -1,
-       ioapic_last_index = -1;
+       ioapic_last_index = -1,
+       video_mem_mapping_index = -1;
+
+extern char *video_mem;
 
 int arch_phys_map(const int index,
                        phys_bytes *addr,
@@ -929,6 +771,8 @@ int arch_phys_map(const int index,
        static char *ser_var = NULL;
 
        if(first) {
+               video_mem_mapping_index = freeidx++;
+
 #ifdef USE_APIC
                if(lapic_addr)
                        lapic_mapping_index = freeidx++;
@@ -950,20 +794,28 @@ int arch_phys_map(const int index,
                        }
                }
 #endif
+
                first = 0;
        }
 
 #ifdef USE_APIC
-       /* map the local APIC if enabled */
-       if (index == lapic_mapping_index) {
+       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;
+               return OK;
+       }
+       else if (index == lapic_mapping_index) {
+               /* map the local APIC if enabled */
                if (!lapic_addr)
                        return EINVAL;
-               *addr = vir2phys(lapic_addr);
+               *addr = lapic_addr;
                *len = 4 << 10 /* 4kB */;
                *flags = VMMF_UNCACHED;
                return OK;
        }
-       else if (ioapic_enabled && index <= nioapics) {
+       else if (ioapic_enabled && index <= ioapic_last_index) {
                *addr = io_apic[index - 1].paddr;
                *len = 4 << 10 /* 4kB */;
                *flags = VMMF_UNCACHED;
@@ -993,7 +845,8 @@ int arch_phys_map_reply(const int index, const vir_bytes addr)
        }
        else if (ioapic_enabled && index >= ioapic_first_index &&
                index <= ioapic_last_index) {
-               io_apic[index - ioapic_first_index].vaddr = addr;
+               int i = index - ioapic_first_index;
+               io_apic[i].vaddr = addr;
                return OK;
        }
 #endif
@@ -1004,56 +857,22 @@ int arch_phys_map_reply(const int index, const vir_bytes addr)
                return OK;
        }
 #endif
+       if (index == video_mem_mapping_index) {
+               video_mem_vaddr =  addr;
+               return OK;
+       }
 
        return EINVAL;
 }
 
-int arch_enable_paging(struct proc * caller, const message * m_ptr)
+int arch_enable_paging(struct proc * caller)
 {
-       struct vm_ep_data ep_data;
-       int r;
-
-       /* switch_address_space() checks what is in cr3, and do nothing if it's
-        * the same as the cr3 of its argument, newptproc.  If MINIX was
-        * previously booted, this could very well be the case.
-        *
-        * The first time switch_address_space() is called, we want to
-        * force it to do something (load cr3 and set newptproc), so we
-        * zero cr3, and force paging off to make that a safe thing to do.
-        *
-        * After that, segmentation2paging() enables paging with the page table
-        * of caller loaded.
-        */
-
-       vm_stop();
-       write_cr3(0);
+       assert(caller->p_seg.p_cr3);
 
-       /* switch from segmentation only to paging */
-       segmentation2paging(caller);
+       /* load caller's page table */
+       switch_address_space(caller);
 
-       vm_running = 1;
-
-       /*
-        * copy the extra data associated with the call from userspace
-        */
-       if((r=data_copy(caller->p_endpoint, (vir_bytes)m_ptr->SVMCTL_VALUE,
-               KERNEL, (vir_bytes) &ep_data, sizeof(ep_data))) != OK) {
-               printf("vmctl_enable_paging: data_copy failed! (%d)\n", r);
-               return r;
-       }
-
-       /*
-        * when turning paging on i386 we also change the segment limits to make
-        * the special mappings requested by the kernel reachable
-        */
-       if ((r = prot_set_kern_seg_limit(ep_data.data_seg_limit)) != OK)
-               return r;
-
-       /*
-        * install the new map provided by the call
-        */
-       if (newmap(caller, caller, ep_data.mem_map) != OK)
-               panic("arch_enable_paging: newmap failed");
+       video_mem = (char *) video_mem_vaddr;
 
 #ifdef USE_APIC
        /* start using the virtual addresses */
@@ -1074,8 +893,6 @@ int arch_enable_paging(struct proc * caller, const message * m_ptr)
 #if CONFIG_SMP
        barrier();
 
-       i386_paging_enabled = 1;
-
        wait_for_APs_to_finish_booting();
 #endif
 #endif
@@ -1120,7 +937,7 @@ int platform_tbl_ptr(phys_bytes start,
        phys_bytes addr;
 
        for (addr = start; addr < end; addr += increment) {
-               phys_copy (addr, vir2phys(buff), size);
+               phys_copy (addr, (phys_bytes) buff, size);
                if (cmp_f(buff)) {
                        if (phys_addr)
                                *phys_addr = addr;
index 89c0d86597693c33e34186cf2e64594e4833da5d..830a994151ede7b2ce346849b6777a3030ebc9ba 100644 (file)
 IMPORT(copr_not_available_handler)
 IMPORT(params_size)
 IMPORT(params_offset)
-IMPORT(mon_ds)
 IMPORT(switch_to_user)
 IMPORT(multiboot_init)
 
 .text
-/*===========================================================================*/
-/*                             MINIX                                        */
-/*===========================================================================*/
-.global MINIX
-MINIX:
-/* this is the entry point for the MINIX kernel */
-
-       jmp _C_LABEL(multiboot_init)
-
-/* Multiboot header here*/
-
-.balign 8
-
-multiboot_magic:
-       .long MULTIBOOT_HEADER_MAGIC
-multiboot_flags:
-       .long MULTIBOOT_FLAGS
-multiboot_checksum:
-       .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_FLAGS)
-       .long 0
-       .long 0
-       .long 0
-       .long 0
-       .long 0
-/* Video mode */
-multiboot_mode_type:
-       .long MULTIBOOT_VIDEO_MODE_EGA
-multiboot_width:
-       .long MULTIBOOT_CONSOLE_COLS
-multiboot_height:
-       .long MULTIBOOT_CONSOLE_LINES
-multiboot_depth:
-       .long 0
-
-.globl kernel_init
-kernel_init: /* after pre-init*/
-       push    %ebp
-       mov     %esp, %ebp
-       push    %esi
-       push    %edi
-/* Copy the monitor global descriptor table to the address space of kernel and */
-/* switch over to it.  Prot_init() can then update it with immediate effect. */
-
-       sgdt    _C_LABEL(gdt)+GDT_SELECTOR      /* get the monitor gdtr */
-       movl    _C_LABEL(gdt)+GDT_SELECTOR+2, %esi      /* absolute address of GDT */
-       mov     $_C_LABEL(gdt), %ebx    /* address of kernel GDT */
-       mov     $8*8, %ecx      /* copying eight descriptors */
-copygdt:
-       movb    %es:(%esi), %al
-       movb    %al, (%ebx)
-       inc     %esi
-       inc     %ebx
-       loop    copygdt
-       movl    _C_LABEL(gdt)+DS_SELECTOR+2, %eax /* base of kernel data */
-       and     $0x00FFFFFF, %eax       /* only 24 bits */
-       add     $_C_LABEL(gdt), %eax    /* eax = vir2phys(gdt) */
-       movl    %eax, _C_LABEL(gdt)+GDT_SELECTOR+2 /* set base of GDT */
-       lgdt    _C_LABEL(gdt)+GDT_SELECTOR      /* switch over to kernel GDT */
-
-/* Locate boot parameters, set up kernel segment registers and stack. */
-       mov     8(%ebp), %ebx   /* boot parameters offset */
-       mov     12(%ebp), %edx  /* boot parameters length */
-       mov     16(%ebp), %eax  /* address of a.out headers */
-       mov     %ds, %ax        /* kernel data */
-       mov     %ax, %es
-       mov     %ax, %fs
-       mov     %ax, %gs
-       mov     %ax, %ss
-       mov     $_C_LABEL(k_boot_stktop) - 4, %esp      /* set sp to point to the top of kernel stack */
-
-/* Save boot parameters into these global variables for i386 code */
-       movl    %edx, _C_LABEL(params_size)
-       movl    %ebx, _C_LABEL(params_offset)
-       movl    $SS_SELECTOR, _C_LABEL(mon_ds)
-
-/* Call C startup code to set up a proper environment to run main(). */
-       push    %edx
-       push    %ebx
-       push    $SS_SELECTOR
-       push    $DS_SELECTOR
-       push    $CS_SELECTOR
-       call    _C_LABEL(cstart) /* cstart(cs, ds, mds, parmoff, parmlen) */
-       add     $5*4, %esp
-
-/* Reload gdtr, idtr and the segment registers to global descriptor table set */
-/* up by prot_init(). */
-
-       lgdt    _C_LABEL(gdt)+GDT_SELECTOR
-       lidt    _C_LABEL(gdt)+IDT_SELECTOR
-
-       ljmp    $CS_SELECTOR, $csinit
-csinit:
-       movw    $DS_SELECTOR, %ax
-       mov     %ax, %ds
-       mov     %ax, %es
-       mov     %ax, %fs
-       mov     %ax, %gs
-       mov     %ax, %ss
-       movw    $TSS_SELECTOR_BOOT, %ax /* no other TSS is used */
-       ltr     %ax
-       push    $0      /* set flags to known good state */
-       popf    /* esp, clear nested task and int enable */
-       jmp     _C_LABEL(main)  /* main() */
-
-
 /*===========================================================================*/
 /*                             interrupt handlers                           */
 /*             interrupt handlers for 386 32-bit protected mode             */
@@ -419,22 +313,26 @@ ENTRY(restore_user_context)
        mov     4(%esp), %ebp   /* will assume P_STACKBASE == 0 */
 
        /* reconstruct the stack for iret */
-       movl    SSREG(%ebp), %eax
-       push    %eax
+       push    $USER_DS_SELECTOR       /* ss */
        movl    SPREG(%ebp), %eax
        push    %eax
        movl    PSWREG(%ebp), %eax
        push    %eax
-       movl    CSREG(%ebp), %eax
-       push    %eax
+       push    $USER_CS_SELECTOR       /* cs */
        movl    PCREG(%ebp), %eax
        push    %eax
 
-       RESTORE_GP_REGS(%ebp)
+       /* Restore segments as the user should see them. */
+       movw    $USER_DS_SELECTOR, %si
+        movw    %si, %ds
+        movw    %si, %es
+        movw    %si, %fs
+        movw    %si, %gs
 
-       RESTORE_SEGS(%ebp)
+       /* Same for general-purpose registers. */
+       RESTORE_GP_REGS(%ebp)
 
-       movl    %ss:BPREG(%ebp), %ebp
+       movl    BPREG(%ebp), %ebp
 
        iret    /* continue process */
 
@@ -582,7 +480,7 @@ ENTRY(startup_ap_32)
         * we are in protected mode now, %cs is correct and we need to set the
         * data descriptors before we can touch anything
         */
-       movw    $DS_SELECTOR, %ax
+       movw    $KERN_DS_SELECTOR, %ax
        mov     %ax, %ds
        mov     %ax, %ss
        mov     %ax, %es
@@ -613,6 +511,10 @@ ENTRY(startup_ap_32)
 .data
 .short 0x526F  /* this must be the first data entry (magic #) */
 .bss
+k_initial_stack:
+.space K_STACK_SIZE
+LABEL(__k_unpaged_k_initial_stktop)
+
 /*
  * the kernel stack
  */
diff --git a/kernel/arch/i386/multiboot.S b/kernel/arch/i386/multiboot.S
deleted file mode 100644 (file)
index 4fdd097..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-#include "kernel/kernel.h" /* configures the kernel */
-#include <minix/config.h>
-#include <minix/const.h>
-#include <minix/com.h>
-#include <machine/asm.h>
-#include <machine/interrupt.h>
-#include "archconst.h"
-#include "kernel/const.h"
-#include "kernel/proc.h"
-#include "sconst.h"
-#include <machine/multiboot.h>
-
-#define GDT_SET_ENTRY(selector, base, limit) \
-       mov     %ebp, %edi; \
-       add     $(_C_LABEL(gdt) + selector), %edi; \
-       mov     base, %eax; \
-       movw %ax, 2(%edi); \
-       shr     $16, %eax; \
-       movb    %al, 4(%edi); \
-       and     $0xff00, %ax; \
-       andw    $0xff, 6(%edi); \
-       or      %ax, 6(%edi); \
-       mov     limit, %eax; \
-       movw    %ax, (%edi); \
-       shr     $16, %eax; \
-       and     $0xf, %ax; \
-       andb    $0xf0, 6(%edi); \
-       or      %ax, 6(%edi); \
-
-IMPORT(pre_init)
-.extern kernel_init
-
-ENTRY(multiboot_init)
-       mov     $(GDT_SIZE*DESC_SIZE), %eax
-       mov     $(_C_LABEL(gdt) + GDT_SELECTOR), %edi
-       mov     %ax, (%edi)
-       mov     $_C_LABEL(gdt), %eax
-       mov     %eax, 2(%edi)
-       lgdt    (%edi)
-       ljmp    $(CS_SELECTOR), $reload_cs
-
-reload_cs:
-       mov     $DS_SELECTOR, %eax
-       mov     %eax, %ds
-       mov     %eax, %ss
-       mov     %eax, %es
-       mov     %eax, %fs
-       mov     %eax, %gs
-       
-       mov     $(multiboot_stack + MULTIBOOT_STACK_SIZE), %esp
-
-       push    %ebx
-       call    _C_LABEL(pre_init)
-       
-       add     $4, %esp
-
-       /* return to old boot code of kernel */
-       push    %eax
-       push    $MULTIBOOT_PARAM_BUF_SIZE
-       push    $_C_LABEL(multiboot_param_buf)
-       push    $0
-
-       mov     $ES_SELECTOR, %eax
-       mov     %eax, %es
-
-       jmp     kernel_init
-
-.data
-LABEL(multiboot_param_buf)
-       .space  MULTIBOOT_PARAM_BUF_SIZE
-
-multiboot_stack:
-.space MULTIBOOT_STACK_SIZE + 4
diff --git a/kernel/arch/i386/pg_utils.c b/kernel/arch/i386/pg_utils.c
new file mode 100644 (file)
index 0000000..2702500
--- /dev/null
@@ -0,0 +1,260 @@
+
+#include <minix/cpufeature.h>
+
+#include <minix/type.h>
+#include <libexec.h>
+#include <assert.h>
+#include "kernel.h"
+#include "arch_proto.h"
+
+#include <string.h>
+#include <libexec.h>
+#include <minix/type.h>
+
+/* These are set/computed in kernel.lds. */
+extern char _kern_vir_base, _kern_phys_base, _kern_size;
+
+/* Retrieve the absolute values to something we can use. */
+static phys_bytes kern_vir_start = (phys_bytes) &_kern_vir_base;
+static phys_bytes kern_phys_start = (phys_bytes) &_kern_phys_base;
+static phys_bytes kern_kernlen = (phys_bytes) &_kern_size;
+
+/* page directory we can use to map things */
+static u32_t pagedir[1024]  __aligned(4096);
+
+void cut_memmap(kinfo_t *cbi, phys_bytes start, phys_bytes end)
+{
+        int m;
+        phys_bytes o;
+
+        if((o=start % I386_PAGE_SIZE))
+                start -= o;
+        if((o=end % I386_PAGE_SIZE))
+                end += I386_PAGE_SIZE - o;
+
+        for(m = 0; m < cbi->mmap_size; m++) {
+                phys_bytes substart = start, subend = end;
+                phys_bytes memaddr = cbi->memmap[m].addr,
+                        memend = cbi->memmap[m].addr + cbi->memmap[m].len;
+
+                /* adjust cut range to be a subset of the free memory */
+                if(substart < memaddr) substart = memaddr;
+                if(subend > memend) subend = memend;
+                if(substart >= subend) continue;
+
+                /* if there is any overlap, forget this one and add
+                 * 1-2 subranges back
+                 */
+                cbi->memmap[m].addr = cbi->memmap[m].len = 0;
+                if(substart > memaddr)
+                        add_memmap(cbi, memaddr, substart-memaddr);
+                if(subend < memend)
+                        add_memmap(cbi, subend, memend-subend);
+        }
+}
+
+void add_memmap(kinfo_t *cbi, u64_t addr, u64_t len)
+{
+        int m;
+       phys_bytes highmark;
+#define LIMIT 0xFFFFF000
+        /* Truncate available memory at 4GB as the rest of minix
+         * currently can't deal with any bigger.
+         */
+        if(addr > LIMIT) return;
+        if(addr + len > LIMIT) {
+                len -= (addr + len - LIMIT);
+        }
+        assert(cbi->mmap_size < MAXMEMMAP);
+        if(len == 0) return;
+       addr = roundup(addr, I386_PAGE_SIZE);
+       len = rounddown(len, I386_PAGE_SIZE);
+        for(m = 0; m < MAXMEMMAP; m++) {
+                if(cbi->memmap[m].len) continue;
+                cbi->memmap[m].addr = addr;
+                cbi->memmap[m].len = len;
+                cbi->memmap[m].type = MULTIBOOT_MEMORY_AVAILABLE;
+                if(m >= cbi->mmap_size)
+                        cbi->mmap_size = m+1;
+                return;
+        }
+
+       highmark = addr + len;
+       if(highmark > cbi->mem_high_phys)
+               cbi->mem_high_phys = highmark;
+
+        panic("no available memmap slot");
+}
+
+u32_t *alloc_pagetable(phys_bytes *ph)
+{
+       u32_t *ret;
+#define PG_PAGETABLES 3
+       static u32_t pagetables[PG_PAGETABLES][1024]  __aligned(4096);
+       static int pt_inuse = 0;
+       if(pt_inuse >= PG_PAGETABLES) panic("no more pagetables");
+       assert(sizeof(pagetables[pt_inuse]) == I386_PAGE_SIZE);
+       ret = pagetables[pt_inuse++];
+       *ph = vir2phys(ret);
+       return ret;
+}
+
+#define PAGE_KB (I386_PAGE_SIZE / 1024)
+
+phys_bytes pg_alloc_page(kinfo_t *cbi)
+{
+       int m;
+       multiboot_memory_map_t *mmap;
+       for(m = cbi->mmap_size-1; m >= 0; m--) {
+               mmap = &cbi->memmap[m];
+               if(!mmap->len) continue;
+               assert(mmap->len > 0);
+               assert(!(mmap->len % I386_PAGE_SIZE));
+               assert(!(mmap->addr % I386_PAGE_SIZE));
+
+               mmap->len -= I386_PAGE_SIZE;
+
+               return mmap->addr + mmap->len;
+       }
+
+       panic("can't find free memory");
+}
+
+void pg_identity(void)
+{
+       int i;
+       phys_bytes phys;
+
+        /* Set up an identity mapping page directory */
+        for(i = 0; i < I386_VM_DIR_ENTRIES; i++) {
+                phys = i * I386_BIG_PAGE_SIZE;
+                pagedir[i] =  phys | I386_VM_PRESENT | I386_VM_BIGPAGE |
+                        I386_VM_USER | I386_VM_WRITE;
+        }
+}
+
+int pg_mapkernel(void)
+{
+       int pde;
+       u32_t mapped = 0, kern_phys = kern_phys_start;
+
+        assert(!(kern_vir_start % I386_BIG_PAGE_SIZE));
+        assert(!(kern_phys % I386_BIG_PAGE_SIZE));
+        pde = kern_vir_start / I386_BIG_PAGE_SIZE; /* start pde */
+       while(mapped < kern_kernlen) {
+               pagedir[pde] = kern_phys | I386_VM_PRESENT | 
+                       I386_VM_BIGPAGE | I386_VM_WRITE;
+               mapped += I386_BIG_PAGE_SIZE;
+               kern_phys += I386_BIG_PAGE_SIZE;
+               pde++;
+       }
+       return pde;     /* free pde */
+}
+
+void vm_enable_paging(void)
+{
+        u32_t cr0, cr4;
+        int pgeok;
+
+        pgeok = _cpufeature(_CPUF_I386_PGE);
+
+        cr0= read_cr0();
+        cr4= read_cr4();
+
+       /* The boot loader should have put us in protected mode. */
+       assert(cr0 & I386_CR0_PE);
+
+        /* First clear PG and PGE flag, as PGE must be enabled after PG. */
+        write_cr0(cr0 & ~I386_CR0_PG);
+        write_cr4(cr4 & ~(I386_CR4_PGE | I386_CR4_PSE));
+
+        cr0= read_cr0();
+        cr4= read_cr4();
+
+        /* Our page table contains 4MB entries. */
+        cr4 |= I386_CR4_PSE;
+
+        write_cr4(cr4);
+
+        /* First enable paging, then enable global page flag. */
+        cr0 |= I386_CR0_PG;
+        write_cr0(cr0);
+        cr0 |= I386_CR0_WP;
+        write_cr0(cr0);
+
+        /* May we enable these features? */
+        if(pgeok)
+                cr4 |= I386_CR4_PGE;
+
+        write_cr4(cr4);
+}
+
+phys_bytes pg_load()
+{
+       phys_bytes phpagedir = vir2phys(pagedir);
+        write_cr3(phpagedir);
+       return phpagedir;
+}
+
+void pg_clear(void)
+{
+       memset(pagedir, 0, sizeof(pagedir));
+}
+
+phys_bytes pg_rounddown(phys_bytes b)
+{
+       phys_bytes o;
+       if(!(o = b % I386_PAGE_SIZE))
+               return b;
+       return b  - o;
+}
+
+void pg_map(phys_bytes phys, vir_bytes vaddr, vir_bytes vaddr_end,
+       kinfo_t *cbi)
+{
+       static int mapped_pde = -1;
+       static u32_t *pt = NULL;
+       int pde, pte;
+
+       if(phys == PG_ALLOCATEME) {
+               assert(!(vaddr % I386_PAGE_SIZE));
+       } else  {
+               assert((vaddr % I386_PAGE_SIZE) == (phys % I386_PAGE_SIZE));
+               vaddr = pg_rounddown(vaddr);
+               phys = pg_rounddown(phys);
+       }       
+       assert(vaddr < kern_vir_start);
+
+       while(vaddr < vaddr_end) {
+               phys_bytes source = phys;
+               assert(!(vaddr % I386_PAGE_SIZE));
+               if(phys == PG_ALLOCATEME) {
+                       source = pg_alloc_page(cbi);
+               } else {
+                       assert(!(phys % I386_PAGE_SIZE));
+               }
+               assert(!(source % I386_PAGE_SIZE));
+               pde = I386_VM_PDE(vaddr);
+               pte = I386_VM_PTE(vaddr);
+               if(mapped_pde < pde) {
+                       phys_bytes ph;
+                       pt = alloc_pagetable(&ph);
+                       pagedir[pde] = (ph & I386_VM_ADDR_MASK)
+                               | I386_VM_PRESENT | I386_VM_USER | I386_VM_WRITE;
+                       mapped_pde = pde;
+               }
+               assert(pt);
+               pt[pte] = (source & I386_VM_ADDR_MASK) |
+                       I386_VM_PRESENT | I386_VM_USER | I386_VM_WRITE;
+               vaddr += I386_PAGE_SIZE;
+               if(phys != PG_ALLOCATEME)
+                       phys += I386_PAGE_SIZE;
+       }
+}
+
+void pg_info(reg_t *pagedir_ph, u32_t **pagedir_v)
+{
+       *pagedir_ph = vir2phys(pagedir);
+       *pagedir_v = pagedir;
+}
+
index 0e5532436046b6cb48b0c27a7be2c8b68725b14f..53aac5b6657d8ef377e7ee4fc8009bec2d268def 100644 (file)
-#include "kernel/kernel.h"
+
+#define UNPAGED 1      /* for proper kmain() prototype */
+
+#include "kernel.h"
+#include <assert.h>
+#include <stdlib.h>
 #include <minix/minlib.h>
 #include <minix/const.h>
-/*
- * == IMPORTANT == 
- * Routines in this file can not use any variable in kernel BSS, 
- * since before image is extracted, no BSS is allocated. 
- * So pay attention to any external call (including library call).
- * 
- * */
 #include <minix/types.h>
 #include <minix/type.h>
 #include <minix/com.h>
 #include <sys/param.h>
+#include <sys/reboot.h>
 #include <machine/partition.h>
 #include "string.h"
 #include "arch_proto.h"
 #include "libexec.h"
-#include "mb_utils.h"
+#include "direct_utils.h"
 #include "serial.h"
+#include "glo.h"
 #include <machine/multiboot.h>
 
 #if USE_SYSDEBUG
 #define MULTIBOOT_VERBOSE 1
 #endif
 
-/* FIXME: Share this define with kernel linker script */
-#define MULTIBOOT_KERNEL_ADDR 0x00200000UL
+/* to-be-built kinfo struct, diagnostics buffer */
+kinfo_t kinfo;
+struct kmessages kmess;
 
-/* Granularity used in image file and copying */
-#define GRAN 512
-#define SECT_CEIL(x) ((((x) - 1) / GRAN + 1) * GRAN)
+/* pg_utils.c uses this; in this phase, there is a 1:1 mapping. */
+phys_bytes vir2phys(void *addr) { return (phys_bytes) addr; } 
+
+/* mb_utils.c uses this; we can reach it directly */
+char *video_mem = (char *) MULTIBOOT_VIDEO_BUFFER;
 
 /* String length used for mb_itoa */
 #define ITOA_BUFFER_SIZE 20
 
-#define mb_load_phymem(buf, phy, len) \
-               phys_copy((phy), (u32_t)(buf), (len))
-
-#define mb_save_phymem(buf, phy, len) \
-               phys_copy((u32_t)(buf), (phy), (len))
-
-#define mb_clear_memrange(start, end) \
-               phys_memset((start), 0, (end)-(start))
-
-static void mb_itoa(u32_t val, char * out) 
-{
-       char ret[ITOA_BUFFER_SIZE];
-       int i = ITOA_BUFFER_SIZE - 2;
-       /* Although there's a library version of itoa(int n), 
-       * we can't use it since that implementation relies on BSS segment
-       */
-       ret[ITOA_BUFFER_SIZE - 2] = '0';
-       if (val) {
-               for (; i >= 0; i--) {
-                       char c;
-                       if (val == 0) break;
-                       c = val % 10;
-                       val = val / 10;
-                               c += '0';
-                       ret[i] = c;
-               }
-       }
-       else
-               i--;
-       ret[ITOA_BUFFER_SIZE - 1] = 0;
-       strcpy(out, ret + i + 1);
-}
-
-static void mb_itox(u32_t val, char *out) 
-{
-       char ret[9];
-       int i = 7;
-       /* Convert a number to hex string */
-       ret[7] = '0';
-       if (val) {
-               for (; i >= 0; i--) {
-                       char c;
-                       if (val == 0) break;
-                       c = val & 0xF;
-                       val = val >> 4;
-                       if (c > 9)
-                               c += 'A' - 10;
-                       else
-                               c += '0';
-                       ret[i] = c;
-               }       
-       }
-       else
-               i--;
-       ret[8] = 0;
-       strcpy(out, ret + i + 1);
-}
-
-static void mb_put_char(char c, int line, int col) 
+static int mb_set_param(char *bigbuf, char *name, char *value, kinfo_t *cbi) 
 {
-       /* Write a char to vga display buffer. */
-       if (line<MULTIBOOT_CONSOLE_LINES&&col<MULTIBOOT_CONSOLE_COLS)
-               mb_save_phymem(
-                       &c, 
-                       MULTIBOOT_VIDEO_BUFFER 
-                               + line * MULTIBOOT_CONSOLE_COLS * 2 
-                               + col * 2, 
-                       1);
-}
-
-static char mb_get_char(int line, int col) 
-{
-       char c;
-       /* Read a char to from display buffer. */
-       if (line < MULTIBOOT_CONSOLE_LINES && col < MULTIBOOT_CONSOLE_COLS)
-               mb_load_phymem(
-                       &c, 
-                       MULTIBOOT_VIDEO_BUFFER 
-                       + line * MULTIBOOT_CONSOLE_COLS * 2 
-                       + col * 2, 
-                       1);
-       return c;
-}
-
-/* Give non-zero values to avoid them in BSS */
-static int print_line = 1, print_col = 1;
-
-#include <sys/video.h>
-       
-void mb_cls(void)
-{
-       int i, j;
-       /* Clear screen */
-       for (i = 0; i < MULTIBOOT_CONSOLE_LINES; i++ )
-               for (j = 0; j < MULTIBOOT_CONSOLE_COLS; j++ )
-                       mb_put_char(0, i, j);
-       print_line = print_col = 0;
-
-       /* Tell video hardware origin is 0. */
-       outb(C_6845+INDEX, VID_ORG);
-       outb(C_6845+DATA, 0);
-       outb(C_6845+INDEX, VID_ORG+1);
-       outb(C_6845+DATA, 0);
-}
-
-static void mb_scroll_up(int lines) 
-{
-       int i, j;
-       for (i = 0; i < MULTIBOOT_CONSOLE_LINES; i++ ) {
-               for (j = 0; j < MULTIBOOT_CONSOLE_COLS; j++ ) {
-                       char c = 0;
-                       if(i < MULTIBOOT_CONSOLE_LINES-lines)
-                               c = mb_get_char(i + lines, j);
-                       mb_put_char(c, i, j);
-               }
-       }
-       print_line-= lines;
-}
-
-void mb_print_char(char c)
-{
-       while (print_line >= MULTIBOOT_CONSOLE_LINES)
-               mb_scroll_up(1);
-
-       if (c == '\n') {
-               while (print_col < MULTIBOOT_CONSOLE_COLS)
-                       mb_put_char(' ', print_line, print_col++);
-               print_line++;
-               print_col = 0;
-               return;
-       }
-
-       mb_put_char(c, print_line, print_col++);
-
-       if (print_col >= MULTIBOOT_CONSOLE_COLS) {
-               print_line++;
-               print_col = 0;
-       }
-
-       while (print_line >= MULTIBOOT_CONSOLE_LINES)
-               mb_scroll_up(1);
-}
-
-void mb_print(char *str)
-{
-       while (*str) {
-               mb_print_char(*str);
-               str++;
-       }
-}
-
-/* Standard and AT keyboard.  (PS/2 MCA implies AT throughout.) */
-#define KEYBD          0x60    /* I/O port for keyboard data */
-#define KB_STATUS      0x64    /* I/O port for status on AT */
-#define KB_OUT_FULL    0x01    /* status bit set when keypress char pending */
-#define KB_AUX_BYTE    0x20    /* Auxiliary Device Output Buffer Full */
-
-int mb_read_char(unsigned char *ch)
-{
-       unsigned long b, sb;
-#ifdef DEBUG_SERIAL
-       u8_t c, lsr;
-
-       if (do_serial_debug) {
-               lsr= inb(COM1_LSR);
-               if (!(lsr & LSR_DR))
-                       return 0;
-               c = inb(COM1_RBR);
-               return 1;
-       }
-#endif /* DEBUG_SERIAL */
-
-       sb = inb(KB_STATUS);
-
-       if (!(sb & KB_OUT_FULL)) {
-               return 0;
-       }
-
-       b = inb(KEYBD);
-
-       if (!(sb & KB_AUX_BYTE))
-               return 1;
-
-       return 0;
-}
-
-static void mb_print_hex(u32_t value) 
-{
-       int i;
-       char c;
-       char out[9] = "00000000";
-       /* Print a hex value */
-       for (i = 7; i >= 0; i--) {
-               c = value % 0x10;
-               value /= 0x10;
-               if (c < 10) 
-                       c += '0';
-               else
-                       c += 'A'-10;
-               out[i] = c;
-       }
-       mb_print(out);
-}
-
-static int mb_set_param(char *name, char *value) 
-{
-       char *p = multiboot_param_buf;
+       char *p = bigbuf;
+       char *bufend = bigbuf + MULTIBOOT_PARAM_BUF_SIZE;
        char *q;
        int namelen = strlen(name);
        int valuelen = strlen(value);
-       
+
+       /* Some variables we recognize */
+       if(!strcmp(name, SERVARNAME)) { cbi->do_serial_debug = 1; return 0; }
+       if(!strcmp(name, SERBAUDVARNAME)) { cbi->serial_debug_baud = atoi(value); return 0; }
+
        /* Delete the item if already exists */
        while (*p) {
                if (strncmp(p, name, namelen) == 0 && p[namelen] == '=') {
                        q = p;
                        while (*q) q++;
-                       for (q++; 
-                               q < multiboot_param_buf + MULTIBOOT_PARAM_BUF_SIZE; 
-                               q++, p++)
+                       for (q++; q < bufend; q++, p++)
                                *p = *q;
                        break;
                }
@@ -261,16 +63,12 @@ static int mb_set_param(char *name, char *value)
                p++;
        }
        
-       for (p = multiboot_param_buf;
-               p < multiboot_param_buf + MULTIBOOT_PARAM_BUF_SIZE 
-                       && (*p || *(p + 1));
-               p++)
+       for (p = bigbuf; p < bufend && (*p || *(p + 1)); p++)
                ;
-       if (p > multiboot_param_buf) p++;
+       if (p > bigbuf) p++;
        
        /* Make sure there's enough space for the new parameter */
-       if (p + namelen + valuelen + 3 
-               > multiboot_param_buf + MULTIBOOT_PARAM_BUF_SIZE)
+       if (p + namelen + valuelen + 3 > bufend)
                return -1;
        
        strcpy(p, name);
@@ -281,202 +79,172 @@ static int mb_set_param(char *name, char *value)
        return 0;
 }
 
-static void get_parameters(multiboot_info_t *mbi) 
+int overlaps(multiboot_module_t *mod, int n, int cmp_mod)
 {
-       char mem_value[40], temp[ITOA_BUFFER_SIZE];
-       int i;
-       int dev;
-       int ctrlr;
-       int disk, prim, sub;
-       int var_i,value_i;
-       char *p;
-       const static int dev_cNd0[] = { 0x0300, 0x0800, 0x0A00, 0x0C00, 0x1000 };
-       static char mb_cmd_buff[GRAN] = "add some value to avoid me in BSS";
-       static char var[GRAN] = "add some value to avoid me in BSS";
-       static char value[GRAN] = "add some value to avoid me in BSS";
-       for (i = 0; i < MULTIBOOT_PARAM_BUF_SIZE; i++)
-               multiboot_param_buf[i] = 0;
-       
-       if (mbi->flags & MULTIBOOT_INFO_BOOTDEV) {
-               disk = ((mbi->boot_device&0xff000000) >> 24)-0x80;
-               prim = (mbi->boot_device & 0xff0000) >> 16;
-               if (prim == 0xff)
-                   prim = 0;
-               sub = (mbi->boot_device & 0xff00) >> 8;
-               if (sub == 0xff)
-                   sub = 0;
-               ctrlr = 0;
-               dev = dev_cNd0[ctrlr];
-
-               /* Determine the value of rootdev */
-               dev += 0x80
-                   + (disk * NR_PARTITIONS + prim) * NR_PARTITIONS + sub;
-
-               mb_itoa(dev, temp);
-               mb_set_param("rootdev", temp);
-               mb_set_param("ramimagedev", temp);
+       multiboot_module_t *cmp = &mod[cmp_mod];
+       int m;
+
+#define INRANGE(mod, v) ((v) >= mod->mod_start && (v) <= thismod->mod_end)
+#define OVERLAP(mod1, mod2) (INRANGE(mod1, mod2->mod_start) || \
+                       INRANGE(mod1, mod2->mod_end))
+       for(m = 0; m < n; m++) {
+               multiboot_module_t *thismod = &mod[m];
+               if(m == cmp_mod) continue;
+               if(OVERLAP(thismod, cmp))
+                       return 1;
        }
-       mb_set_param("hz", "60");
-       
-       if (mbi->flags & MULTIBOOT_INFO_MEMORY)
-       {
-               strcpy(mem_value, "800:");
-               mb_itox(
-                       mbi->mem_lower * 1024 > MULTIBOOT_LOWER_MEM_MAX ? 
-                               MULTIBOOT_LOWER_MEM_MAX : mbi->mem_lower * 1024, 
-                       temp);
-               strcat(mem_value, temp);
-               strcat(mem_value, ",100000:");
-               mb_itox(mbi->mem_upper * 1024, temp);
-               strcat(mem_value, temp);
-               mb_set_param("memory", mem_value);
+       return 0;
+}
+
+void print_memmap(kinfo_t *cbi)
+{
+       int m;
+       assert(cbi->mmap_size < MAXMEMMAP);
+       for(m = 0; m < cbi->mmap_size; m++) {
+               printf("%08lx-%08lx ",cbi->memmap[m].addr, cbi->memmap[m].addr + cbi->memmap[m].len);
        }
-       
+       printf("\nsize %08lx\n", cbi->mmap_size);
+}
+
+void get_parameters(u32_t ebx, kinfo_t *cbi) 
+{
+       multiboot_memory_map_t *mmap;
+       multiboot_info_t *mbi = &cbi->mbi;
+       int var_i,value_i, m, k;
+       char *p;
+       extern char _kern_phys_base, _kern_vir_base, _kern_size,
+               _kern_unpaged_start, _kern_unpaged_end;
+       phys_bytes kernbase = (phys_bytes) &_kern_phys_base,
+               kernsize = (phys_bytes) &_kern_size;
+#define BUF 1024
+       static char cmdline[BUF];
+
+       /* get our own copy of the multiboot info struct and module list */
+       memcpy((void *) mbi, (void *) ebx, sizeof(*mbi));
+
+       /* Set various bits of info for the higher-level kernel. */
+       cbi->mem_high_phys = 0;
+       cbi->user_sp = (vir_bytes) &_kern_vir_base;
+       cbi->vir_kern_start = (vir_bytes) &_kern_vir_base;
+       cbi->bootstrap_start = (vir_bytes) &_kern_unpaged_start;
+       cbi->bootstrap_len = (vir_bytes) &_kern_unpaged_end -
+               cbi->bootstrap_start;
+       cbi->kmess = &kmess;
+
+       /* set some configurable defaults */
+       cbi->do_serial_debug = 0;
+       cbi->serial_debug_baud = 115200;
+
+       /* parse boot command line */
        if (mbi->flags&MULTIBOOT_INFO_CMDLINE) {
+               static char var[BUF];
+               static char value[BUF];
+
                /* Override values with cmdline argument */
-               p = mb_cmd_buff;
-               mb_load_phymem(mb_cmd_buff, mbi->cmdline, GRAN);
+               memcpy(cmdline, (void *) mbi->cmdline, BUF);
+               p = cmdline;
                while (*p) {
                        var_i = 0;
                        value_i = 0;
                        while (*p == ' ') p++;
                        if (!*p) break;
-                       while (*p && *p != '=' && *p != ' ' && var_i < GRAN - 1) 
+                       while (*p && *p != '=' && *p != ' ' && var_i < BUF - 1) 
                                var[var_i++] = *p++ ;
                        var[var_i] = 0;
                        if (*p++ != '=') continue; /* skip if not name=value */
-                       while (*p && *p != ' ' && value_i < GRAN - 1) 
+                       while (*p && *p != ' ' && value_i < BUF - 1) 
                                value[value_i++] = *p++ ;
                        value[value_i] = 0;
                        
-                       mb_set_param(var, value);
+                       mb_set_param(cbi->param_buf, var, value, cbi);
                }
        }
-}
-
-static void mb_extract_image(multiboot_info_t mbi)
-{
-       phys_bytes start_paddr = 0x5000000;
-       multiboot_module_t *mb_module_info;
-       multiboot_module_t *module;
-       u32_t mods_count = mbi.mods_count;
-       int r, i;
-       vir_bytes text_vaddr, text_filebytes, text_membytes;
-       vir_bytes data_vaddr, data_filebytes, data_membytes;
-       phys_bytes text_paddr, data_paddr;
-       vir_bytes stack_bytes;
-       vir_bytes pc;
-       off_t text_offset, data_offset;
 
-       /* Save memory map for kernel tasks */
-       r = read_header_elf((char *) MULTIBOOT_KERNEL_ADDR,
-                               4096, /* everything is there */
-                           &text_vaddr, &text_paddr,
-                           &text_filebytes, &text_membytes,
-                           &data_vaddr, &data_paddr,
-                           &data_filebytes, &data_membytes,
-                           &pc, &text_offset, &data_offset);
-
-       for (i = 0; i < NR_TASKS; ++i) {
-           image[i].memmap.text_vaddr = trunc_page(text_vaddr);
-           image[i].memmap.text_paddr = trunc_page(text_paddr);
-           image[i].memmap.text_bytes = text_membytes;
-           image[i].memmap.data_vaddr = trunc_page(data_vaddr);
-           image[i].memmap.data_paddr = trunc_page(data_paddr);
-           image[i].memmap.data_bytes = data_membytes;
-           image[i].memmap.stack_bytes = 0;
-           image[i].memmap.entry = pc;
+       /* round user stack down to leave a gap to catch kernel
+        * stack overflow; and to distinguish kernel and user addresses
+        * at a glance (0xf.. vs 0xe..) 
+        */
+       cbi->user_sp &= 0xF0000000;
+       cbi->user_end = cbi->user_sp;
+
+       assert(!(cbi->bootstrap_start % I386_PAGE_SIZE));
+       cbi->bootstrap_len = rounddown(cbi->bootstrap_len, I386_PAGE_SIZE);
+       assert(mbi->flags & MULTIBOOT_INFO_MODS);
+       assert(mbi->mods_count < MULTIBOOT_MAX_MODS);
+       assert(mbi->mods_count > 0);
+       memcpy(&cbi->module_list, (void *) mbi->mods_addr,
+               mbi->mods_count * sizeof(multiboot_module_t));
+       
+       memset(cbi->memmap, 0, sizeof(cbi->memmap));
+       /* mem_map has a variable layout */
+       if(mbi->flags & MULTIBOOT_INFO_MEM_MAP) {
+               cbi->mmap_size = 0;
+               for (mmap = (multiboot_memory_map_t *) mbi->mmap_addr;
+                    (unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length;
+                      mmap = (multiboot_memory_map_t *) 
+                       ((unsigned long) mmap + mmap->size + sizeof(mmap->size))) {
+                       if(mmap->type != MULTIBOOT_MEMORY_AVAILABLE) continue;
+                       add_memmap(cbi, mmap->addr, mmap->len);
+               }
+       } else {
+               assert(mbi->flags & MULTIBOOT_INFO_MEMORY);
+               add_memmap(cbi, 0, mbi->mem_lower_unused*1024);
+               add_memmap(cbi, 0x100000, mbi->mem_upper_unused*1024);
        }
 
-#ifdef MULTIBOOT_VERBOSE
-       mb_print("\nKernel:   ");
-       mb_print_hex(trunc_page(text_paddr));
-       mb_print("-");
-       mb_print_hex(trunc_page(data_paddr) + data_membytes);
-       mb_print(" Entry: ");
-       mb_print_hex(pc);
-#endif
-
-       mb_module_info = ((multiboot_module_t *)mbi.mods_addr);
-       module = &mb_module_info[0];
-
-       /* Load boot image services into memory and save memory map */
-       for (i = 0; module < &mb_module_info[mods_count]; ++module, ++i) {
-           r = read_header_elf((char *) module->mod_start,
-                               module->mod_end - module->mod_start + 1,
-                               &text_vaddr, &text_paddr,
-                               &text_filebytes, &text_membytes,
-                               &data_vaddr, &data_paddr,
-                               &data_filebytes, &data_membytes,
-                               &pc, &text_offset, &data_offset);
-           if (r) {
-               mb_print("fatal: ELF parse failure\n");
-               /* Spin here */
-               while (1)
-                       ;
-           }
-
-           stack_bytes = image[NR_TASKS+i].stack_kbytes * 1024;
-
-           text_paddr = start_paddr + (text_vaddr & PAGE_MASK);
-
-           /* Load text segment */
-           phys_copy(module->mod_start+text_offset, text_paddr,
-                     text_filebytes);
-           mb_clear_memrange(text_paddr+text_filebytes,
-                             round_page(text_paddr) + text_membytes);
-
-           data_paddr  = round_page((text_paddr + text_membytes));
-           data_paddr += data_vaddr & PAGE_MASK;
-           /* start of next module */
-           start_paddr = round_page(data_paddr + data_membytes + stack_bytes);
-
-           /* Load data and stack segments */
-           phys_copy(module->mod_start+data_offset, data_paddr, data_filebytes);
-           mb_clear_memrange(data_paddr+data_filebytes, start_paddr);
-
-           /* Save memmap for  non-kernel tasks, so subscript past kernel
-              tasks. */
-           image[NR_TASKS+i].memmap.text_vaddr = trunc_page(text_vaddr);
-           image[NR_TASKS+i].memmap.text_paddr = trunc_page(text_paddr);
-           image[NR_TASKS+i].memmap.text_bytes = text_membytes;
-           image[NR_TASKS+i].memmap.data_vaddr = trunc_page(data_vaddr);
-           image[NR_TASKS+i].memmap.data_paddr = trunc_page(data_paddr);
-           image[NR_TASKS+i].memmap.data_bytes = data_membytes;
-           image[NR_TASKS+i].memmap.stack_bytes = stack_bytes;
-           image[NR_TASKS+i].memmap.entry = pc;
-
-#ifdef MULTIBOOT_VERBOSE
-           mb_print("\n");
-           mb_print_hex(i);
-           mb_print(": ");
-           mb_print_hex(trunc_page(text_paddr));
-           mb_print("-");
-           mb_print_hex(trunc_page(data_paddr) + data_membytes + stack_bytes);
-           mb_print(" Entry: ");
-           mb_print_hex(pc);
-           mb_print(" Stack: ");
-           mb_print_hex(stack_bytes);
-           mb_print(" ");
-           mb_print((char *)module->cmdline);
+       /* Sanity check: the kernel nor any of the modules may overlap
+        * with each other. Pretend the kernel is an extra module for a
+        * second.
+        */
+       k = mbi->mods_count;
+       assert(k < MULTIBOOT_MAX_MODS);
+       cbi->module_list[k].mod_start = kernbase;
+       cbi->module_list[k].mod_end = kernbase + kernsize;
+       cbi->mods_with_kernel = mbi->mods_count+1;
+       cbi->kern_mod = k;
+
+       for(m = 0; m < cbi->mods_with_kernel; m++) {
+#if 0
+               printf("checking overlap of module %08lx-%08lx\n",
+                 cbi->module_list[m].mod_start, cbi->module_list[m].mod_end);
 #endif
+               if(overlaps(cbi->module_list, cbi->mods_with_kernel, m))
+                       panic("overlapping boot modules/kernel");
+               /* We cut out the bits of memory that we know are
+                * occupied by the kernel and boot modules.
+                */
+               cut_memmap(cbi,
+                       cbi->module_list[m].mod_start, 
+                       cbi->module_list[m].mod_end);
        }
-
-       return;
 }
 
-phys_bytes pre_init(u32_t ebx)
+kinfo_t *pre_init(u32_t magic, u32_t ebx)
 {
-       multiboot_info_t mbi;
-
-       /* Do pre-initialization for multiboot, returning physical address of
-       *  of multiboot module info
-       */
-       mb_cls();
-       mb_print("\nMINIX booting... ");
-       mb_load_phymem(&mbi, ebx, sizeof(mbi));
-       get_parameters(&mbi);
-       mb_print("\nLoading image... ");
-       mb_extract_image(mbi);
-       return mbi.mods_addr;
+       /* Get our own copy boot params pointed to by ebx.
+        * Here we find out whether we should do serial output.
+        */
+       get_parameters(ebx, &kinfo);
+       
+       /* Say hello. */
+       printf("MINIX loading\n");
+
+       assert(magic == MULTIBOOT_BOOTLOADER_MAGIC);
+
+       /* Make and load a pagetable that will map the kernel
+        * to where it should be; but first a 1:1 mapping so
+        * this code stays where it should be.
+        */
+       pg_clear();
+       pg_identity();
+       kinfo.freepde_start = pg_mapkernel();
+       pg_load();
+       vm_enable_paging();
+
+       /* Done, return boot info so it can be passed to kmain(). */
+       return &kinfo;
 }
+
+int send_sig(endpoint_t proc_nr, int sig_nr) { return 0; }
+void minix_shutdown(timer_t *t) { arch_shutdown(RBT_PANIC); }
+void busy_delay_ms(int x) { }
index 835a6f64917fc2bedf49612dd249a6cfb2b75208..a0264d03a4514e827b6b4e4bdf902056d3e6077a 100644 (file)
@@ -3,10 +3,6 @@ include "kernel.h"
 include "proc.h"
 
 struct proc
-member GSREG p_reg.gs
-member FSREG p_reg.fs
-member ESREG p_reg.es
-member DSREG p_reg.ds
 member DIREG p_reg.di
 member SIREG p_reg.si
 member BPREG p_reg.fp
@@ -20,9 +16,4 @@ member PCREG p_reg.pc
 member CSREG p_reg.cs
 member PSWREG p_reg.psw
 member SPREG p_reg.sp
-member SSREG p_reg.ss
-member P_LDT_SEL p_seg.p_ldt_sel
 member P_CR3 p_seg.p_cr3
-member P_CR3_V p_seg.p_cr3_v
-member P_LDT p_seg.p_ldt
-
index 4c5949d0ac66164f54b5db5603c6e1075f8077fa..8efa837f0a4a612650456596ffa5f84da70bd61b 100644 (file)
@@ -3,19 +3,23 @@
  * for local descriptors in the process table.
  */
 
+#include <string.h>
+#include <assert.h>
+#include <machine/multiboot.h>
+
 #include "kernel/kernel.h"
 #include "kernel/proc.h"
 #include "archconst.h"
 
 #include "arch_proto.h"
 
+#include <libexec.h>
+
 #define INT_GATE_TYPE  (INT_286_GATE | DESC_386_BIT)
 #define TSS_TYPE       (AVL_286_TSS  | DESC_386_BIT)
 
-struct desctableptr_s {
-  char limit[sizeof(u16_t)];
-  char base[sizeof(u32_t)];            /* really u24_t + pad for 286 */
-};
+/* This is OK initially, when the 1:1 mapping is still there. */
+char *video_mem = (char *) MULTIBOOT_VIDEO_BUFFER;
 
 struct gatedesc_s {
   u16_t offset_low;
@@ -23,27 +27,20 @@ struct gatedesc_s {
   u8_t pad;                    /* |000|XXXXX| ig & trpg, |XXXXXXXX| task g */
   u8_t p_dpl_type;             /* |P|DL|0|TYPE| */
   u16_t offset_high;
-};
+} __attribute__((packed));
 
+/* Storage for gdt, idt and tss. */
+static struct segdesc_s gdt[GDT_SIZE] __aligned(DESC_SIZE);
+struct gatedesc_s idt[IDT_SIZE] __aligned(DESC_SIZE);
+struct tss_s tss[CONFIG_MAX_CPUS];
 
-/* used in klib.s and mpx.s */
-struct segdesc_s gdt[GDT_SIZE] __aligned(DESC_SIZE) =
-{      {0},
-       {0,0,0,0},                              /* GDT descriptor */
-       {0,0,0,0},                              /* IDT descriptor */
-       {0xffff,0,0,0x93,0xcf,0},       /* kernel DS */
-       {0xffff,0,0,0x93,0xcf,0},       /* kernel ES (386: flag 4 Gb at startup) */
-       {0xffff,0,0,0x93,0xcf,0},       /* kernel SS (386: monitor SS at startup) */
-       {0xffff,0,0,0x9b,0xcf,0},       /* kernel CS */
-       {0xffff,0,0,0x9b,0xcf,0},       /* temp for BIOS (386: monitor CS at startup) */
-};
-
-/* zero-init so none present */
-static struct gatedesc_s idt[IDT_SIZE] __aligned(DESC_SIZE);
-struct tss_s tss[CONFIG_MAX_CPUS];                     /* zero init */
-
-static void sdesc(struct segdesc_s *segdp, phys_bytes base, vir_bytes
-       size);
+phys_bytes vir2phys(void *vir)
+{
+       extern char _kern_vir_base, _kern_phys_base;    /* in kernel.lds */
+       u32_t offset = (vir_bytes) &_kern_vir_base -
+               (vir_bytes) &_kern_phys_base;
+       return (phys_bytes)vir - offset;
+}
 
 /*===========================================================================*
  *                             enable_iop                                   * 
@@ -58,51 +55,60 @@ void enable_iop(struct proc *pp)
   pp->p_reg.psw |= 0x3000;
 }
 
+
 /*===========================================================================*
- *                             seg2phys                                     *
+ *                             sdesc                                        *
  *===========================================================================*/
-phys_bytes seg2phys(const u16_t seg)
+ void sdesc(struct segdesc_s *segdp, phys_bytes base, vir_bytes size)
 {
-/* Return the base address of a segment, with seg being a 
- * register, or a 286/386 segment selector.
- */
-  phys_bytes base;
-  struct segdesc_s *segdp;
-
-  segdp = &gdt[seg >> 3];
-  base =    ((u32_t) segdp->base_low << 0)
-       | ((u32_t) segdp->base_middle << 16)
-       | ((u32_t) segdp->base_high << 24);
-  return base;
+/* Fill in the size fields (base, limit and granularity) of a descriptor. */
+  segdp->base_low = base;
+  segdp->base_middle = base >> BASE_MIDDLE_SHIFT;
+  segdp->base_high = base >> BASE_HIGH_SHIFT;
+
+  --size;                      /* convert to a limit, 0 size means 4G */
+  if (size > BYTE_GRAN_MAX) {
+       segdp->limit_low = size >> PAGE_GRAN_SHIFT;
+       segdp->granularity = GRANULAR | (size >>
+                            (PAGE_GRAN_SHIFT + GRANULARITY_SHIFT));
+  } else {
+       segdp->limit_low = size;
+       segdp->granularity = size >> GRANULARITY_SHIFT;
+  }
+  segdp->granularity |= DEFAULT;       /* means BIG for data seg */
 }
 
 /*===========================================================================*
  *                             init_dataseg                                 *
  *===========================================================================*/
-void init_dataseg(register struct segdesc_s *segdp,
+void init_param_dataseg(register struct segdesc_s *segdp,
        phys_bytes base, vir_bytes size, const int privilege)
 {
        /* Build descriptor for a data segment. */
        sdesc(segdp, base, size);
        segdp->access = (privilege << DPL_SHIFT) | (PRESENT | SEGMENT |
-               WRITEABLE);
+               WRITEABLE | ACCESSED);
                /* EXECUTABLE = 0, EXPAND_DOWN = 0, ACCESSED = 0 */
 }
 
+void init_dataseg(int index, const int privilege)
+{
+       init_param_dataseg(&gdt[index], 0, 0xFFFFFFFF, privilege);
+}
+
 /*===========================================================================*
  *                             init_codeseg                                 *
  *===========================================================================*/
-static void init_codeseg(register struct segdesc_s *segdp, phys_bytes base,
-       vir_bytes size, int privilege)
+static void init_codeseg(int index, int privilege)
 {
        /* Build descriptor for a code segment. */
-       sdesc(segdp, base, size);
-       segdp->access = (privilege << DPL_SHIFT)
+       sdesc(&gdt[index], 0, 0xFFFFFFFF);
+       gdt[index].access = (privilege << DPL_SHIFT)
                | (PRESENT | SEGMENT | EXECUTABLE | READABLE);
                /* CONFORMING = 0, ACCESSED = 0 */
 }
 
-struct gate_table_s gate_table_pic[] = {
+static struct gate_table_s gate_table_pic[] = {
        { hwint00, VECTOR( 0), INTR_PRIVILEGE },
        { hwint01, VECTOR( 1), INTR_PRIVILEGE },
        { hwint02, VECTOR( 2), INTR_PRIVILEGE },
@@ -122,17 +128,47 @@ struct gate_table_s gate_table_pic[] = {
        { NULL, 0, 0}
 };
 
-void tss_init(unsigned cpu, void * kernel_stack)
+static struct gate_table_s gate_table_exceptions[] = {
+       { divide_error, DIVIDE_VECTOR, INTR_PRIVILEGE },
+       { single_step_exception, DEBUG_VECTOR, INTR_PRIVILEGE },
+       { nmi, NMI_VECTOR, INTR_PRIVILEGE },
+       { breakpoint_exception, BREAKPOINT_VECTOR, USER_PRIVILEGE },
+       { overflow, OVERFLOW_VECTOR, USER_PRIVILEGE },
+       { bounds_check, BOUNDS_VECTOR, INTR_PRIVILEGE },
+       { inval_opcode, INVAL_OP_VECTOR, INTR_PRIVILEGE },
+       { copr_not_available, COPROC_NOT_VECTOR, INTR_PRIVILEGE },
+       { double_fault, DOUBLE_FAULT_VECTOR, INTR_PRIVILEGE },
+       { copr_seg_overrun, COPROC_SEG_VECTOR, INTR_PRIVILEGE },
+       { inval_tss, INVAL_TSS_VECTOR, INTR_PRIVILEGE },
+       { segment_not_present, SEG_NOT_VECTOR, INTR_PRIVILEGE },
+       { stack_exception, STACK_FAULT_VECTOR, INTR_PRIVILEGE },
+       { general_protection, PROTECTION_VECTOR, INTR_PRIVILEGE },
+       { page_fault, PAGE_FAULT_VECTOR, INTR_PRIVILEGE },
+       { copr_error, COPROC_ERR_VECTOR, INTR_PRIVILEGE },
+       { alignment_check, ALIGNMENT_CHECK_VECTOR, INTR_PRIVILEGE },
+       { machine_check, MACHINE_CHECK_VECTOR, INTR_PRIVILEGE },
+       { simd_exception, SIMD_EXCEPTION_VECTOR, INTR_PRIVILEGE },
+       { ipc_entry, IPC_VECTOR, USER_PRIVILEGE },
+       { kernel_call_entry, KERN_CALL_VECTOR, USER_PRIVILEGE },
+       { NULL, 0, 0}
+};
+
+int tss_init(unsigned cpu, void * kernel_stack)
 {
        struct tss_s * t = &tss[cpu];
+       int index = TSS_INDEX(cpu);
+       struct segdesc_s *tssgdt;
+
+       tssgdt = &gdt[index];
   
-       t->ss0 = DS_SELECTOR;
-       init_dataseg(&gdt[TSS_INDEX(cpu)], vir2phys(t),
+       init_param_dataseg(tssgdt, (phys_bytes) t,
                        sizeof(struct tss_s), INTR_PRIVILEGE);
-       gdt[TSS_INDEX(cpu)].access = PRESENT |
-               (INTR_PRIVILEGE << DPL_SHIFT) | TSS_TYPE;
+       tssgdt->access = PRESENT | (INTR_PRIVILEGE << DPL_SHIFT) | TSS_TYPE;
 
-       /* Complete building of main TSS. */
+       /* Build TSS. */
+       memset(t, 0, sizeof(*t));
+       t->ds = t->es = t->fs = t->gs = t->ss0 = KERN_DS_SELECTOR;
+       t->cs = KERN_CS_SELECTOR;
        t->iobase = sizeof(struct tss_s);       /* empty i/o permissions map */
 
        /* 
@@ -145,344 +181,203 @@ void tss_init(unsigned cpu, void * kernel_stack)
         * this stak in use when we trap to kernel
         */
        *((reg_t *)(t->sp0 + 1 * sizeof(reg_t))) = cpu;
+
+       return SEG_SELECTOR(index);
 }
 
-/*===========================================================================*
- *                             prot_init                                    *
- *===========================================================================*/
-void prot_init(void)
+phys_bytes init_segdesc(int gdt_index, void *base, int size)
 {
-/* Set up tables for protected mode.
- * All GDT slots are allocated at compile time.
- */
-  struct desctableptr_s *dtp;
-  unsigned ldt_index;
-  register struct proc *rp;
-
-  /* Click-round kernel. */
-  if(kinfo.data_base % CLICK_SIZE)
-       panic("kinfo.data_base not aligned");
-  kinfo.data_size = (phys_bytes) (CLICK_CEIL(kinfo.data_size));
-
-  /* Build gdt and idt pointers in GDT where the BIOS expects them. */
-  dtp= (struct desctableptr_s *) &gdt[GDT_INDEX];
-  * (u16_t *) dtp->limit = (sizeof gdt) - 1;
-  * (u32_t *) dtp->base = vir2phys(gdt);
-
-  dtp= (struct desctableptr_s *) &gdt[IDT_INDEX];
-  * (u16_t *) dtp->limit = (sizeof idt) - 1;
-  * (u32_t *) dtp->base = vir2phys(idt);
-
-  /* Build segment descriptors for tasks and interrupt handlers. */
-  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, INTR_PRIVILEGE);
-
-  /* Build local descriptors in GDT for LDT's in process table.
-   * The LDT's are allocated at compile time in the process table, and
-   * initialized whenever a process' map is initialized or changed.
-   */
-  for (rp = BEG_PROC_ADDR, ldt_index = FIRST_LDT_INDEX;
-       rp < END_PROC_ADDR; ++rp, ldt_index++) {
-       init_dataseg(&gdt[ldt_index], vir2phys(rp->p_seg.p_ldt),
-                                    sizeof(rp->p_seg.p_ldt), INTR_PRIVILEGE);
-       gdt[ldt_index].access = PRESENT | LDT;
-       rp->p_seg.p_ldt_sel = ldt_index * DESC_SIZE;
-  }
+       struct desctableptr_s *dtp = (struct desctableptr_s *) &gdt[gdt_index];
+       dtp->limit = size - 1;
+       dtp->base = (phys_bytes) base;
+
+       return (phys_bytes) dtp;
+}
+
+void int_gate(struct gatedesc_s *tab,
+       unsigned vec_nr, vir_bytes offset, unsigned dpl_type)
+{
+/* Build descriptor for an interrupt gate. */
+  register struct gatedesc_s *idp;
+
+  idp = &tab[vec_nr];
+  idp->offset_low = offset;
+  idp->selector = KERN_CS_SELECTOR;
+  idp->p_dpl_type = dpl_type;
+  idp->offset_high = offset >> OFFSET_HIGH_SHIFT;
+}
 
-  /* Build boot TSS */
-  tss_init(0, &k_boot_stktop);
+void int_gate_idt(unsigned vec_nr, vir_bytes offset, unsigned dpl_type)
+{
+       int_gate(idt, vec_nr, offset, dpl_type);
 }
 
 void idt_copy_vectors(struct gate_table_s * first)
 {
        struct gate_table_s *gtp;
        for (gtp = first; gtp->gate; gtp++) {
-               int_gate(gtp->vec_nr, (vir_bytes) gtp->gate,
+               int_gate(idt, gtp->vec_nr, (vir_bytes) gtp->gate,
                                PRESENT | INT_GATE_TYPE |
                                (gtp->privilege << DPL_SHIFT));
        }
 }
 
-/* Build descriptors for interrupt gates in IDT. */
-void idt_init(void)
+void idt_copy_vectors_pic(void)
 {
-       struct gate_table_s gate_table[] = {
-               { divide_error, DIVIDE_VECTOR, INTR_PRIVILEGE },
-               { single_step_exception, DEBUG_VECTOR, INTR_PRIVILEGE },
-               { nmi, NMI_VECTOR, INTR_PRIVILEGE },
-               { breakpoint_exception, BREAKPOINT_VECTOR, USER_PRIVILEGE },
-               { overflow, OVERFLOW_VECTOR, USER_PRIVILEGE },
-               { bounds_check, BOUNDS_VECTOR, INTR_PRIVILEGE },
-               { inval_opcode, INVAL_OP_VECTOR, INTR_PRIVILEGE },
-               { copr_not_available, COPROC_NOT_VECTOR, INTR_PRIVILEGE },
-               { double_fault, DOUBLE_FAULT_VECTOR, INTR_PRIVILEGE },
-               { copr_seg_overrun, COPROC_SEG_VECTOR, INTR_PRIVILEGE },
-               { inval_tss, INVAL_TSS_VECTOR, INTR_PRIVILEGE },
-               { segment_not_present, SEG_NOT_VECTOR, INTR_PRIVILEGE },
-               { stack_exception, STACK_FAULT_VECTOR, INTR_PRIVILEGE },
-               { general_protection, PROTECTION_VECTOR, INTR_PRIVILEGE },
-               { page_fault, PAGE_FAULT_VECTOR, INTR_PRIVILEGE },
-               { copr_error, COPROC_ERR_VECTOR, INTR_PRIVILEGE },
-               { alignment_check, ALIGNMENT_CHECK_VECTOR, INTR_PRIVILEGE },
-               { machine_check, MACHINE_CHECK_VECTOR, INTR_PRIVILEGE },
-               { simd_exception, SIMD_EXCEPTION_VECTOR, INTR_PRIVILEGE },
-               { ipc_entry, IPC_VECTOR, USER_PRIVILEGE },
-               { kernel_call_entry, KERN_CALL_VECTOR, USER_PRIVILEGE },
-               { NULL, 0, 0}
-       };
-
-       idt_copy_vectors(gate_table);
        idt_copy_vectors(gate_table_pic);
 }
 
-
-/*===========================================================================*
- *                             sdesc                                        *
- *===========================================================================*/
-static void sdesc(segdp, base, size)
-register struct segdesc_s *segdp;
-phys_bytes base;
-vir_bytes size;
+void idt_init(void)
 {
-/* Fill in the size fields (base, limit and granularity) of a descriptor. */
-  segdp->base_low = base;
-  segdp->base_middle = base >> BASE_MIDDLE_SHIFT;
-  segdp->base_high = base >> BASE_HIGH_SHIFT;
-
-  --size;                      /* convert to a limit, 0 size means 4G */
-  if (size > BYTE_GRAN_MAX) {
-       segdp->limit_low = size >> PAGE_GRAN_SHIFT;
-       segdp->granularity = GRANULAR | (size >>
-                                    (PAGE_GRAN_SHIFT + GRANULARITY_SHIFT));
-  } else {
-       segdp->limit_low = size;
-       segdp->granularity = size >> GRANULARITY_SHIFT;
-  }
-  segdp->granularity |= DEFAULT;       /* means BIG for data seg */
+       idt_copy_vectors_pic();
+       idt_copy_vectors(gate_table_exceptions);
 }
 
-/*===========================================================================*
- *                             int_gate                                     *
- *===========================================================================*/
-void int_gate(unsigned vec_nr, vir_bytes offset, unsigned dpl_type)
-{
-/* Build descriptor for an interrupt gate. */
-  register struct gatedesc_s *idp;
+struct desctableptr_s gdt_desc, idt_desc;
 
-  idp = &idt[vec_nr];
-  idp->offset_low = offset;
-  idp->selector = CS_SELECTOR;
-  idp->p_dpl_type = dpl_type;
-  idp->offset_high = offset >> OFFSET_HIGH_SHIFT;
-}
-
-/*===========================================================================*
- *                             alloc_segments                               *
- *===========================================================================*/
-void alloc_segments(register struct proc *rp)
+void idt_reload(void)
 {
-/* This is called at system initialization from main() and by do_newmap(). 
- * The code has a separate function because of all hardware-dependencies.
- */
-  phys_bytes code_bytes;
-  phys_bytes data_bytes;
-  phys_bytes text_vaddr, data_vaddr;
-  phys_bytes text_segbase, data_segbase;
-  int privilege;
-
-      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 = USER_PRIVILEGE;
-
-      text_vaddr = rp->p_memmap[T].mem_vir << CLICK_SHIFT;
-      data_vaddr = rp->p_memmap[D].mem_vir << CLICK_SHIFT;
-      text_segbase = (rp->p_memmap[T].mem_phys -
-                     rp->p_memmap[T].mem_vir) << CLICK_SHIFT;
-      data_segbase = (rp->p_memmap[D].mem_phys -
-                     rp->p_memmap[D].mem_vir) << CLICK_SHIFT;
-
-      init_codeseg(&rp->p_seg.p_ldt[CS_LDT_INDEX],
-                  text_segbase,
-                  text_vaddr + code_bytes, privilege);
-      init_dataseg(&rp->p_seg.p_ldt[DS_LDT_INDEX],
-                  data_segbase,
-                  data_vaddr + data_bytes, privilege);
-      rp->p_reg.cs = (CS_LDT_INDEX * DESC_SIZE) | TI | privilege;
-      rp->p_reg.gs =
-      rp->p_reg.fs =
-      rp->p_reg.ss =
-      rp->p_reg.es =
-      rp->p_reg.ds = (DS_LDT_INDEX*DESC_SIZE) | TI | privilege;
+       x86_lidt(&idt_desc);
 }
 
-#if 0
-/*===========================================================================*
- *                             check_segments                               *
- *===========================================================================*/
-static void check_segments(char *File, int line)
+multiboot_module_t *bootmod(int pnr)
 {
-  int checked = 0;
-int fail = 0;
-struct proc *rp;
-for (rp = BEG_PROC_ADDR; rp < END_PROC_ADDR; ++rp) {
-
-  int privilege;
-  int cs, ds;
-
-               if (isemptyp(rp))
-                       continue;
+       int i;
 
-       privilege = USER_PRIVILEGE;
+       assert(pnr >= 0);
 
-       cs = (CS_LDT_INDEX*DESC_SIZE) | TI | privilege;
-       ds = (DS_LDT_INDEX*DESC_SIZE) | TI | privilege;
-
-#define CHECK(s1, s2) if(s1 != s2) {           \
-       printf("%s:%d: " #s1 " != " #s2 " for ep %d\n", \
-               File, line, rp->p_endpoint); fail++; } checked++;
-
-       CHECK(rp->p_reg.cs, cs);
-       CHECK(rp->p_reg.gs, ds);
-       CHECK(rp->p_reg.fs, ds);
-       CHECK(rp->p_reg.ss, ds);
-       if(rp->p_endpoint != SYSTEM) {
-               CHECK(rp->p_reg.es, ds);
+       /* Search for desired process in boot process
+        * list. The first NR_TASKS ones do not correspond
+        * to a module, however, so we don't search those.
+        */
+       for(i = NR_TASKS; i < NR_BOOT_PROCS; i++) {
+               int p;
+               p = i - NR_TASKS;
+               if(image[i].proc_nr == pnr) {
+                       assert(p < MULTIBOOT_MAX_MODS);
+                       assert(p < kinfo.mbi.mods_count);
+                       return &kinfo.module_list[p];
+               }
        }
-       CHECK(rp->p_reg.ds, ds);
-     }
-     if(fail) {
-       printf("%d/%d checks failed\n", fail, checked);
-       panic("wrong: %d",  fail);
-     }
+
+       panic("boot module %d not found", pnr);
 }
-#endif
 
 /*===========================================================================*
- *                             printseg                             *
+ *                             prot_init                                    *
  *===========================================================================*/
-void printseg(char *banner, const int iscs, struct proc *pr,
-  const u32_t selector)
+void prot_init()
 {
-#if USE_SYSDEBUG
-       u32_t base, limit, index, dpl;
-       struct segdesc_s *desc;
-
-       if(banner) { printf("%s", banner); }
-
-       index = selector >> 3;
-
-       printf("RPL %d, ind %d of ",
-               (selector & RPL_MASK), index);
-
-       if(selector & TI) {
-               printf("LDT");
-               if(index >= LDT_SIZE) {
-                       printf("invalid index in ldt\n");
-                       return;
-               }
-               if(!pr) {
-                       printf("local selector but unknown process\n");
-                       return;
-               }
-               desc = &pr->p_seg.p_ldt[index];
-       } else {
-               printf("GDT");
-               if(index >= GDT_SIZE) {
-                       printf("invalid index in gdt\n");
-                       return;
-               }
-               desc = &gdt[index];
-       }
-
-       limit = desc->limit_low |
-               (((u32_t) desc->granularity & LIMIT_HIGH) << GRANULARITY_SHIFT);
-
-       if(desc->granularity & GRANULAR) {
-               limit = (limit << PAGE_GRAN_SHIFT) + 0xfff;
-       }
-
-       base = desc->base_low | 
-               ((u32_t) desc->base_middle << BASE_MIDDLE_SHIFT) |
-               ((u32_t) desc->base_high << BASE_HIGH_SHIFT);
-
-       printf(" -> base 0x%08lx size 0x%08lx ", base, limit+1);
-
-       if(iscs) {
-               if(!(desc->granularity & BIG))
-                       printf("16bit ");
-       } else {
-               if(!(desc->granularity & BIG)) 
-                       printf("not big ");
-       }
-
-       if(desc->granularity & 0x20) {  /* reserved */
-               panic("granularity reserved field set");
-       }
-
-       if(!(desc->access & PRESENT))
-               printf("notpresent ");
-
-       if(!(desc->access & SEGMENT))
-               printf("system ");
-
-       if(desc->access & EXECUTABLE) {
-               printf("   exec ");
-               if(desc->access & CONFORMING) printf("conforming ");
-               if(!(desc->access & READABLE)) printf("non-readable ");
-       } else {
-               printf("nonexec ");
-               if(desc->access & EXPAND_DOWN) printf("non-expand-down ");
-               if(!(desc->access & WRITEABLE)) printf("non-writable ");
-       }
-
-       if(!(desc->access & ACCESSED)) {
-               printf("nonacc ");
-       }
+  int sel_tss;
+  extern char k_boot_stktop;
+
+  memset(gdt, 0, sizeof(gdt));
+  memset(idt, 0, sizeof(idt));
+
+  /* Build GDT, IDT, IDT descriptors. */
+  gdt_desc.base = (u32_t) gdt;
+  gdt_desc.limit = sizeof(gdt)-1;
+  idt_desc.base = (u32_t) idt;
+  idt_desc.limit = sizeof(idt)-1;
+  sel_tss = tss_init(0, &k_boot_stktop);
+
+  /* Build GDT */
+  init_param_dataseg(&gdt[LDT_INDEX],
+    (phys_bytes) 0, 0, INTR_PRIVILEGE); /* unusable LDT */
+  gdt[LDT_INDEX].access = PRESENT | LDT;
+  init_codeseg(KERN_CS_INDEX, INTR_PRIVILEGE);
+  init_dataseg(KERN_DS_INDEX, INTR_PRIVILEGE);
+  init_codeseg(USER_CS_INDEX, USER_PRIVILEGE);
+  init_dataseg(USER_DS_INDEX, USER_PRIVILEGE);
+
+  x86_lgdt(&gdt_desc); /* Load gdt */ 
+  idt_init();
+  idt_reload();
+  x86_lldt(LDT_SELECTOR);      /* Load bogus ldt */
+  x86_ltr(sel_tss);    /* Load global TSS */
+
+  /* Currently the multiboot segments are loaded; which is fine, but
+   * let's replace them with the ones from our own GDT so we test
+   * right away whether they work as expected.
+   */
+  x86_load_kerncs();
+  x86_load_ds(KERN_DS_SELECTOR);
+  x86_load_es(KERN_DS_SELECTOR);
+  x86_load_fs(KERN_DS_SELECTOR);
+  x86_load_gs(KERN_DS_SELECTOR);
+  x86_load_ss(KERN_DS_SELECTOR);
+
+  /* Set up a new post-relocate bootstrap pagetable so that
+   * we can map in VM, and we no longer rely on pre-relocated
+   * data.
+   */
 
-       dpl = ((u32_t) desc->access & DPL) >> DPL_SHIFT;
+  pg_clear();
+  pg_identity(); /* Still need 1:1 for lapic and video mem and such. */
+  pg_mapkernel();
+  pg_load();
+  bootstrap_pagetable_done = 1;        /* secondary CPU's can use it too */
+}
 
-       printf("DPL %d\n", dpl);
+void arch_post_init(void)
+{
+  /* Let memory mapping code know what's going on at bootstrap time */
+  struct proc *vm;
+  vm = proc_addr(VM_PROC_NR);
+  get_cpulocal_var(ptproc) = vm;
+  pg_info(&vm->p_seg.p_cr3, &vm->p_seg.p_cr3_v);
+}
 
-       return;
-#endif /* USE_SYSDEBUG */
+int libexec_pg_alloc(struct exec_info *execi, off_t vaddr, size_t len)
+{
+        pg_map(PG_ALLOCATEME, vaddr, vaddr+len, &kinfo);
+       pg_load();
+        memset((char *) vaddr, 0, len);
+        return OK;
 }
 
-/*===========================================================================*
- *                             prot_set_kern_seg_limit                      *
- *===========================================================================*/
-int prot_set_kern_seg_limit(const vir_bytes limit)
+void arch_boot_proc(struct boot_image *ip, struct proc *rp)
 {
-       struct proc *rp;
-       int orig_click;
-       int incr_clicks;
+       multiboot_module_t *mod;
 
-       if(limit <= kinfo.data_base) {
-               printf("prot_set_kern_seg_limit: limit bogus\n");
-               return EINVAL;
-       }
+       if(rp->p_nr < 0) return;
 
-       /* Do actual increase. */
-       orig_click = kinfo.data_size / CLICK_SIZE;
-       kinfo.data_size = limit - kinfo.data_base;
-       incr_clicks = kinfo.data_size / CLICK_SIZE - orig_click;
+       mod = bootmod(rp->p_nr);
 
-       prot_init();
+       /* Important special case: we put VM in the bootstrap pagetable
+        * so it can run.
+        */
 
-       /* Increase kernel processes too. */
-       for (rp = BEG_PROC_ADDR; rp < END_PROC_ADDR; ++rp) {
-               if (isemptyp(rp) || !iskernelp(rp))
-                       continue;
-               rp->p_memmap[S].mem_len += incr_clicks;
-               alloc_segments(rp);
-               rp->p_memmap[S].mem_len -= incr_clicks;
+       if(rp->p_nr == VM_PROC_NR) {
+               struct exec_info execi;
+
+               memset(&execi, 0, sizeof(execi));
+
+               /* exec parameters */
+               execi.stack_high = kinfo.user_sp;
+               execi.stack_size = 16 * 1024;   /* not too crazy as it must be preallocated */
+               execi.proc_e = ip->endpoint;
+               execi.hdr = (char *) mod->mod_start; /* phys mem direct */
+               execi.hdr_len = mod->mod_end - mod->mod_start;
+               strcpy(execi.progname, ip->proc_name);
+               execi.frame_len = 0;
+
+               /* callbacks for use in the kernel */
+               execi.copymem = libexec_copy_memcpy;
+               execi.clearmem = libexec_clear_memset;
+               execi.allocmem_prealloc = libexec_pg_alloc;
+               execi.allocmem_ondemand = libexec_pg_alloc;
+               execi.clearproc = NULL;
+
+               /* parse VM ELF binary and alloc/map it into bootstrap pagetable */
+               libexec_load_elf(&execi);
+
+               /* Initialize the server stack pointer. Take it down three words
+                * to give startup code something to use as "argc", "argv" and "envp".
+                */
+               arch_proc_init(rp, execi.pc, kinfo.user_sp - 3*4, ip->proc_name);
+
+               /* Free VM blob that was just copied into existence. */
+               cut_memmap(&kinfo, mod->mod_start, mod->mod_end);
        }
-
-       return OK;
 }
index c0108185ef46122897bbcff7864471be8f3a5f73..1262f6cd62ffdc05fca368126c469e6358498081 100644 (file)
@@ -17,7 +17,7 @@
  * zeroed
  */
 #define TEST_INT_IN_KERNEL(displ, label)       \
-       cmpl    $CS_SELECTOR, displ(%esp)       ;\
+       cmpl    $KERN_CS_SELECTOR, displ(%esp)  ;\
        je      label                           ;
 
 /*
        movl    tmp, PSWREG(pptr)                       ;\
        movl    (12 + displ)(%esp), tmp                 ;\
        movl    tmp, SPREG(pptr)                        ;\
-       movl    tmp, STREG(pptr)                        ;\
-       movl    (16 + displ)(%esp), tmp                 ;\
-       movl    tmp, SSREG(pptr)                        ;
-
-#define SAVE_SEGS(pptr)                \
-       mov     %ds, %ss:DSREG(pptr)    ;\
-       mov     %es, %ss:ESREG(pptr)    ;\
-       mov     %fs, %ss:FSREG(pptr)    ;\
-       mov     %gs, %ss:GSREG(pptr)    ;
-
-#define RESTORE_SEGS(pptr)             \
-       movw    %ss:DSREG(pptr), %ds    ;\
-       movw    %ss:ESREG(pptr), %es    ;\
-       movw    %ss:FSREG(pptr), %fs    ;\
-       movw    %ss:GSREG(pptr), %gs    ;
+       movl    tmp, STREG(pptr)
 
 /*
- * restore kernel segments, %ss is kernnel data segment, %cs is aready set and
- * %fs, %gs are not used
- */
+ * restore kernel segments. %cs is aready set and %fs, %gs are not used */
 #define RESTORE_KERNEL_SEGS    \
-       mov     %ss, %si        ;\
+       mov     $KERN_DS_SELECTOR, %si  ;\
        mov     %si, %ds        ;\
        mov     %si, %es        ;\
        movw    $0, %si         ;\
        mov     %si, %fs        ;
 
 #define SAVE_GP_REGS(pptr)     \
-       mov     %eax, %ss:AXREG(pptr)           ;\
-       mov     %ecx, %ss:CXREG(pptr)           ;\
-       mov     %edx, %ss:DXREG(pptr)           ;\
-       mov     %ebx, %ss:BXREG(pptr)           ;\
-       mov     %esi, %ss:SIREG(pptr)           ;\
-       mov     %edi, %ss:DIREG(pptr)           ;
+       mov     %eax, AXREG(pptr)               ;\
+       mov     %ecx, CXREG(pptr)               ;\
+       mov     %edx, DXREG(pptr)               ;\
+       mov     %ebx, BXREG(pptr)               ;\
+       mov     %esi, SIREG(pptr)               ;\
+       mov     %edi, DIREG(pptr)               ;
 
 #define RESTORE_GP_REGS(pptr)  \
-       movl    %ss:AXREG(pptr), %eax           ;\
-       movl    %ss:CXREG(pptr), %ecx           ;\
-       movl    %ss:DXREG(pptr), %edx           ;\
-       movl    %ss:BXREG(pptr), %ebx           ;\
-       movl    %ss:SIREG(pptr), %esi           ;\
-       movl    %ss:DIREG(pptr), %edi           ;
+       movl    AXREG(pptr), %eax               ;\
+       movl    CXREG(pptr), %ecx               ;\
+       movl    DXREG(pptr), %edx               ;\
+       movl    BXREG(pptr), %ebx               ;\
+       movl    SIREG(pptr), %esi               ;\
+       movl    DIREG(pptr), %edi               ;
 
 /*
  * save the context of the interrupted process to the structure in the process
                                                        ;\
        movl    (CURR_PROC_PTR + 4 + displ)(%esp), %ebp ;\
                                                        \
-       /* save the segment registers */                \
-       SAVE_SEGS(%ebp)                                 ;\
-                                                       \
        SAVE_GP_REGS(%ebp)                              ;\
        pop     %esi                    /* get the orig %ebp and save it */ ;\
-       mov     %esi, %ss:BPREG(%ebp)                   ;\
+       mov     %esi, BPREG(%ebp)                       ;\
                                                        \
        RESTORE_KERNEL_SEGS                             ;\
        SAVE_TRAP_CTX(displ, %ebp, %esi)                ;
index 43d0c709cf59256d9ccfb0c3c074f32d41c923b6..a03aedbf80cd7bc0cfc58dcd6706a3c5775203c3 100644 (file)
@@ -20,7 +20,7 @@ ENTRY(trampoline)
        orb     $1, %al
        mov     %eax, %cr0
 
-       ljmpl   $CS_SELECTOR, $_C_LABEL(startup_ap_32)
+       ljmpl   $KERN_CS_SELECTOR, $_C_LABEL(startup_ap_32)
 
 .balign 4
 LABEL(__ap_id)
index 5571da27e64daa11ee55fc387e8ff6acfd5ad185..1049d6b55564de43fa623de786a747e36941fcbe 100644 (file)
@@ -141,7 +141,7 @@ int timer_int_handler(void)
                }
 
 #ifdef DEBUG_SERIAL
-               if (do_serial_debug)
+               if (kinfo.do_serial_debug)
                        do_ser_debug();
 #endif
 
index a3dd15219cbfcdef3e7514027906b5ff488f55ca..55c24a09f44a79ea07850b873a98e23fa8a53c3f 100644 (file)
 #define USE_MEMSET        1    /* write char to a given memory area */
 #define USE_RUNCTL         1   /* control stop flags of a process */
 
-/* Length of program names stored in the process table. This is only used
- * for the debugging dumps that can be generated with the IS server. The PM
- * server keeps its own copy of the program name.  
- */
-#define P_NAME_LEN        8
-
 /* This section contains defines for valuable system resources that are used
  * by device drivers. The number of elements of the vectors is determined by 
  * the maximum needed by any given driver. The number of interrupt hooks may
index 16857462b9640ccf906d6bdcfd2f0e19674376a3..7e7e3da9b859f47d41523bd9db0778c130e9172c 100644 (file)
 #define unset_sys_bit(map,bit) \
        ( MAP_CHUNK((map).chunk,bit) &= ~(1 << CHUNK_OFFSET(bit) ))
 
-/* args to intr_init() */
-#define INTS_ORIG      0       /* restore interrupts */
-#define INTS_MINIX     1       /* initialize interrupts for minix */
-
 /* for kputc() */
 #define END_OF_KMESS   0
 
index 8c37e32a817e82f76e4916a67accb91d151ec443..f0ac507b074cdb5e48ad3cfa49bdc8ad0cd95e45 100644 (file)
@@ -175,7 +175,6 @@ miscflagstr(const u32_t flags)
        str[0] = '\0';
 
        FLAG(MF_REPLY_PEND);
-       FLAG(MF_FULLVM);
        FLAG(MF_DELIVERMSG);
        FLAG(MF_KCALL_RESUME);
 
index bb0ef72356f69ec31cc22ad649e4323f950ddd38..4bb96da5216c189d15ec7cc00a6a8e28356817f0 100644 (file)
@@ -22,7 +22,6 @@
 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 char kmess_buf[80*25];          /* printable copy of message buffer */
 EXTERN struct k_randomness krandom;    /* gather kernel random information */
 EXTERN struct loadinfo kloadinfo;      /* status of load average */
 
@@ -40,14 +39,8 @@ EXTERN int irq_use;                          /* map of all in-use irq's */
 EXTERN u32_t system_hz;                                /* HZ value */
 
 /* Miscellaneous. */
-EXTERN int do_serial_debug;
-EXTERN int serial_debug_baud;
 EXTERN time_t boottime;
-EXTERN char params_buffer[512];                /* boot monitor parameters */
-EXTERN int minix_panicing;
 EXTERN int verboseboot;                        /* verbose boot, init'ed in cstart */
-#define MAGICTEST 0xC0FFEE23
-EXTERN u32_t magictest;                        /* global magic number */
 
 #if DEBUG_TRACE
 EXTERN int verboseflags;
@@ -66,14 +59,14 @@ EXTERN u64_t cpu_hz[CONFIG_MAX_CPUS];
 #ifdef CONFIG_SMP
 EXTERN int config_no_smp; /* optionaly turn off SMP */
 #endif
+EXTERN int bootstrap_pagetable_done;
 
 /* VM */
 EXTERN int vm_running;
 EXTERN int catch_pagefaults;
 
 /* Variables that are initialized elsewhere are just extern here. */
-extern struct boot_image image[];      /* system image processes */
-extern struct segdesc_s gdt[];         /* global descriptor table */
+extern struct boot_image image[NR_BOOT_PROCS];         /* system image processes */
 
 EXTERN volatile int serial_debug_active;
 
@@ -85,4 +78,7 @@ EXTERN u64_t bkl_ticks[CONFIG_MAX_CPUS];
 EXTERN unsigned bkl_tries[CONFIG_MAX_CPUS];
 EXTERN unsigned bkl_succ[CONFIG_MAX_CPUS];
 
+/* Feature flags */
+EXTERN int minix_feature_flags;
+
 #endif /* GLO_H */
index 004948aa3ff3778cd343383c88c0da78272aac73..5cf56e1db569835f340be281cf6fbf65dab72c67 100644 (file)
  */
 #include "kernel.h"
 #include <string.h>
+#include <stdlib.h>
 #include <unistd.h>
 #include <assert.h>
+#include <libexec.h>
 #include <a.out.h>
 #include <minix/com.h>
 #include <minix/endpoint.h>
+#include <machine/vmparam.h>
 #include <minix/u64.h>
+#include <minix/type.h>
 #include "proc.h"
 #include "debug.h"
 #include "clock.h"
@@ -102,35 +106,40 @@ void bsp_finish_booting(void)
   machine.processors_count = 1;
   machine.bsp_id = 0;
 #endif
-  
+
   switch_to_user();
   NOT_REACHABLE;
 }
 
 /*===========================================================================*
- *                             main                                         *
+ *                     kmain                                           *
  *===========================================================================*/
-int main(void)
+void kmain(kinfo_t *local_cbi)
 {
 /* Start the ball rolling. */
   struct boot_image *ip;       /* boot image pointer */
   register struct proc *rp;    /* process pointer */
   register int i, j;
-  size_t argsz;                        /* size of arguments passed to crtso on stack */
+
+  /* save a global copy of the boot parameters */
+  memcpy(&kinfo, local_cbi, sizeof(kinfo));
+  memcpy(&kmess, kinfo.kmess, sizeof(kmess));
+
+  /* We can talk now */
+  printf("MINIX booting\n");
+
+  assert(sizeof(kinfo.boot_procs) == sizeof(image));
+  memcpy(kinfo.boot_procs, image, sizeof(kinfo.boot_procs));
+
+  cstart();
 
   BKL_LOCK();
-   /* Global value to test segment sanity. */
-   magictest = MAGICTEST;
  
    DEBUGEXTRA(("main()\n"));
 
    proc_init();
 
-  /* Set up proc table entries for processes in boot image.  The stacks
-   * of the servers have been added to the data segment by the monitor, so
-   * the stack pointer is set to the end of the data segment.
-   */
-
+  /* Set up proc table entries for processes in boot image. */
   for (i=0; i < NR_BOOT_PROCS; ++i) {
        int schedulable_proc;
        proc_nr_t proc_nr;
@@ -142,7 +151,13 @@ int main(void)
        rp = proc_addr(ip->proc_nr);            /* get process pointer */
        ip->endpoint = rp->p_endpoint;          /* ipc endpoint */
        make_zero64(rp->p_cpu_time_left);
-       strncpy(rp->p_name, ip->proc_name, P_NAME_LEN); /* set process name */
+
+       if(i >= NR_TASKS) {
+               /* Remember this so it can be passed to VM */
+               multiboot_module_t *mb_mod = &kinfo.module_list[i - NR_TASKS];
+               ip->start_addr = mb_mod->mod_start;
+               ip->len = mb_mod->mod_end - mb_mod->mod_start;
+       }
        
        reset_proc_accounting(rp);
 
@@ -154,13 +169,23 @@ int main(void)
         * process has set their privileges.
         */
        proc_nr = proc_nr(rp);
-       schedulable_proc = (iskerneln(proc_nr) || isrootsysn(proc_nr));
+       schedulable_proc = (iskerneln(proc_nr) || isrootsysn(proc_nr) ||
+               proc_nr == VM_PROC_NR);
        if(schedulable_proc) {
            /* Assign privilege structure. Force a static privilege id. */
             (void) get_priv(rp, static_priv_id(proc_nr));
 
             /* Priviliges for kernel tasks. */
-            if(iskerneln(proc_nr)) {
+           if(proc_nr == VM_PROC_NR) {
+                priv(rp)->s_flags = VM_F;
+                priv(rp)->s_trap_mask = SRV_T;
+               ipc_to_m = SRV_M;
+               kcalls = SRV_KC;
+                priv(rp)->s_sig_mgr = SELF;
+                rp->p_priority = SRV_Q;
+                rp->p_quantum_size_ms = SRV_QT;
+           }
+           else if(iskerneln(proc_nr)) {
                 /* Privilege flags. */
                 priv(rp)->s_flags = (proc_nr == IDLE ? IDL_F : TSK_F);
                 /* Allowed traps. */
@@ -203,64 +228,34 @@ int main(void)
            /* Don't let the process run for now. */
             RTS_SET(rp, RTS_NO_PRIV | RTS_NO_QUANTUM);
        }
-       rp->p_memmap[T].mem_vir  = ABS2CLICK(ip->memmap.text_vaddr);
-       rp->p_memmap[T].mem_phys = ABS2CLICK(ip->memmap.text_paddr);
-       rp->p_memmap[T].mem_len  = ABS2CLICK(ip->memmap.text_bytes);
-       rp->p_memmap[D].mem_vir  = ABS2CLICK(ip->memmap.data_vaddr);
-       rp->p_memmap[D].mem_phys = ABS2CLICK(ip->memmap.data_paddr);
-       rp->p_memmap[D].mem_len  = ABS2CLICK(ip->memmap.data_bytes);
-       rp->p_memmap[S].mem_phys = ABS2CLICK(ip->memmap.data_paddr +
-                                            ip->memmap.data_bytes +
-                                            ip->memmap.stack_bytes);
-       rp->p_memmap[S].mem_vir  = ABS2CLICK(ip->memmap.data_vaddr +
-                                            ip->memmap.data_bytes +
-                                            ip->memmap.stack_bytes);
-       rp->p_memmap[S].mem_len  = 0;
-
-       /* Set initial register values.  The processor status word for tasks 
-        * is different from that of other processes because tasks can
-        * access I/O; this is not allowed to less-privileged processes 
-        */
-       rp->p_reg.pc = ip->memmap.entry;
-       rp->p_reg.psw = (iskerneln(proc_nr)) ? INIT_TASK_PSW : INIT_PSW;
 
-       /* Initialize the server stack pointer. Take it down three words
-        * to give crtso.s something to use as "argc", "argv" and "envp".
-        */
-       if (isusern(proc_nr)) {         /* user-space process? */ 
-               rp->p_reg.sp = (rp->p_memmap[S].mem_vir +
-                               rp->p_memmap[S].mem_len) << CLICK_SHIFT;
-               argsz = 3 * sizeof(reg_t);
-               rp->p_reg.sp -= argsz;
-               phys_memset(rp->p_reg.sp - 
-                       (rp->p_memmap[S].mem_vir << CLICK_SHIFT) +
-                       (rp->p_memmap[S].mem_phys << CLICK_SHIFT), 
-                       0, argsz);
-       }
+       /* Arch-specific state initialization. */
+       arch_boot_proc(ip, rp);
 
        /* scheduling functions depend on proc_ptr pointing somewhere. */
        if(!get_cpulocal_var(proc_ptr))
                get_cpulocal_var(proc_ptr) = rp;
 
-       /* If this process has its own page table, VM will set the
-        * PT up and manage it. VM will signal the kernel when it has
-        * done this; until then, don't let it run.
-        */
-       if(ip->flags & PROC_FULLVM)
+       /* Process isn't scheduled until VM has set up a pagetable for it. */
+       if(rp->p_nr != VM_PROC_NR && rp->p_nr >= 0)
                rp->p_rts_flags |= RTS_VMINHIBIT;
 
        rp->p_rts_flags |= RTS_PROC_STOP;
        rp->p_rts_flags &= ~RTS_SLOT_FREE;
-       alloc_segments(rp);
        DEBUGEXTRA(("done\n"));
   }
 
+  /* update boot procs info for VM */
+  memcpy(kinfo.boot_procs, image, sizeof(kinfo.boot_procs));
+
 #define IPCNAME(n) { \
        assert((n) >= 0 && (n) <= IPCNO_HIGHEST); \
        assert(!ipc_call_names[n]);     \
        ipc_call_names[n] = #n; \
 }
 
+  arch_post_init();
+
   IPCNAME(SEND);
   IPCNAME(RECEIVE);
   IPCNAME(SENDREC);
@@ -268,16 +263,17 @@ int main(void)
   IPCNAME(SENDNB);
   IPCNAME(SENDA);
 
-  /* Architecture-dependent initialization. */
-  DEBUGEXTRA(("arch_init()... "));
-  arch_init();
-  DEBUGEXTRA(("done\n"));
-
   /* System and processes initialization */
+  memory_init();
   DEBUGEXTRA(("system_init()... "));
   system_init();
   DEBUGEXTRA(("done\n"));
 
+  /* The bootstrap phase is over, so we can add the physical
+   * memory used for it to the free list.
+   */
+  add_memmap(&kinfo, kinfo.bootstrap_start, kinfo.bootstrap_len);
+
 #ifdef CONFIG_SMP
   if (config_no_apic) {
          BOOT_VERBOSE(printf("APIC disabled, disables SMP, using legacy PIC\n"));
@@ -303,7 +299,6 @@ int main(void)
 #endif
 
   NOT_REACHABLE;
-  return 1;
 }
 
 /*===========================================================================*
@@ -360,7 +355,127 @@ void minix_shutdown(timer_t *tp)
 #endif
   hw_intr_disable_all();
   stop_local_timer();
-  intr_init(INTS_ORIG, 0);
   arch_shutdown(tp ? tmr_arg(tp)->ta_int : RBT_PANIC);
 }
 
+/*===========================================================================*
+ *                             cstart                                       *
+ *===========================================================================*/
+void cstart()
+{
+/* Perform system initializations prior to calling main(). Most settings are
+ * determined with help of the environment strings passed by MINIX' loader.
+ */
+  register char *value;                                /* value in key=value pair */
+  int h;
+
+  /* low-level initialization */
+  prot_init();
+
+  /* determine verbosity */
+  if ((value = env_get(VERBOSEBOOTVARNAME)))
+         verboseboot = atoi(value);
+
+  /* Get clock tick frequency. */
+  value = env_get("hz");
+  if(value)
+       system_hz = atoi(value);
+  if(!value || system_hz < 2 || system_hz > 50000)     /* sanity check */
+       system_hz = DEFAULT_HZ;
+
+  DEBUGEXTRA(("cstart\n"));
+
+  /* Record miscellaneous information for user-space servers. */
+  kinfo.nr_procs = NR_PROCS;
+  kinfo.nr_tasks = NR_TASKS;
+  strncpy(kinfo.release, OS_RELEASE, sizeof(kinfo.release));
+  kinfo.release[sizeof(kinfo.release)-1] = '\0';
+  strncpy(kinfo.version, OS_VERSION, sizeof(kinfo.version));
+  kinfo.version[sizeof(kinfo.version)-1] = '\0';
+
+  /* Load average data initialization. */
+  kloadinfo.proc_last_slot = 0;
+  for(h = 0; h < _LOAD_HISTORY; h++)
+       kloadinfo.proc_load_history[h] = 0;
+
+#ifdef USE_APIC
+  value = env_get("no_apic");
+  if(value)
+       config_no_apic = atoi(value);
+  else
+       config_no_apic = 1;
+  value = env_get("apic_timer_x");
+  if(value)
+       config_apic_timer_x = atoi(value);
+  else
+       config_apic_timer_x = 1;
+#endif
+
+#ifdef USE_WATCHDOG
+  value = env_get("watchdog");
+  if (value)
+         watchdog_enabled = atoi(value);
+#endif
+
+#ifdef CONFIG_SMP
+  if (config_no_apic)
+         config_no_smp = 1;
+  value = env_get("no_smp");
+  if(value)
+       config_no_smp = atoi(value);
+  else
+       config_no_smp = 0;
+#endif
+  DEBUGEXTRA(("intr_init(0)\n"));
+
+  intr_init(0);
+
+  arch_init();
+}
+
+/*===========================================================================*
+ *                             get_value                                    *
+ *===========================================================================*/
+
+char *get_value(
+  const char *params,                  /* boot monitor parameters */
+  const char *name                     /* key to look up */
+)
+{
+/* Get environment value - kernel version of getenv to avoid setting up the
+ * usual environment array.
+ */
+  register const char *namep;
+  register char *envp;
+
+  for (envp = (char *) params; *envp != 0;) {
+       for (namep = name; *namep != 0 && *namep == *envp; namep++, envp++)
+               ;
+       if (*namep == '\0' && *envp == '=') return(envp + 1);
+       while (*envp++ != 0)
+               ;
+  }
+  return(NULL);
+}
+
+/*===========================================================================*
+ *                             env_get                                 *
+ *===========================================================================*/
+char *env_get(const char *name)
+{
+       return get_value(kinfo.param_buf, name);
+}
+
+void cpu_print_freq(unsigned cpu)
+{
+        u64_t freq;
+
+        freq = cpu_get_freq(cpu);
+        printf("CPU %d freq %lu MHz\n", cpu, div64u(freq, 1000000));
+}
+
+int is_fpu(void)
+{
+        return get_cpulocal_var(fpu_presence);
+}
+
index 8dcf53b238711096806e3222794bf6e16a1bec66..e47298555cafbf660415e117f7513659edb54b53 100644 (file)
@@ -6,11 +6,4 @@
 /* Enable copy-on-write optimization for safecopy. */
 #define PERF_USE_COW_SAFECOPY 0
 
-/* Use a private page table for critical system processes. */
-#ifdef CONFIG_SMP
-#define PERF_SYS_CORE_FULLVM 1
-#else
-#define PERF_SYS_CORE_FULLVM 0
-#endif
-
 #endif /* PERF_H */
index 6c1f5098e4f9e63925ad9bff2a681b75ca5bd807..0d5330693f14d721e1cda0d705d38be30ffa65c0 100644 (file)
@@ -72,10 +72,7 @@ static void set_idle_name(char * name, int n)
 {
         int i, c;
         int p_z = 0;
-        /*   
-         * P_NAME_LEN limits us to 3 characters for the idle task numer. 999
-         * should be enough though.
-         */
+
         if (n > 999) 
                 n = 999; 
 
@@ -138,7 +135,7 @@ void proc_init(void)
                rp->p_quantum_size_ms = 0;      /* no quantum size */
 
                /* arch-specific initialization */
-               arch_proc_init(i, rp);
+               arch_proc_reset(rp);
        }
        for (sp = BEG_PRIV_ADDR, i = 0; sp < END_PRIV_ADDR; ++sp, ++i) {
                sp->s_proc_nr = NONE;           /* initialize as free */
@@ -387,7 +384,7 @@ check_misc_flags:
         */
        p->p_misc_flags &= ~MF_CONTEXT_SET;
 
-       assert(!(p->p_misc_flags & MF_FULLVM) || p->p_seg.p_cr3 != 0);
+       assert(p->p_seg.p_cr3 != 0);
 #ifdef CONFIG_SMP
        if (p->p_misc_flags & MF_FLUSH_TLB) {
                if (tlb_must_refresh)
@@ -816,7 +813,7 @@ int mini_send(
        assert(!(dst_ptr->p_misc_flags & MF_DELIVERMSG));       
 
        if (!(flags & FROM_KERNEL)) {
-               if(copy_msg_from_user(caller_ptr, m_ptr, &dst_ptr->p_delivermsg))
+               if(copy_msg_from_user(m_ptr, &dst_ptr->p_delivermsg))
                        return EFAULT;
        } else {
                dst_ptr->p_delivermsg = *m_ptr;
@@ -851,7 +848,7 @@ int mini_send(
 
        /* Destination is not waiting.  Block and dequeue caller. */
        if (!(flags & FROM_KERNEL)) {
-               if(copy_msg_from_user(caller_ptr, m_ptr, &caller_ptr->p_sendmsg))
+               if(copy_msg_from_user(m_ptr, &caller_ptr->p_sendmsg))
                        return EFAULT;
        } else {
                caller_ptr->p_sendmsg = *m_ptr;
index ea546ef33ec25334a88022982a3ecfac5578d808..9b792b931ae4522eb716af6111aaeb0c44c5fc18 100644 (file)
@@ -54,8 +54,6 @@ struct proc {
        unsigned long preempted;
   } p_accounting;
 
-  struct mem_map p_memmap[NR_LOCAL_SEGS];   /* memory map (T, D, S) */
-
   clock_t p_user_time;         /* user time in ticks */
   clock_t p_sys_time;          /* sys time in ticks */
 
@@ -74,7 +72,7 @@ struct proc {
 
   sigset_t p_pending;          /* bit map for pending kernel signals */
 
-  char p_name[P_NAME_LEN];     /* name of the process, including \0 */
+  char p_name[PROC_NAME_LEN];  /* name of the process, including \0 */
 
   endpoint_t p_endpoint;       /* endpoint number, generation-aware */
 
@@ -237,7 +235,6 @@ struct proc {
                                   We need to resume the kernel call execution
                                   now
                                 */
-#define MF_FULLVM      0x020
 #define MF_DELIVERMSG  0x040   /* Copy message for him before running */
 #define MF_SIG_DELAY   0x080   /* Send signal when no longer sending */
 #define MF_SC_ACTIVE   0x100   /* Syscall tracing: in a system call now */
index a417aa8acc18f3a04225e544b2c682644e5fbd96..29e4ea3d4ef6ae807e4b69494ec935aa630fae82 100644 (file)
@@ -82,7 +82,7 @@ static void sprof_save_proc(struct proc * p)
        s = (struct sprof_proc *) (sprof_sample_buffer + sprof_info.mem_used);
 
        s->proc = p->p_endpoint;
-       memcpy(&s->name, p->p_name, P_NAME_LEN);
+       strcpy(s->name, p->p_name);
 
        sprof_info.mem_used += sizeof(struct sprof_proc);
 }
index 7ceb06e25f422625fbccfa6659eaff644857e64f..0159fbf7184d39ae15f6672f24dd3e2a2215de70 100644 (file)
@@ -38,7 +38,10 @@ void fpu_sigcontext(struct proc *, struct sigframe *fr, struct
        sigcontext *sc);
 
 /* main.c */
-int main(void);
+#ifndef UNPAGED
+#define kmain __k_unpaged_kmain
+#endif
+void kmain(kinfo_t *cbi);
 void prepare_shutdown(int how);
 __dead void minix_shutdown(struct timer *tp);
 void bsp_finish_booting(void);
@@ -55,7 +58,7 @@ int mini_notify(const struct proc *src, endpoint_t dst);
 void enqueue(struct proc *rp);
 void dequeue(struct proc *rp);
 void switch_to_user(void);
-void arch_proc_init(int nr, struct proc *rp);
+void arch_proc_reset(struct proc *rp);
 struct proc * arch_finish_switch_to_user(void);
 struct proc *endpoint_lookup(endpoint_t ep);
 #if DEBUG_ENABLE_IPC_WARNINGS
@@ -73,8 +76,7 @@ int try_deliver_senda(struct proc *caller_ptr, asynmsg_t *table, size_t
        size);
 
 /* start.c */
-void cstart(u16_t cs, u16_t ds, u16_t mds, u16_t parmoff, u16_t
-       parmsize);
+void cstart();
 char *env_get(const char *key);
 
 /* system.c */
@@ -87,17 +89,11 @@ void cause_sig(proc_nr_t proc_nr, int sig_nr);
 void sig_delay_done(struct proc *rp);
 void kernel_call(message *m_user, struct proc * caller);
 void system_init(void);
-#define numap_local(proc_nr, vir_addr, bytes) \
-       umap_local(proc_addr(proc_nr), D, (vir_addr), (bytes))
 void clear_endpoint(struct proc *rc);
 void clear_ipc_refs(struct proc *rc, int caller_ret);
 void kernel_call_resume(struct proc *p);
 int sched_proc(struct proc *rp, int priority, int quantum, int cpu);
 
-/* system/do_newmap.c */
-int newmap(struct proc * caller, struct proc *rp, struct mem_map
-       *map_ptr);
-
 /* system/do_vtimer.c */
 void vtimer_check(struct proc *rp);
 
@@ -152,7 +148,8 @@ void stop_profile_clock(void);
 #endif
 
 /* functions defined in architecture-dependent files. */
-void prot_init(void);
+void prot_init();
+void arch_post_init();
 phys_bytes phys_copy(phys_bytes source, phys_bytes dest, phys_bytes
        count);
 void phys_copy_fault(void);
@@ -169,18 +166,15 @@ int data_copy(endpoint_t from, vir_bytes from_addr, endpoint_t to,
        vir_bytes to_addr, size_t bytes);
 int data_copy_vmcheck(struct proc *, endpoint_t from, vir_bytes
        from_addr, endpoint_t to, vir_bytes to_addr, size_t bytes);
-void alloc_segments(struct proc *rp);
-void vm_stop(void);
-phys_bytes umap_local(register struct proc *rp, int seg, vir_bytes
-       vir_addr, vir_bytes bytes);
 phys_bytes umap_virtual(struct proc* rp, int seg, vir_bytes vir_addr,
        vir_bytes bytes);
 phys_bytes seg2phys(u16_t);
 int vm_memset(endpoint_t who,
        phys_bytes source, u8_t pattern, phys_bytes count);
-int intr_init(int, int);
+int intr_init(int);
 void halt_cpu(void);
 void arch_init(void);
+void arch_boot_proc(struct boot_image *b, struct proc *p);
 void cpu_identify(void);
 /* arch dependent FPU initialization per CPU */
 void fpu_init(void);
@@ -195,8 +189,9 @@ void arch_stop_profile_clock(void);
 void arch_ack_profile_clock(void);
 void do_ser_debug(void);
 int arch_get_params(char *parm, int max);
-int arch_set_params(char *parm, int max);
-void arch_pre_exec(struct proc *pr, u32_t, u32_t);
+void memory_init(void);
+void mem_clear_mapcache(void);
+void arch_proc_init(struct proc *pr, u32_t, u32_t, char *);
 int arch_do_vmctl(message *m_ptr, struct proc *p);
 int vm_contiguous(const struct proc *targetproc, vir_bytes vir_buf,
        size_t count);
@@ -210,14 +205,12 @@ void arch_do_syscall(struct proc *proc);
 int arch_phys_map(int index, phys_bytes *addr, phys_bytes *len, int
        *flags);
 int arch_phys_map_reply(int index, vir_bytes addr);
-int arch_enable_paging(struct proc * caller, const message * m_ptr);
+int arch_enable_paging(struct proc * caller);
 int vm_check_range(struct proc *caller,
        struct proc *target, vir_bytes vir_addr, size_t bytes);
 
-int copy_msg_from_user(struct proc * p, message * user_mbuf, message *
-       dst);
-int copy_msg_to_user(struct proc * p, message * src, message *
-       user_mbuf);
+int copy_msg_from_user(message * user_mbuf, message * dst);
+int copy_msg_to_user(message * src, message * user_mbuf);
 void switch_address_space(struct proc * p);
 void release_address_space(struct proc *pr);
 
diff --git a/kernel/start.c b/kernel/start.c
deleted file mode 100644 (file)
index 32127b6..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-
-/* First C file used by the kernel. */
-
-#include "kernel.h"
-#include "proc.h"
-#include <stdlib.h>
-#include <string.h>
-#include "proto.h"
-
-#ifdef USE_WATCHDOG
-#include "watchdog.h"
-#endif
-
-/*===========================================================================*
- *                             cstart                                       *
- *===========================================================================*/
-void cstart(
-   u16_t cs,           /* kernel code segment */
-   u16_t ds,           /* kernel data segment */
-   u16_t mds,          /* monitor data segment */
-   u16_t parmoff,      /* boot parameters offset */
-   u16_t parmsize      /* boot parameters length */
-)
-{
-/* Perform system initializations prior to calling main(). Most settings are
- * determined with help of the environment strings passed by MINIX' loader.
- */
-  register char *value;                                /* value in key=value pair */
-  extern int etext, end;
-  int h;
-
-  /* Record where the kernel and the monitor are. */
-  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 */
-
-  /* protection initialization */
-  prot_init();
-
-  /* Copy the boot parameters to the local buffer. */
-  arch_get_params(params_buffer, sizeof(params_buffer));
-
-  /* determine verbosity */
-  if ((value = env_get(VERBOSEBOOTVARNAME)))
-         verboseboot = atoi(value);
-
-  /* Get clock tick frequency. */
-  value = env_get("hz");
-  if(value)
-       system_hz = atoi(value);
-  if(!value || system_hz < 2 || system_hz > 50000)     /* sanity check */
-       system_hz = DEFAULT_HZ;
-
-#ifdef DEBUG_SERIAL
-  /* Intitialize serial debugging */
-  value = env_get(SERVARNAME);
-  if(value && atoi(value) == 0) {
-       do_serial_debug=1;
-
-       value = env_get(SERBAUDVARNAME);
-       if (value) serial_debug_baud = atoi(value);
-  }
-#endif
-
-  DEBUGEXTRA(("cstart\n"));
-
-  /* Record miscellaneous information for user-space servers. */
-  kinfo.nr_procs = NR_PROCS;
-  kinfo.nr_tasks = NR_TASKS;
-  strncpy(kinfo.release, OS_RELEASE, sizeof(kinfo.release));
-  kinfo.release[sizeof(kinfo.release)-1] = '\0';
-  strncpy(kinfo.version, OS_VERSION, sizeof(kinfo.version));
-  kinfo.version[sizeof(kinfo.version)-1] = '\0';
-  kinfo.proc_addr = (vir_bytes) proc;
-
-  /* Load average data initialization. */
-  kloadinfo.proc_last_slot = 0;
-  for(h = 0; h < _LOAD_HISTORY; h++)
-       kloadinfo.proc_load_history[h] = 0;
-
-#ifdef USE_APIC
-  value = env_get("no_apic");
-  if(value)
-       config_no_apic = atoi(value);
-  else
-       config_no_apic = 1;
-  value = env_get("apic_timer_x");
-  if(value)
-       config_apic_timer_x = atoi(value);
-  else
-       config_apic_timer_x = 1;
-#endif
-
-#ifdef USE_WATCHDOG
-  value = env_get("watchdog");
-  if (value)
-         watchdog_enabled = atoi(value);
-#endif
-
-#ifdef CONFIG_SMP
-  if (config_no_apic)
-         config_no_smp = 1;
-  value = env_get("no_smp");
-  if(value)
-       config_no_smp = atoi(value);
-  else
-       config_no_smp = 0;
-#endif
-
-  /* Return to assembler code to switch to protected mode (if 286), 
-   * reload selectors and call main().
-   */
-
-  DEBUGEXTRA(("intr_init(%d, 0)\n", INTS_MINIX));
-  intr_init(INTS_MINIX, 0);
-}
-
-/*===========================================================================*
- *                             get_value                                    *
- *===========================================================================*/
-
-char *get_value(
-  const char *params,                  /* boot monitor parameters */
-  const char *name                     /* key to look up */
-)
-{
-/* Get environment value - kernel version of getenv to avoid setting up the
- * usual environment array.
- */
-  register const char *namep;
-  register char *envp;
-
-  for (envp = (char *) params; *envp != 0;) {
-       for (namep = name; *namep != 0 && *namep == *envp; namep++, envp++)
-               ;
-       if (*namep == '\0' && *envp == '=') return(envp + 1);
-       while (*envp++ != 0)
-               ;
-  }
-  return(NULL);
-}
-
-/*===========================================================================*
- *                             env_get                                 *
- *===========================================================================*/
-char *env_get(const char *name)
-{
-       return get_value(params_buffer, name);
-}
-
index 2b08d4cfec3e43ee621cc4b55561161b15571ade..b1dd9337e0da4c07fb6fa90a5f05dd6acd47e4aa 100644 (file)
@@ -81,8 +81,7 @@ static void kernel_call_finish(struct proc * caller, message *msg, int result)
 #if DEBUG_IPC_HOOK
        hook_ipc_msgkresult(msg, caller);
 #endif
-                 if (copy_msg_to_user(caller, msg,
-                                 (message *)caller->p_delivermsg_vir)) {
+                 if (copy_msg_to_user(msg, (message *)caller->p_delivermsg_vir)) {
                          printf("WARNING wrong user pointer 0x%08x from "
                                          "process %s / %d\n",
                                          caller->p_delivermsg_vir,
@@ -146,7 +145,7 @@ void kernel_call(message *m_user, struct proc * caller)
    * into the kernel or was already set in switch_to_user() before we resume
    * execution of an interrupted kernel call
    */
-  if (copy_msg_from_user(caller, m_user, &msg) == 0) {
+  if (copy_msg_from_user(m_user, &msg) == 0) {
          msg.m_source = caller->p_endpoint;
          result = kernel_call_dispatch(caller, &msg);
   }
@@ -216,7 +215,6 @@ void system_init(void)
   map(SYS_VDEVIO, do_vdevio);                  /* vector with devio requests */ 
 
   /* Memory management. */
-  map(SYS_NEWMAP, do_newmap);          /* set up a process memory map */
   map(SYS_MEMSET, do_memset);          /* write char to memory area */
   map(SYS_VMCTL, do_vmctl);            /* various VM process settings */
 
@@ -366,13 +364,16 @@ int send_sig(endpoint_t ep, int sig_nr)
  * send a notification with source SYSTEM.
  */ 
   register struct proc *rp;
+  struct priv *priv;
   int proc_nr;
 
   if(!isokendpt(ep, &proc_nr) || isemptyn(proc_nr))
        return EINVAL;
 
   rp = proc_addr(proc_nr);
-  sigaddset(&priv(rp)->s_sig_pending, sig_nr);
+  priv = priv(rp);
+  if(!priv) return ENOENT;
+  sigaddset(&priv->s_sig_pending, sig_nr);
   mini_notify(proc_addr(SYSTEM), rp->p_endpoint);
 
   return OK;
index 59c9ef31fe0a36259bd8276309594f01f7790be6..755ebae4e1acf3ee6be4a947128badb1f5437ccd 100644 (file)
@@ -46,11 +46,6 @@ int do_fork(struct proc * caller, message *m_ptr);
 #define do_fork NULL
 #endif
 
-int do_newmap(struct proc * caller, message *m_ptr);
-#if ! USE_NEWMAP
-#define do_newmap NULL
-#endif
-
 int do_clear(struct proc * caller, message *m_ptr);
 #if ! USE_CLEAR
 #define do_clear NULL
index 4209c9901dcb101e581e4fb898291d8973623f9b..c4ccc04ed69ebdcf43e8fbf982bf51787d3ed2a5 100644 (file)
@@ -5,7 +5,6 @@
 SRCS+=         \
        do_fork.c \
        do_exec.c \
-       do_newmap.c \
        do_clear.c \
        do_exit.c \
        do_trace.c \
index c0c5078814d3f2f8d16c564aee3aeaa14719170d..8208af5248e3e7565fbec47ad5fc45dee78a4a44 100644 (file)
@@ -35,10 +35,6 @@ int do_abort(struct proc * caller, message * m_ptr)
                return p;
       }
       paramsbuffer[len] = '\0';
-
-      /* Parameters seem ok, copy them and prepare shutting down. */
-      if((p = arch_set_params(paramsbuffer, len+1)) != OK)
-       return p;
   }
 
   /* Now prepare to shutdown MINIX. */
index 2e80c8351d2e3fb9f74e02c072d889ddda52c348..52b535b74c603f8033fa511f6bc5e4cd5240f48b 100644 (file)
@@ -26,7 +26,6 @@ int do_copy(struct proc * caller, message * m_ptr)
   struct vir_addr vir_addr[2]; /* virtual source and destination address */
   phys_bytes bytes;            /* number of bytes to copy */
   int i;
-  endpoint_t pe;
 
 #if 0
   if (caller->p_endpoint != PM_PROC_NR && caller->p_endpoint != VFS_PROC_NR &&
@@ -47,11 +46,10 @@ int do_copy(struct proc * caller, message * m_ptr)
 #endif
 
   /* Dismember the command message. */
-  pe = vir_addr[_SRC_].proc_nr_e = m_ptr->CP_SRC_ENDPT;
-  vir_addr[_SRC_].segment = (pe == NONE ? PHYS_SEG : D);
+  vir_addr[_SRC_].proc_nr_e = m_ptr->CP_SRC_ENDPT;
+  vir_addr[_DST_].proc_nr_e = m_ptr->CP_DST_ENDPT;
+
   vir_addr[_SRC_].offset = (vir_bytes) m_ptr->CP_SRC_ADDR;
-  pe = vir_addr[_DST_].proc_nr_e = m_ptr->CP_DST_ENDPT;
-  vir_addr[_DST_].segment = (pe == NONE ? PHYS_SEG : D);
   vir_addr[_DST_].offset = (vir_bytes) m_ptr->CP_DST_ADDR;
   bytes = (phys_bytes) m_ptr->CP_NR_BYTES;
 
@@ -63,10 +61,9 @@ int do_copy(struct proc * caller, message * m_ptr)
       /* Check if process number was given implictly with SELF and is valid. */
       if (vir_addr[i].proc_nr_e == SELF)
        vir_addr[i].proc_nr_e = caller->p_endpoint;
-      if (vir_addr[i].segment != PHYS_SEG) {
+      if (vir_addr[i].proc_nr_e != NONE) {
        if(! isokendpt(vir_addr[i].proc_nr_e, &p)) {
-         printf("do_copy: %d: seg 0x%x, %d not ok endpoint\n",
-               i, vir_addr[i].segment, vir_addr[i].proc_nr_e);
+         printf("do_copy: %d: %d not ok endpoint\n", i, vir_addr[i].proc_nr_e);
           return(EINVAL); 
         }
       }
index 0919d8dc9a3fbea4c2b3ddbd707a6431379efdef..74370544b6d916286a2e97dd3b5c2d70a9b17ca2 100644 (file)
@@ -21,6 +21,7 @@ int do_exec(struct proc * caller, message * m_ptr)
 /* Handle sys_exec().  A process has done a successful EXEC. Patch it up. */
   register struct proc *rp;
   int proc_nr;
+  char name[PROC_NAME_LEN];
 
   if(!isokendpt(m_ptr->PR_ENDPT, &proc_nr))
        return EINVAL;
@@ -33,11 +34,14 @@ int do_exec(struct proc * caller, message * m_ptr)
 
   /* Save command name for debugging, ps(1) output, etc. */
   if(data_copy(caller->p_endpoint, (vir_bytes) m_ptr->PR_NAME_PTR,
-       KERNEL, (vir_bytes) rp->p_name, (phys_bytes) P_NAME_LEN - 1) != OK)
-       strncpy(rp->p_name, "<unset>", P_NAME_LEN);
+       KERNEL, (vir_bytes) name,
+       (phys_bytes) sizeof(name) - 1) != OK)
+       strncpy(name, "<unset>", PROC_NAME_LEN);
 
-  /* Do architecture-specific exec() stuff. */
-  arch_pre_exec(rp, (u32_t) m_ptr->PR_IP_PTR, (u32_t) m_ptr->PR_STACK_PTR);
+  name[sizeof(name)-1] = '\0';
+
+  /* Set process state. */
+  arch_proc_init(rp, (u32_t) m_ptr->PR_IP_PTR, (u32_t) m_ptr->PR_STACK_PTR, name);
 
   /* No reply to EXEC call */
   RTS_UNSET(rp, RTS_RECEIVING);
index 6d588b107b59b1aa7e98da75cf5ddd66871fe2c9..e7ef19a233906811d15eefdd231e599edc1fb46c 100644 (file)
@@ -26,13 +26,11 @@ int do_fork(struct proc * caller, message * m_ptr)
 {
 /* Handle sys_fork().  PR_ENDPT has forked.  The child is PR_SLOT. */
 #if (_MINIX_CHIP == _CHIP_INTEL)
-  reg_t old_ldt_sel;
   char *old_fpu_save_area_p;
 #endif
   register struct proc *rpc;           /* child process pointer */
   struct proc *rpp;                    /* parent process pointer */
-  struct mem_map *map_ptr;     /* virtual address of map inside caller (PM) */
-  int gen, r;
+  int gen;
   int p_proc;
   int namelen;
 
@@ -51,19 +49,15 @@ int do_fork(struct proc * caller, message * m_ptr)
        return EINVAL;
   }
 
-  map_ptr= (struct mem_map *) m_ptr->PR_MEM_PTR;
-
   /* make sure that the FPU context is saved in parent before copy */
   save_fpu(rpp);
   /* Copy parent 'proc' struct to child. And reinitialize some fields. */
   gen = _ENDPOINT_G(rpc->p_endpoint);
 #if (_MINIX_CHIP == _CHIP_INTEL)
-  old_ldt_sel = rpc->p_seg.p_ldt_sel;  /* backup local descriptors */
   old_fpu_save_area_p = rpc->p_seg.fpu_state;
 #endif
   *rpc = *rpp;                         /* copy 'proc' struct */
 #if (_MINIX_CHIP == _CHIP_INTEL)
-  rpc->p_seg.p_ldt_sel = old_ldt_sel;  /* restore descriptors */
   rpc->p_seg.fpu_state = old_fpu_save_area_p;
   if(proc_used_fpu(rpp))
        memcpy(rpc->p_seg.fpu_state, rpp->p_seg.fpu_state, FPU_XFP_SIZE);
@@ -111,9 +105,6 @@ int do_fork(struct proc * caller, message * m_ptr)
   m_ptr->PR_ENDPT = rpc->p_endpoint;
   m_ptr->PR_FORK_MSGADDR = (char *) rpp->p_delivermsg_vir;
 
-  /* Install new map */
-  r = newmap(caller, rpc, map_ptr);
-
   /* Don't schedule process in VM mode until it has a new pagetable. */
   if(m_ptr->PR_FORK_FLAGS & PFF_VMINHIBIT) {
        RTS_SET(rpc, RTS_VMINHIBIT);
@@ -128,7 +119,7 @@ int do_fork(struct proc * caller, message * m_ptr)
   rpc->p_seg.p_cr3 = 0;
   rpc->p_seg.p_cr3_v = NULL;
 
-  return r;
+  return OK;
 }
 
 #endif /* USE_FORK */
index b13e6e2efe317c8ae01e4258eb1a0615d648e662..5ccc6abcb3b8b9f128ab18b92ea47bc8a827084e 100644 (file)
@@ -133,8 +133,8 @@ int do_getinfo(struct proc * caller, message * m_ptr)
        return OK;
     }
     case GET_MONPARAMS: {
-        src_vir = (vir_bytes) params_buffer;
-       length = sizeof(params_buffer);
+        src_vir = (vir_bytes) kinfo.param_buf;
+       length = sizeof(kinfo.param_buf);
         break;
     }
     case GET_RANDOMNESS: {             
diff --git a/kernel/system/do_newmap.c b/kernel/system/do_newmap.c
deleted file mode 100644 (file)
index 307f4b0..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/* The kernel call implemented in this file:
- *   m_type:   SYS_NEWMAP
- *
- * The parameters for this kernel call are:
- *    m1_i1:   PR_ENDPT                (install new map for this process)
- *    m1_p1:   PR_MEM_PTR              (pointer to the new memory map)
- */
-#include "kernel/system.h"
-#include <minix/endpoint.h>
-
-#if USE_NEWMAP
-
-/*===========================================================================*
- *                             do_newmap                                    *
- *===========================================================================*/
-int do_newmap(struct proc * caller, message * m_ptr)
-{
-/* Handle sys_newmap().  Fetch the memory map. */
-  struct proc *rp;     /* process whose map is to be loaded */
-  struct mem_map *map_ptr;     /* virtual address of map inside caller */
-  int proc_nr;
-
-  map_ptr = (struct mem_map *) m_ptr->PR_MEM_PTR;
-  if (! isokendpt(m_ptr->PR_ENDPT, &proc_nr)) return(EINVAL);
-  if (iskerneln(proc_nr)) return(EPERM);
-  rp = proc_addr(proc_nr);
-
-  return newmap(caller, rp, map_ptr);
-}
-
-
-/*===========================================================================*
- *                             newmap                                       *
- *===========================================================================*/
-int newmap(struct proc *caller, struct proc *rp, struct mem_map *map_ptr)
-{
-  int r;
-/* Fetch the memory map. */
-  if((r=data_copy(caller->p_endpoint, (vir_bytes) map_ptr,
-       KERNEL, (vir_bytes) rp->p_memmap, sizeof(rp->p_memmap))) != OK) {
-       printf("newmap: data_copy failed! (%d)\n", r);
-       return r;
-  }
-
-  alloc_segments(rp);
-
-  return(OK);
-}
-#endif /* USE_NEWMAP */
-
index 3812afc41739d63add894af6004519d49c3ad0ac..86a43335595c8259966f2e173a5bcd952adeef5d 100644 (file)
@@ -13,6 +13,7 @@
  *      VSCP_VEC_SIZE   number of significant elements in vector
  */
 
+#include <assert.h>
 #include <minix/type.h>
 #include <minix/safecopies.h>
 
@@ -245,6 +246,11 @@ int access;                        /* CPF_READ for a copy from granter to grantee, CPF_WRITE
        vir_bytes size;
 #endif
 
+       if(granter == NONE || grantee == NONE) {
+               printf("safecopy: nonsense processes\n");
+               return EFAULT;
+       }
+
        /* See if there is a reasonable grant table. */
        if(!(granter_p = endpoint_lookup(granter))) return EINVAL;
        if(!HASGRANTTABLE(granter_p)) {
@@ -277,8 +283,6 @@ int access;                 /* CPF_READ for a copy from granter to grantee, CPF_WRITE
        granter = new_granter;
 
        /* Now it's a regular copy. */
-       v_src.segment = D;
-       v_dst.segment = D;
        v_src.proc_nr_e = *src;
        v_dst.proc_nr_e = *dst;
 
@@ -373,8 +377,8 @@ int do_vsafecopy(struct proc * caller, message * m_ptr)
 
        /* Set vector copy parameters. */
        src.proc_nr_e = caller->p_endpoint;
+       assert(src.proc_nr_e != NONE);
        src.offset = (vir_bytes) m_ptr->VSCP_VEC_ADDR;
-       src.segment = dst.segment = D;
        dst.proc_nr_e = KERNEL;
        dst.offset = (vir_bytes) vec;
 
index f9a28ec90c7123119c7305a2eefabe21460efc65..1b59b6e5f099743d6806e036ba1cc876510edb97 100644 (file)
@@ -120,21 +120,12 @@ int map_invoke_vm(struct proc * caller,
                        size_t size, int flag)
 {
        struct proc *src, *dst;
-       phys_bytes lin_src, lin_dst;
 
        src = endpoint_lookup(end_s);
        dst = endpoint_lookup(end_d);
 
-       lin_src = umap_local(src, D, off_s, size);
-       lin_dst = umap_local(dst, D, off_d, size);
-       if(lin_src == 0 || lin_dst == 0) {
-               printf("map_invoke_vm: error in umap_local.\n");
-               return EINVAL;
-       }
-
        /* Make sure the linear addresses are both page aligned. */
-       if(lin_src % CLICK_SIZE != 0
-               || lin_dst % CLICK_SIZE != 0) {
+       if(off_s % CLICK_SIZE != 0 || off_d % CLICK_SIZE != 0) {
                printf("map_invoke_vm: linear addresses not page aligned.\n");
                return EINVAL;
        }
@@ -149,9 +140,9 @@ int map_invoke_vm(struct proc * caller,
        /* Map to the destination. */
        caller->p_vmrequest.req_type = req_type;
        caller->p_vmrequest.target = end_d;             /* destination proc */
-       caller->p_vmrequest.params.map.vir_d = lin_dst; /* destination addr */
+       caller->p_vmrequest.params.map.vir_d = off_d;   /* destination addr */
        caller->p_vmrequest.params.map.ep_s = end_s;    /* source process */
-       caller->p_vmrequest.params.map.vir_s = lin_src; /* source address */
+       caller->p_vmrequest.params.map.vir_s = off_s;   /* source address */
        caller->p_vmrequest.params.map.length = (vir_bytes) size;
        caller->p_vmrequest.params.map.writeflag = flag;
 
index 8966154545538d15d6cc8bea175b2c4122cba058..48dbae3603e35796c4589acf10c67161e310938f 100644 (file)
@@ -51,15 +51,13 @@ int do_trace(struct proc * caller, message * m_ptr)
   unsigned char ub;
   int i;
 
-#define COPYTOPROC(seg, addr, myaddr, length) {                \
+#define COPYTOPROC(addr, myaddr, length) {             \
        struct vir_addr fromaddr, toaddr;               \
        int r;  \
        fromaddr.proc_nr_e = KERNEL;                    \
        toaddr.proc_nr_e = tr_proc_nr_e;                \
        fromaddr.offset = (myaddr);                     \
        toaddr.offset = (addr);                         \
-       fromaddr.segment = D;                           \
-       toaddr.segment = (seg);                         \
        if((r=virtual_copy_vmcheck(caller, &fromaddr,   \
                        &toaddr, length)) != OK) {      \
                printf("Can't copy in sys_trace: %d\n", r);\
@@ -67,15 +65,13 @@ int do_trace(struct proc * caller, message * m_ptr)
        }  \
 }
 
-#define COPYFROMPROC(seg, addr, myaddr, length) {      \
+#define COPYFROMPROC(addr, myaddr, length) {   \
        struct vir_addr fromaddr, toaddr;               \
        int r;  \
        fromaddr.proc_nr_e = tr_proc_nr_e;              \
        toaddr.proc_nr_e = KERNEL;                      \
        fromaddr.offset = (addr);                       \
        toaddr.offset = (myaddr);                       \
-       fromaddr.segment = (seg);                       \
-       toaddr.segment = D;                             \
        if((r=virtual_copy_vmcheck(caller, &fromaddr,   \
                        &toaddr, length)) != OK) {      \
                printf("Can't copy in sys_trace: %d\n", r);\
@@ -96,12 +92,12 @@ int do_trace(struct proc * caller, message * m_ptr)
        return(OK);
 
   case T_GETINS:               /* return value from instruction space */
-       COPYFROMPROC(T, tr_addr, (vir_bytes) &tr_data, sizeof(long));
+       COPYFROMPROC(tr_addr, (vir_bytes) &tr_data, sizeof(long));
        m_ptr->CTL_DATA = tr_data;
        break;
 
   case T_GETDATA:              /* return value from data space */
-       COPYFROMPROC(D, tr_addr, (vir_bytes) &tr_data, sizeof(long));
+       COPYFROMPROC(tr_addr, (vir_bytes) &tr_data, sizeof(long));
        m_ptr->CTL_DATA= tr_data;
        break;
 
@@ -125,12 +121,12 @@ int do_trace(struct proc * caller, message * m_ptr)
        break;
 
   case T_SETINS:               /* set value in instruction space */
-       COPYTOPROC(T, tr_addr, (vir_bytes) &tr_data, sizeof(long));
+       COPYTOPROC(tr_addr, (vir_bytes) &tr_data, sizeof(long));
        m_ptr->CTL_DATA = 0;
        break;
 
   case T_SETDATA:                      /* set value in data space */
-       COPYTOPROC(D, tr_addr, (vir_bytes) &tr_data, sizeof(long));
+       COPYTOPROC(tr_addr, (vir_bytes) &tr_data, sizeof(long));
        m_ptr->CTL_DATA = 0;
        break;
 
@@ -184,13 +180,13 @@ int do_trace(struct proc * caller, message * m_ptr)
        break;
 
   case T_READB_INS:            /* get value from instruction space */
-       COPYFROMPROC(T, tr_addr, (vir_bytes) &ub, 1);
+       COPYFROMPROC(tr_addr, (vir_bytes) &ub, 1);
        m_ptr->CTL_DATA = ub;
        break;
 
   case T_WRITEB_INS:           /* set value in instruction space */
        ub = (unsigned char) (tr_data & 0xff);
-       COPYTOPROC(T, tr_addr, (vir_bytes) &ub, 1);
+       COPYTOPROC(tr_addr, (vir_bytes) &ub, 1);
        m_ptr->CTL_DATA = 0;
        break;
 
index a4ecc64f9eac1f492c087328d005c43bd92da416..57dad9af6b383af854d2f58ab41eff99a0108650 100644 (file)
@@ -33,7 +33,6 @@ int do_umap_remote(struct proc * caller, message * m_ptr)
   int endpt = (int) m_ptr->CP_SRC_ENDPT;
   endpoint_t grantee = (endpoint_t) m_ptr->CP_DST_ENDPT;
   int proc_nr, proc_nr_grantee;
-  int naughty = 0;
   phys_bytes phys_addr = 0, lin_addr = 0;
   struct proc *targetpr;
 
@@ -57,11 +56,6 @@ int do_umap_remote(struct proc * caller, message * m_ptr)
 
   /* See which mapping should be made. */
   switch(seg_type) {
-  case LOCAL_SEG:
-      phys_addr = lin_addr = umap_local(targetpr, seg_index, offset, count);
-      if(!lin_addr) return EFAULT;
-      naughty = 1;
-      break;
   case LOCAL_VM_SEG:
     if(seg_index == MEM_GRANT) {
        vir_bytes newoffset;
@@ -84,11 +78,11 @@ int do_umap_remote(struct proc * caller, message * m_ptr)
        /* New lookup. */
        offset = newoffset;
        targetpr = proc_addr(new_proc_nr);
-       seg_index = D;
+       seg_index = VIR_ADDR;
       }
 
-      if(seg_index == T || seg_index == D || seg_index == S) {
-        phys_addr = lin_addr = umap_local(targetpr, seg_index, offset, count);
+      if(seg_index == VIR_ADDR) {
+        phys_addr = lin_addr = offset;
       } else {
        printf("SYSTEM: bogus seg type 0x%lx\n", seg_index);
        return EFAULT;
@@ -115,7 +109,7 @@ int do_umap_remote(struct proc * caller, message * m_ptr)
   }
 
   m_ptr->CP_DST_ADDR = phys_addr;
-  if(naughty || phys_addr == 0) {
+  if(phys_addr == 0) {
          printf("kernel: umap 0x%x done by %d / %s, pc 0x%lx, 0x%lx -> 0x%lx\n",
                seg_type, caller->p_endpoint, caller->p_name,
                caller->p_reg.pc, offset, phys_addr);
index 1271575096c3918dfeedb3a550d1811920297ff5..38341b32a400451261b8df91bc49c11e0db93be4 100644 (file)
@@ -111,11 +111,6 @@ int do_update(struct proc * caller, message * m_ptr)
   /* Swap global process slot addresses. */
   swap_proc_slot_pointer(get_cpulocal_var_ptr(ptproc), src_rp, dst_rp);
 
-  /* Fix segments. */
-  alloc_segments(src_rp);
-  alloc_segments(dst_rp);
-  prot_init();
-
 #if DEBUG
   printf("do_update: updated %d (%s, %d, %d) into %d (%s, %d, %d)\n",
       src_rp->p_endpoint, src_rp->p_name, src_rp->p_nr, priv(src_rp)->s_proc_nr,
index 20ef5672e573bf7555606fca801da8d18ddafa83..f3a9b980eacd1bef2880ae723eba857e3adaf1b9 100644 (file)
@@ -120,13 +120,6 @@ int do_vmctl(struct proc * caller, message * m_ptr)
                RTS_UNSET(p, RTS_VMREQUEST);
                return OK;
 
-       case VMCTL_ENABLE_PAGING:
-               if(vm_running) 
-                       panic("do_vmctl: paging already enabled");
-               if (arch_enable_paging(caller, m_ptr) != OK)
-                       panic("do_vmctl: paging enabling failed");
-               return OK;
-
        case VMCTL_KERN_PHYSMAP:
        {
                int i = m_ptr->SVMCTL_VALUE;
@@ -177,6 +170,10 @@ int do_vmctl(struct proc * caller, message * m_ptr)
                bits_fill(p->p_stale_tlb, CONFIG_MAX_CPUS);
 #endif
                return OK;
+       case VMCTL_CLEARMAPCACHE:
+               /* VM says: forget about old mappings we have cached. */
+               mem_clear_mapcache();
+               return OK;
   }
 
   /* Try architecture-specific vmctls. */
index 6ad430361d38f3e1afcf3b514ecd044ebd77e65e..56bd635f490e9640bde74dda5774af322833739a 100644 (file)
@@ -29,7 +29,7 @@ int do_vumap(struct proc *caller, message *m_ptr)
   struct proc *procp;
   struct vumap_vir vvec[MAPVEC_NR];
   struct vumap_phys pvec[MAPVEC_NR];
-  vir_bytes vaddr, paddr, vir_addr, lin_addr;
+  vir_bytes vaddr, paddr, vir_addr;
   phys_bytes phys_addr;
   int i, r, proc_nr, vcount, pcount, pmax, access;
   size_t size, chunk, offset;
@@ -89,13 +89,9 @@ int do_vumap(struct proc *caller, message *m_ptr)
        okendpt(granter, &proc_nr);
        procp = proc_addr(proc_nr);
 
-       lin_addr = umap_local(procp, D, vir_addr, size);
-       if (!lin_addr)
-               return EFAULT;
-
        /* Each virtual range is made up of one or more physical ranges. */
        while (size > 0 && pcount < pmax) {
-               chunk = vm_lookup_range(procp, lin_addr, &phys_addr, size);
+               chunk = vm_lookup_range(procp, vir_addr, &phys_addr, size);
 
                if (!chunk) {
                        /* Try to get the memory allocated, unless the memory
@@ -107,14 +103,14 @@ int do_vumap(struct proc *caller, message *m_ptr)
                        /* This call may suspend the current call, or return an
                         * error for a previous invocation.
                         */
-                       return vm_check_range(caller, procp, lin_addr, size);
+                       return vm_check_range(caller, procp, vir_addr, size);
                }
 
                pvec[pcount].vp_addr = phys_addr;
                pvec[pcount].vp_size = chunk;
                pcount++;
 
-               lin_addr += chunk;
+               vir_addr += chunk;
                size -= chunk;
        }
 
index 4975a7dd6a5dfe0708a7313fe7eeb5577e8a870c..6a4a3f3d1f494d00932a2a46d771ab16584176a1 100644 (file)
 #include "ipc.h"
 #include <minix/com.h>
 
-/* Define boot process flags. */
-#define BVM_F   (PROC_FULLVM)                    /* boot processes with VM */
-#define OVM_F   (PERF_SYS_CORE_FULLVM ? PROC_FULLVM : 0) /* critical boot
-                                                           * processes with
-                                                           * optional VM.
-                                                           */
-
 /* The system image table lists all programs that are part of the boot image. 
  * The order of the entries here MUST agree with the order of the programs
  * in the boot image and all kernel tasks must come first.
  * to prioritize ping messages periodically delivered to system processes.
  */
 
-struct boot_image image[] = {
+struct boot_image image[NR_BOOT_PROCS] = {
 /* process nr, flags, stack size, name */
-{ASYNCM,           0,          0, "asyncm"},
-{IDLE,             0,          0, "idle"  },
-{CLOCK,            0,          0, "clock" },
-{SYSTEM,           0,          0, "system"},
-{HARDWARE,         0,          0, "kernel"},
+{ASYNCM,        "asyncm"},
+{IDLE,          "idle"  },
+{CLOCK,         "clock" },
+{SYSTEM,        "system"},
+{HARDWARE,      "kernel"},
                       
-{DS_PROC_NR,   BVM_F,         16, "ds"    },
-{RS_PROC_NR,       0,       8125, "rs"    },
+{DS_PROC_NR,    "ds"    },
+{RS_PROC_NR,    "rs"    },
                       
-{PM_PROC_NR,   OVM_F,         32, "pm"    },
-{SCHED_PROC_NR,OVM_F,         32, "sched" },
-{VFS_PROC_NR,  BVM_F,         16, "vfs"   },
-{MEM_PROC_NR,  BVM_F,          8, "memory"},
-{LOG_PROC_NR,  BVM_F,         32, "log"   },
-{TTY_PROC_NR,  BVM_F,         16, "tty"   },
-{MFS_PROC_NR,  BVM_F,        128, "mfs"   },
-{VM_PROC_NR,       0,        128, "vm"    },
-{PFS_PROC_NR,  BVM_F,        128, "pfs"   },
-{INIT_PROC_NR, BVM_F,         64, "init"  },
+{PM_PROC_NR,    "pm"    },
+{SCHED_PROC_NR, "sched" },
+{VFS_PROC_NR,   "vfs"   },
+{MEM_PROC_NR,   "memory"},
+{LOG_PROC_NR,   "log"   },
+{TTY_PROC_NR,   "tty"   },
+{MFS_PROC_NR,   "mfs"   },
+{VM_PROC_NR,    "vm"    },
+{PFS_PROC_NR,   "pfs"   },
+{INIT_PROC_NR,  "init"  },
 };
 
-/* Verify the size of the system image table at compile time.
- * If a problem is detected, the size of the 'dummy' array will be negative, 
- * causing a compile time error. Note that no space is actually allocated 
- * because 'dummy' is declared extern.
- */
-extern int dummy[(NR_BOOT_PROCS==sizeof(image)/
-       sizeof(struct boot_image))?1:-1];
index 27aa46e2872480f1f30084fe3e83c95a70800d23..4c45bcf656a10fa7f961e044690bd1e8a6f7e5b9 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <minix/com.h>
 #include <machine/interrupt.h>
+#include <machine/multiboot.h>
 
 /* Process table and system property related types. */ 
 typedef int proc_nr_t;                 /* process table entry number */
@@ -11,26 +12,6 @@ typedef struct {                     /* bitmap for system indexes */
   bitchunk_t chunk[BITMAP_CHUNKS(NR_SYS_PROCS)];
 } sys_map_t;
 
-struct boot_image_memmap {
-  phys_bytes text_vaddr;               /* Virtual start address of text */
-  phys_bytes text_paddr;               /* Physical start address of text */
-  phys_bytes text_bytes;               /* Text segment's size (bytes) */
-  phys_bytes data_vaddr;               /* Virtual start address of data */
-  phys_bytes data_paddr;               /* Physical start address of data */
-  phys_bytes data_bytes;               /* Data segment's size (bytes) */
-  phys_bytes stack_bytes;              /* Size of stack set aside (bytes) */
-  phys_bytes entry;                    /* Entry point of executable */
-};
-
-struct boot_image {
-  proc_nr_t proc_nr;                   /* process number to use */
-  int flags;                           /* process flags */
-  int stack_kbytes;                    /* stack size (in KB) */
-  char proc_name[P_NAME_LEN];          /* name in process table */
-  endpoint_t endpoint;                 /* endpoint number when started */
-  struct boot_image_memmap memmap;     /* memory map info for boot image */
-};
-
 typedef unsigned long irq_policy_t;    
 typedef unsigned long irq_id_t;        
 
index a513b57e247d757da25b3bb62dcd930c62c386ec..1751573f511eec160fe6bad607d9a90b90d5b2ce 100644 (file)
@@ -24,10 +24,10 @@ void panic(const char *fmt, ...)
 {
   va_list arg;
   /* The system has run aground of a fatal kernel error. Terminate execution. */
-  if (minix_panicing == ARE_PANICING) {
+  if (kinfo.minix_panicing == ARE_PANICING) {
        reset();
   }
-  minix_panicing = ARE_PANICING;
+  kinfo.minix_panicing = ARE_PANICING;
   if (fmt != NULL) {
        printf("kernel panic: ");
        va_start(arg, fmt);
@@ -38,8 +38,12 @@ void panic(const char *fmt, ...)
   printf("kernel on CPU %d: ", cpuid);
   util_stacktrace();
 
-  printf("current process : ");
-  proc_stacktrace(get_cpulocal_var(proc_ptr));
+#if 0
+  if(get_cpulocal_var(proc_ptr)) {
+         printf("current process : ");
+         proc_stacktrace(get_cpulocal_var(proc_ptr));
+  }
+#endif
 
   /* Abort MINIX. */
   minix_shutdown(NULL);
@@ -55,29 +59,29 @@ int c;                                      /* character to append */
  * to the output driver if an END_OF_KMESS is encountered. 
  */
   if (c != END_OF_KMESS) {
-      static int blpos = 0;
-      int maxblpos = sizeof(kmess_buf) - 2;
+      int maxblpos = sizeof(kmess.kmess_buf) - 2;
 #ifdef DEBUG_SERIAL
-      if (do_serial_debug) {
+      if (kinfo.do_serial_debug) {
        if(c == '\n')
                ser_putc('\r');
        ser_putc(c);
       }
 #endif
       kmess.km_buf[kmess.km_next] = c; /* put normal char in buffer */
-      kmess_buf[blpos] = c;
+      kmess.kmess_buf[kmess.blpos] = c;
       if (kmess.km_size < sizeof(kmess.km_buf))
           kmess.km_size += 1;          
       kmess.km_next = (kmess.km_next + 1) % _KMESS_BUF_SIZE;
-      if(blpos == maxblpos) {
-       memmove(kmess_buf, kmess_buf+1, sizeof(kmess_buf)-1);
-      } else blpos++;
+      if(kmess.blpos == maxblpos) {
+       memmove(kmess.kmess_buf,
+               kmess.kmess_buf+1, sizeof(kmess.kmess_buf)-1);
+      } else kmess.blpos++;
   } else {
       int p;
       endpoint_t outprocs[] = OUTPUT_PROCS_ARRAY;
-      if(!(minix_panicing || do_serial_debug)) {
+      if(!(kinfo.minix_panicing || kinfo.do_serial_debug)) {
              for(p = 0; outprocs[p] != NONE; p++) {
-                if(isokprocn(outprocs[p]) && !isemptyn(outprocs[p])) {
+                if(isokprocn(outprocs[p])) {
                    send_sig(outprocs[p], SIGKMESS);
                 }
        }
@@ -86,15 +90,3 @@ int c;                                       /* character to append */
   return;
 }
 
-void cpu_print_freq(unsigned cpu)
-{
-       u64_t freq;
-
-       freq = cpu_get_freq(cpu);
-       printf("CPU %d freq %lu MHz\n", cpu, div64u(freq, 1000000));
-}
-
-int is_fpu(void)
-{
-       return get_cpulocal_var(fpu_presence);
-}
index 4acfdbbd6f341e0865870c5b965404e02fd965de..301f34050c0d3b99ef902d79b2436f91a6ba8e2b 100644 (file)
@@ -14,4 +14,6 @@
 
 typedef struct _asynfd asynfd_t;
 
+#undef IDLE
+
 typedef enum state { IDLE, WAITING, PENDING } state_t;
index 88d248094d28ce665365ea835dda641ef706e951..6ff932c5d43719c1b43f71ece04c2b8b72514d6e 100644 (file)
@@ -933,7 +933,7 @@ static int init_buffers(sub_dev_t *sub_dev_ptr)
        }
 
        sub_dev_ptr->DmaPtr = sub_dev_ptr->DmaBuf;
-       i = sys_umap(SELF, D, 
+       i = sys_umap(SELF, VM_D, 
                        (vir_bytes) sub_dev_ptr->DmaBuf, 
                        (phys_bytes) sizeof(sub_dev_ptr->DmaBuf), 
                        &(sub_dev_ptr->DmaPhys));
index 4f2c15759f10438992db11f8ee77d709e73a174f..3fc9f71c64286da84a72fb401b7b98c8e7dc0332 100644 (file)
@@ -14,6 +14,7 @@
 #include <machine/elf.h>
 #include <machine/vmparam.h>
 #include <machine/memory.h>
+#include <minix/syslib.h>
 
 /* For verbose logging */
 #define ELF_DEBUG 0
@@ -59,16 +60,12 @@ static int elf_unpack(char *exec_hdr,
 {
   *hdr = (Elf_Ehdr *) exec_hdr;
   if(!elf_sane(*hdr)) {
-#if ELF_DEBUG
-       printf("elf_sane failed\n");
-#endif
+       printf("elf_unpack: elf_sane failed\n");
        return ENOEXEC;
   }
   *phdr = (Elf_Phdr *)(exec_hdr + (*hdr)->e_phoff);
   if(!elf_ph_sane(*phdr)) {
-#if ELF_DEBUG
-       printf("elf_ph_sane failed\n");
-#endif
+       printf("elf_unpack: elf_ph_sane failed\n");
        return ENOEXEC;
   }
 #if 0
@@ -77,98 +74,6 @@ static int elf_unpack(char *exec_hdr,
   return OK;
 }
 
-int read_header_elf(
-  char *exec_hdr,                /* executable header */
-  int hdr_len,                 /* significant bytes in exec_hdr */
-  vir_bytes *text_vaddr,       /* text virtual address */
-  phys_bytes *text_paddr,      /* text physical address */
-  vir_bytes *text_filebytes,   /* text segment size (in the file) */
-  vir_bytes *text_membytes,    /* text segment size (in memory) */
-  vir_bytes *data_vaddr,       /* data virtual address */
-  phys_bytes *data_paddr,      /* data physical address */
-  vir_bytes *data_filebytes,   /* data segment size (in the file) */
-  vir_bytes *data_membytes,    /* data segment size (in memory) */
-  vir_bytes *pc,               /* program entry point (initial PC) */
-  off_t *text_offset,          /* file offset to text segment */
-  off_t *data_offset           /* file offset to data segment */
-)
-{
-  Elf_Ehdr *hdr = NULL;
-  Elf_Phdr *phdr = NULL;
-  unsigned long seg_filebytes, seg_membytes;
-  int e, i = 0;
-
-  *text_vaddr = *text_paddr = 0;
-  *text_filebytes = *text_membytes = 0;
-  *data_vaddr = *data_paddr = 0;
-  *data_filebytes = *data_membytes = 0;
-  *pc = *text_offset = *data_offset = 0;
-
-  if((e=elf_unpack(exec_hdr, hdr_len, &hdr, &phdr)) != OK) {
-#if ELF_DEBUG
-       printf("elf_unpack failed\n");
-#endif
-       return e;
-   }
-
-#if ELF_DEBUG
-  printf("Program header file offset (phoff): %ld\n", hdr->e_phoff);
-  printf("Section header file offset (shoff): %ld\n", hdr->e_shoff);
-  printf("Program header entry size (phentsize): %d\n", hdr->e_phentsize);
-  printf("Program header entry num (phnum): %d\n", hdr->e_phnum);
-  printf("Section header entry size (shentsize): %d\n", hdr->e_shentsize);
-  printf("Section header entry num (shnum): %d\n", hdr->e_shnum);
-  printf("Section name strings index (shstrndx): %d\n", hdr->e_shstrndx);
-  printf("Entry Point: 0x%lx\n", hdr->e_entry);
-#endif
-
-  for (i = 0; i < hdr->e_phnum; i++) {
-      switch (phdr[i].p_type) {
-      case PT_LOAD:
-         if (phdr[i].p_memsz == 0)
-             break;
-         seg_filebytes = phdr[i].p_filesz;
-         seg_membytes = round_page(phdr[i].p_memsz + phdr[i].p_vaddr -
-                                   trunc_page(phdr[i].p_vaddr));
-
-         if (hdr->e_entry >= phdr[i].p_vaddr &&
-             hdr->e_entry < (phdr[i].p_vaddr + phdr[i].p_memsz)) {
-             *text_vaddr = phdr[i].p_vaddr;
-             *text_paddr = phdr[i].p_paddr;
-             *text_filebytes = seg_filebytes;
-             *text_membytes = seg_membytes;
-             *pc = (vir_bytes)hdr->e_entry;
-             *text_offset = phdr[i].p_offset;
-         } else {
-             *data_vaddr = phdr[i].p_vaddr;
-             *data_paddr = phdr[i].p_paddr;
-             *data_filebytes = seg_filebytes;
-             *data_membytes = seg_membytes;
-             *data_offset = phdr[i].p_offset;
-         }
-         break;
-      default:
-         break;
-      }
-  }
-
-#if ELF_DEBUG
-  printf("Text vaddr:     0x%lx\n", *text_vaddr);
-  printf("Text paddr:     0x%lx\n", *text_paddr);
-  printf("Text filebytes: 0x%lx\n", *text_filebytes);
-  printf("Text membytes:  0x%lx\n", *text_membytes);
-  printf("Data vaddr:     0x%lx\n", *data_vaddr);
-  printf("Data paddr:     0x%lx\n", *data_paddr);
-  printf("Data filebyte:  0x%lx\n", *data_filebytes);
-  printf("Data membytes:  0x%lx\n", *data_membytes);
-  printf("PC:             0x%lx\n", *pc);
-  printf("Text offset:    0x%lx\n", *text_offset);
-  printf("Data offset:    0x%lx\n", *data_offset);
-#endif
-
-  return OK;
-}
-
 #define IS_ELF(ehdr)   ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \
                         (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \
                         (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \
@@ -243,8 +148,7 @@ int libexec_load_elf(struct exec_info *execi)
        }
 
        execi->stack_size = roundup(execi->stack_size, PAGE_SIZE);
-       execi->stack_high = VM_STACKTOP;
-       assert(!(VM_STACKTOP % PAGE_SIZE));
+       execi->stack_high = rounddown(execi->stack_high, PAGE_SIZE);
        stacklow = execi->stack_high - execi->stack_size;
 
        assert(execi->copymem);
@@ -311,6 +215,10 @@ int libexec_load_elf(struct exec_info *execi)
                return ENOMEM;
        }
 
+#if ELF_DEBUG
+       printf("stack mmapped 0x%lx-0x%lx\n", stacklow, stacklow+execi->stack_size);
+#endif
+
        /* record entry point and lowest load vaddr for caller */
        execi->pc = hdr->e_entry;
        execi->load_base = startv;
index 1887c7f23ae34848afc292e37279545dbb740f0f..20d3ca9eed364f6b5666e7fac2a7b86582ff50ad 100644 (file)
@@ -49,6 +49,20 @@ int libexec_clear_sys_memset(struct exec_info *execi, off_t vaddr, size_t len)
        return sys_memset(execi->proc_e, 0, vaddr, len);
 }
 
+int libexec_copy_memcpy(struct exec_info *execi,
+       off_t off, off_t vaddr, size_t len)
+{
+       assert(off + len <= execi->hdr_len);
+       memcpy((char *) vaddr, (char *) execi->hdr + off, len);
+       return OK;
+}
+
+int libexec_clear_memset(struct exec_info *execi, off_t vaddr, size_t len)
+{
+       memset((char *) vaddr, 0, len);
+       return OK;
+}
+
 void libexec_patch_ptr(char stack[ARG_MAX], vir_bytes base)
 {
 /* When doing an exec(name, argv, envp) call, the user builds up a stack
index 613839c600637fb3a754d3e6810b9b31e398d1bb..5169c4b21434a680145e601e96bfc0d97fa889f8 100644 (file)
@@ -44,12 +44,6 @@ struct exec_info {
 
 int elf_has_interpreter(char *exec_hdr, int hdr_len, char *interp, int maxsz);
 int elf_phdr(char *exec_hdr, int hdr_len, vir_bytes *phdr);
-int read_header_elf(char *exec_hdr, int hdr_len,
-   vir_bytes *text_vaddr, phys_bytes *text_paddr,
-   vir_bytes *text_filebytes, vir_bytes *text_membytes,
-   vir_bytes *data_vaddr, phys_bytes *data_paddr,
-   vir_bytes *data_filebytes, vir_bytes *data_membytes,
-   vir_bytes *pc, off_t *text_offset, off_t *data_offset);
 
 void libexec_patch_ptr(char stack[ARG_MAX], vir_bytes base);
 int libexec_pm_newexec(endpoint_t proc_e, struct exec_info *execi);
@@ -57,6 +51,8 @@ int libexec_pm_newexec(endpoint_t proc_e, struct exec_info *execi);
 typedef int (*libexec_exec_loadfunc_t)(struct exec_info *execi);
 int libexec_load_elf(struct exec_info *execi);
 
+int libexec_copy_memcpy(struct exec_info *execi, off_t offset, off_t vaddr, size_t len);
+int libexec_clear_memset(struct exec_info *execi, off_t vaddr, size_t len);
 int libexec_alloc_mmap_prealloc(struct exec_info *execi, off_t vaddr, size_t len);
 int libexec_alloc_mmap_ondemand(struct exec_info *execi, off_t vaddr, size_t len);
 int libexec_clearproc_vm_procctl(struct exec_info *execi);
index 7a9630efd1f02f89b67296b1e67a170abd73f215..52d8db2dc2296eeccfc197eb761fd3ec12769195 100644 (file)
@@ -7,21 +7,15 @@
 int _cpufeature(int cpufeature)
 {
        u32_t eax, ebx, ecx, edx;
-       int proc;
 
        eax = ebx = ecx = edx = 0;
-       proc = getprocessor();
 
-       /* If processor supports CPUID and its CPUID supports enough
-        * parameters, retrieve EDX feature flags to test against.
-        */
-       if(proc >= 586) {
-               eax = 0;
+       /* We assume >= pentium for cpuid */
+       eax = 0;
+       _cpuid(&eax, &ebx, &ecx, &edx);
+       if(eax > 0) {
+               eax = 1;
                _cpuid(&eax, &ebx, &ecx, &edx);
-               if(eax > 0) {
-                       eax = 1;
-                       _cpuid(&eax, &ebx, &ecx, &edx);
-               }
        }
 
        switch(cpufeature) {
index 1076178f45b640ab5b198a08909fb0fc5073e6ab..9f91256a74e40e774130e896902b7edb77589005 100644 (file)
@@ -74,7 +74,6 @@ SRCS=  \
        sys_kill.c \
        sys_mcontext.c \
        sys_memset.c \
-       sys_newmap.c \
        sys_out.c \
        sys_physcopy.c \
        sys_privctl.c \
@@ -127,7 +126,7 @@ SRCS=  \
        vm_umap.c \
        vm_yield_get_block.c \
        vm_procctl.c \
-       vprintf.c \
+       vprintf.c
 
 .if ${MKCOVERAGE} != "no"
 SRCS+= gcov.c \
index 03db92f1326dd1fe30c4fde130fe9f0bfe8e593f..280598e76cd2c0690053eedae521b033f75c3307 100644 (file)
@@ -6,21 +6,6 @@
 #include <sys/mman.h>
 #include <minix/sysutil.h>
 
-int sys_umap_data_fb(endpoint_t ep, vir_bytes buf, vir_bytes len, phys_bytes *phys)
-{
-       int r;
-
-        if((r=sys_umap(ep, VM_D, buf, len, phys)) != OK) {
-               if(r != EINVAL)
-                       return r;
-               r = sys_umap(ep, D, buf, len, phys);
-       }
-
-
-       return r;
-}
-
-
 void *alloc_contig(size_t len, int flags, phys_bytes *phys)
 {
        vir_bytes buf;
@@ -66,7 +51,7 @@ void *alloc_contig(size_t len, int flags, phys_bytes *phys)
        }
 
        /* Get physical address, if requested. */
-        if(phys != NULL && sys_umap_data_fb(SELF, buf, len, phys) != OK)
+        if(phys != NULL && sys_umap(SELF, VM_D, buf, len, phys) != OK)
                panic("sys_umap_data_fb failed");
 
        return (void *) buf;
index da2031beedd6bdf7dbb3c8879e62f2b8c56fcf02..24e577a7cdcc132e768fc016fff2444160f22559 100644 (file)
@@ -26,7 +26,7 @@ char *value;                          /* where to store value */
 int max_len;                           /* maximum length of value */
 {
   message m;
-  static char mon_params[128*sizeof(char *)];  /* copy parameters here */
+  static char mon_params[MULTIBOOT_PARAM_BUF_SIZE]; /* copy parameters here */
   char *key_value;
   int i, s;
   size_t keylen;
index b48d763b54ef38714787779bd5b3c1eac6b9621a..8e93252cd5ec32950b89f20b93e969f71682fcb4 100644 (file)
@@ -97,44 +97,17 @@ int env_memory_parse(mem_chunks, maxchunks)
 struct memory *mem_chunks;     /* where to store the memory bits */
 int maxchunks;                 /* how many were found */
 {
-  int i, done = 0;
-  char *s;
-  struct memory *memp;
-  char memstr[100], *end;
+  static kinfo_t kinfo;
+  int mm;
 
-  /* Initialize everything to zero. */
-  for (i = 0; i < maxchunks; i++) {
-       memp = &mem_chunks[i];          /* next mem chunk is stored here */
-       memp->base = memp->size = 0;
-  }
-
-  /* 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. 
-   */
-  if(env_get_param("memory", memstr, sizeof(memstr)-1) != OK)
-       return -1;
-  s = memstr;
-  for (i = 0; i < maxchunks && !done; i++) {
-       phys_bytes base = 0, size = 0;
-       memp = &mem_chunks[i];          /* next mem chunk is stored here */
-       if (*s != 0) {                  /* get fresh data, unless at end */     
+  sys_getkinfo(&kinfo);
 
-           /* Read fresh base and expect colon as next char. */ 
-           base = strtoul(s, &end, 0x10);              /* get number */
-           if (end != s && *end == ':') s = ++end;     /* skip ':' */ 
-           else *s=0;                  /* terminate, should not happen */
+  /* Initialize everything to zero. */
+  memset(mem_chunks, 0, maxchunks*sizeof(*mem_chunks));
 
-           /* Read fresh size and expect comma or assume end. */ 
-           size = strtoul(s, &end, 0x10);              /* get number */
-           if (end != s && *end == ',') s = ++end;     /* skip ',' */
-           else done = 1;
-       }
-       if (base + size <= base) continue;
-       memp->base = base;
-       memp->size = size;
+  for(mm = 0; mm < MAXMEMMAP; mm++) {
+       mem_chunks[mm].base = kinfo.memmap[mm].addr;
+       mem_chunks[mm].size = kinfo.memmap[mm].len;
   }
 
   return OK;
index 2f6d7135a0ea77afaa18fe3cb146fd01e23e3f3e..9e73012728756f578a171acddcf9be5795549ddf 100644 (file)
@@ -26,6 +26,7 @@ void kputc(int c)
   if (c != 0) { 
         
         /* Append a single character to the output buffer. */
-       print_buf[buf_count++] = c;
+       print_buf[buf_count] = c;
+       buf_count++;
   }
 }
index f1bc4eee82772d9f8be6a2952a1fa4e95d4a7ad6..c625ce1b7d1f5464020735582023532ceb66101a 100644 (file)
@@ -84,7 +84,9 @@ void sef_startup()
           panic("RS unable to complete init: %d", r);
       }
   }
-  else {
+  else if(sef_self_endpoint == VM_PROC_NR) {
+       /* VM handles initialization by RS later */
+  } else {
       message m;
 
       /* Wait for an initialization message from RS. We need this to learn the
index f978f40eb2af73ff48d0e348a51437417f038c0a..811e2301d1699be7c8451c5c6ae72903a6561b2c 100644 (file)
@@ -1,10 +1,9 @@
 #include "syslib.h"
 
-int sys_fork(parent, child, child_endpoint, map_ptr, flags, msgaddr)
+int sys_fork(parent, child, child_endpoint, flags, msgaddr)
 endpoint_t parent;             /* process doing the fork */
 endpoint_t child;              /* which proc has been created by the fork */
 endpoint_t *child_endpoint;
-struct mem_map *map_ptr;
 u32_t flags;
 vir_bytes *msgaddr;
 {
@@ -15,7 +14,6 @@ vir_bytes *msgaddr;
 
   m.PR_ENDPT = parent;
   m.PR_SLOT = child;
-  m.PR_MEM_PTR = (char *) map_ptr;
   m.PR_FORK_FLAGS = flags;
   r = _kernel_call(SYS_FORK, &m);
   *child_endpoint = m.PR_ENDPT;
diff --git a/lib/libsys/sys_newmap.c b/lib/libsys/sys_newmap.c
deleted file mode 100644 (file)
index 764a703..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#include "syslib.h"
-
-int sys_newmap(
-endpoint_t proc_ep,            /* process whose map is to be changed */
-struct mem_map *ptr            /* pointer to new map */
-)
-{
-/* A process has been assigned a new memory map.  Tell the kernel. */
-
-  message m;
-
-  m.PR_ENDPT = proc_ep;
-  m.PR_MEM_PTR = (char *) ptr;
-  return(_kernel_call(SYS_NEWMAP, &m));
-}
index 9c1dab179daa38c49970f45aedb2a0fd8832501b..3698332df4b5e8091011e6e19c151d2e1ef4f4ac 100644 (file)
@@ -25,8 +25,8 @@ phys_bytes bytes;             /* how many bytes */
   /* provide backwards compatability arguments to old
    * kernels based on process id's; NONE <=> physical
    */
-  copy_mess.CP_DST_SPACE_OBSOLETE = (dst_proc == NONE ? PHYS_SEG : D);
-  copy_mess.CP_SRC_SPACE_OBSOLETE = (src_proc == NONE ? PHYS_SEG : D);
+  copy_mess.CP_DST_SPACE_OBSOLETE = (dst_proc == NONE ? PHYS_SEG : D_OBSOLETE);
+  copy_mess.CP_SRC_SPACE_OBSOLETE = (src_proc == NONE ? PHYS_SEG : D_OBSOLETE);
 
   return(_kernel_call(SYS_PHYSCOPY, &copy_mess));
 }
index bc2b6f78173437fbd7843a227b8017c2eb5e83af..4140b12a477449f666bacba0c2de4ce961a941b9 100644 (file)
@@ -22,7 +22,7 @@ int sys_safecopyfrom(endpoint_t src_e,
   /* for older kernels that still need the 'seg' field
    * provide the right value.
    */
-  copy_mess.SCP_SEG_OBSOLETE = D;
+  copy_mess.SCP_SEG_OBSOLETE = D_OBSOLETE;
 
   return(_kernel_call(SYS_SAFECOPYFROM, &copy_mess));
 
@@ -47,7 +47,7 @@ int sys_safecopyto(endpoint_t dst_e,
   /* for older kernels that still need the 'seg' field
    * provide the right value.
    */
-  copy_mess.SCP_SEG_OBSOLETE = D;
+  copy_mess.SCP_SEG_OBSOLETE = D_OBSOLETE;
 
   return(_kernel_call(SYS_SAFECOPYTO, &copy_mess));
 
index 426b7d58a0fa482a9f8955c15c13735cbe74000f..e3d3d111feb83f92934469982b2c8b3267e3e4f9 100644 (file)
@@ -23,7 +23,7 @@ int sys_safemap(endpoint_t grantor, cp_grant_id_t grant,
        copy_mess.SMAP_BYTES = bytes;
        copy_mess.SMAP_FLAG = writable;
 
-       copy_mess.SMAP_SEG_OBSOLETE = (void *) D;
+       copy_mess.SMAP_SEG_OBSOLETE = (void *) D_OBSOLETE;
 
        return(_kernel_call(SYS_SAFEMAP, &copy_mess));
 
@@ -67,7 +67,7 @@ int sys_safeunmap(vir_bytes my_address)
 
        copy_mess.SMAP_ADDRESS = my_address;
 
-       copy_mess.SMAP_SEG_OBSOLETE = (void *) D;
+       copy_mess.SMAP_SEG_OBSOLETE = (void *) D_OBSOLETE;
 
        return(_kernel_call(SYS_SAFEUNMAP, &copy_mess));
 }
index a9e57abb81fdfe23f95411d63195f899a503a8f2..29e8d2c66292f81c7a74f8bc0a828b46feb0f549 100644 (file)
@@ -23,8 +23,8 @@ phys_bytes bytes;             /* how many bytes */
   copy_mess.CP_NR_BYTES = (long) bytes;
 
   /* backwards compatability D segs */
-  copy_mess.CP_DST_SPACE_OBSOLETE = D;
-  copy_mess.CP_SRC_SPACE_OBSOLETE = D;
+  copy_mess.CP_DST_SPACE_OBSOLETE = D_OBSOLETE;
+  copy_mess.CP_SRC_SPACE_OBSOLETE = D_OBSOLETE;
 
   return(_kernel_call(SYS_VIRCOPY, &copy_mess));
 }
index c0aef7fecf526465afacca05e6e917fe89df10ca..08951f65cfed344f06de912637e18cb08147a207 100644 (file)
@@ -63,15 +63,6 @@ int sys_vmctl_get_memreq(endpoint_t *who, vir_bytes *mem,
   return r;
 }
 
-int sys_vmctl_enable_paging(void * data)
-{
-       message m;
-       m.SVMCTL_WHO = SELF;
-       m.SVMCTL_PARAM = VMCTL_ENABLE_PAGING;
-       m.SVMCTL_VALUE = (u32_t) data;
-       return _kernel_call(SYS_VMCTL, &m);
-}
-
 int sys_vmctl_get_mapping(int index,
        phys_bytes *addr, phys_bytes *len, int *flags)
 {
index b3a2893fd9e1d1d47c94419835995cce8ad7debf..695c5b10cc03486b140dc4e28b9d953dc2c7d704 100644 (file)
@@ -131,7 +131,7 @@ char
 VAssert_Init(void)
 {
    uint32 eax, ebx, ecx, edx;
-   VA page_address = (VA) &vassert_state.inReplay, ph;
+   VA page_address = (VA) &vassert_state.inReplay;
    if (!VAssert_IsInVM()) {
       return -1;
    }
@@ -143,16 +143,7 @@ VAssert_Init(void)
    }
 #endif
 
-   /* vmware expects a linear address (or is simply forgetting
-    * to adjust the given address for segments)
-    */
-
-   if(sys_umap(SELF, D, page_address, 1, (phys_bytes *) &ph)) {
-       printf("VAssert_Init: sys_umap failed\n");
-       return -1;
-   }
-
-   libvassert_process_backdoor(CMD_SET_ADDRESS, ph,
+   libvassert_process_backdoor(CMD_SET_ADDRESS, page_address,
        MAGIC_PORT|(1<<16), &eax, &ebx, &ecx, &edx);
 
    return (eax != -1) ? 0 : -1;
index 71b807834c4f6f0c4190b69d83402efbcbed3e8f..95d47b3940306c60c5c521bf1a0c6b88cb6d1ddd 100644 (file)
@@ -8,6 +8,4 @@ MAN=
 
 BINDIR?= /usr/sbin
 
-LDFLAGS+= -Wl,--section-start=.init=0x0
-
 .include <bsd.prog.mk>
index 1e8b65e89fac167bbbc0f745db8de1d6349914bf..a33b7d07717d19e4c3d16393090648d1c78476c9 100644 (file)
@@ -17,7 +17,6 @@ struct hook_entry {
        char *name;
 } hooks[] = {
        { F1,   proctab_dmp, "Kernel process table" },
-       { F2,   memmap_dmp, "Process memory maps" },
        { F3,   image_dmp, "System image" },
        { F4,   privileges_dmp, "Process privileges" },
        { F5,   monparams_dmp, "Boot monitor parameters" },
index 77b98a05f717d1911fdcd8a812daf9238d4dcd84..36f1116f52b53fab174df355ba99b35616fdf69e 100644 (file)
@@ -45,7 +45,6 @@ static char *proc_name(int proc_nr);
 static char *s_traps_str(int flags);
 static char *s_flags_str(int flags);
 static char *p_rts_flags_str(int flags);
-static char *boot_flags_str(int flags);
 
 /* Some global data that is shared among several dumping procedures. 
  * Note that the process table copy has the same name as in the kernel
@@ -92,7 +91,7 @@ void kmessages_dmp()
  *===========================================================================*/
 void monparams_dmp()
 {
-  char val[1024];
+  char val[MULTIBOOT_PARAM_BUF_SIZE];
   char *e;
   int r;
 
@@ -160,18 +159,6 @@ void irqtab_dmp()
   printf("\n");
 }
 
-/*===========================================================================*
- *                           boot_flags_str                                 *
- *===========================================================================*/
-static char *boot_flags_str(int flags)
-{
-       static char str[10];
-       str[0] = (flags & PROC_FULLVM)        ? 'V' : '-';
-       str[1] = '\0';
-
-       return str;
-}
-
 /*===========================================================================*
  *                             image_dmp                                    *
  *===========================================================================*/
@@ -188,9 +175,7 @@ void image_dmp()
   printf("---name- -nr- flags -stack-\n");
   for (m=0; m<NR_BOOT_PROCS; m++) { 
       ip = &image[m];
-      printf("%8s %4d %5s\n",
-          ip->proc_name, ip->proc_nr,
-          boot_flags_str(ip->flags));
+      printf("%8s %4d\n", ip->proc_name, ip->proc_nr);
   }
   printf("\n");
 }
@@ -215,15 +200,6 @@ void kenv_dmp()
 
     printf("Dump of kinfo structure.\n\n");
     printf("Kernel info structure:\n");
-    printf("- code_base:  %5lu\n", kinfo.code_base); 
-    printf("- code_size:  %5lu\n", kinfo.code_size); 
-    printf("- data_base:  %5lu\n", kinfo.data_base); 
-    printf("- data_size:  %5lu\n", kinfo.data_size); 
-    printf("- proc_addr:  %5lu\n", kinfo.proc_addr); 
-    printf("- bootdev_base:  %5lu\n", kinfo.bootdev_base); 
-    printf("- bootdev_size:  %5lu\n", kinfo.bootdev_size); 
-    printf("- ramdev_base:   %5lu\n", kinfo.ramdev_base); 
-    printf("- ramdev_size:   %5lu\n", kinfo.ramdev_size); 
     printf("- nr_procs:     %3u\n", kinfo.nr_procs); 
     printf("- nr_tasks:     %3u\n", kinfo.nr_tasks); 
     printf("- release:      %.6s\n", kinfo.release); 
@@ -341,7 +317,6 @@ void proctab_dmp()
   register struct proc *rp;
   static struct proc *oldrp = BEG_PROC_ADDR;
   int r;
-  phys_clicks text, data, size;
 
   /* First obtain a fresh copy of the current process table. */
   if ((r = sys_getproctab(proc)) != OK) {
@@ -352,10 +327,6 @@ void proctab_dmp()
   printf("\n-nr-----gen---endpoint-name--- -prior-quant- -user----sys-rtsflags-from/to-\n");
 
   PROCLOOP(rp, oldrp)
-       text = rp->p_memmap[T].mem_phys;
-       data = rp->p_memmap[D].mem_phys;
-       size = rp->p_memmap[T].mem_len
-               + ((rp->p_memmap[S].mem_phys + rp->p_memmap[S].mem_len) - data);
        printf(" %5d %10d ", _ENDPOINT_G(rp->p_endpoint), rp->p_endpoint);
        printf("%-8.8s %5u %5u %6lu %6lu ",
               rp->p_name,
@@ -393,38 +364,6 @@ void procstack_dmp()
   }
 }
 
-/*===========================================================================*
- *                             memmap_dmp                                   *
- *===========================================================================*/
-void memmap_dmp()
-{
-  register struct proc *rp;
-  static struct proc *oldrp = proc;
-  int r;
-  phys_clicks size;
-
-  /* First obtain a fresh copy of the current process table. */
-  if ((r = sys_getproctab(proc)) != OK) {
-      printf("IS: warning: couldn't get copy of process table: %d\n", r);
-      return;
-  }
-
-  printf("\n-nr/name--- --pc--   --sp-- -text---- -data---- -stack--- -cr3-\n");
-  PROCLOOP(rp, oldrp)
-       size = rp->p_memmap[T].mem_len
-               + ((rp->p_memmap[S].mem_phys + rp->p_memmap[S].mem_len)
-                                               - rp->p_memmap[D].mem_phys);
-       printf("%-7.7s%7lx %8lx %4x %4x %4x %4x %5x %5x %8u\n",
-              rp->p_name,
-              (unsigned long) rp->p_reg.pc,
-              (unsigned long) rp->p_reg.sp,
-              rp->p_memmap[T].mem_phys, rp->p_memmap[T].mem_len,
-              rp->p_memmap[D].mem_phys, rp->p_memmap[D].mem_len,
-              rp->p_memmap[S].mem_phys, rp->p_memmap[S].mem_len,
-              rp->p_seg.p_cr3);
-  }
-}
-
 /*===========================================================================*
  *                             proc_name                                    *
  *===========================================================================*/
index 6d61ac556b7fc63250dc15d444f9e91dc9ad2482..ad43b9a24dceb0e315fb8b9643f9889d7f48f189 100644 (file)
@@ -12,14 +12,12 @@ static void print_region(struct vm_region_info *vri, int *n)
 {
   static int vri_count, vri_prev_set;
   static struct vm_region_info vri_prev;
-  char c;
   int is_repeat;
 
   /* part of a contiguous identical run? */
   is_repeat =
        vri &&
        vri_prev_set && 
-       vri->vri_seg == vri_prev.vri_seg &&
        vri->vri_prot == vri_prev.vri_prot &&
        vri->vri_flags == vri_prev.vri_flags &&
        vri->vri_length == vri_prev.vri_length &&
@@ -44,14 +42,7 @@ static void print_region(struct vm_region_info *vri, int *n)
   /* NULL indicates the end of a list of mappings, nothing else to do */
   if (!vri) return;
 
-  /* first in a run, print all info */
-  switch (vri->vri_seg) {
-  case T: c = 'T'; break;
-  case D: c = 'D'; break;
-  default: c = '?';
-  }
-
-  printf("  %c %08lx-%08lx %c%c%c %c (%lu kB)\n", c, vri->vri_addr,
+  printf("  %08lx-%08lx %c%c%c %c (%lu kB)\n", vri->vri_addr,
        vri->vri_addr + vri->vri_length,
        (vri->vri_prot & PROT_READ) ? 'r' : '-',
        (vri->vri_prot & PROT_WRITE) ? 'w' : '-',
index 1dd800585a427bf28900762a13fa84834810e63a..bc8a8c59078472f1ed7cc92d281298a4aa72aa9b 100644 (file)
@@ -12,7 +12,6 @@ void vm_dmp(void);
 /* dmp_kernel.c */
 void proctab_dmp(void);
 void procstack_dmp(void);
-void memmap_dmp(void);
 void privileges_dmp(void);
 void image_dmp(void);
 void irqtab_dmp(void);
index c29b5ec2642cc4dfc899b85958e2c58edc8da74f..d000fc708f431578d5693b65a3a813a4d860cc82 100644 (file)
@@ -12,7 +12,7 @@
  *
  * The entry points into this file are:
  *   do_exec:   perform the EXEC system call
- *   do_exec_newmem: allocate new memory map for a process that tries to exec
+ *   do_newexec: handle PM part of exec call after VFS
  *   do_execrestart: finish the special exec call for RS
  *   exec_restart: finish a regular exec call
  */
@@ -73,14 +73,14 @@ int do_newexec()
 
        proc_e= m_in.EXC_NM_PROC;
        if (pm_isokendpt(proc_e, &proc_n) != OK) {
-               panic("do_exec_newmem: got bad endpoint: %d", proc_e);
+               panic("do_newexec: got bad endpoint: %d", proc_e);
        }
        rmp= &mproc[proc_n];
        ptr= m_in.EXC_NM_PTR;
        r= sys_datacopy(who_e, (vir_bytes)ptr,
                SELF, (vir_bytes)&args, sizeof(args));
        if (r != OK)
-               panic("do_exec_newmem: sys_datacopy failed: %d", r);
+               panic("do_newexec: sys_datacopy failed: %d", r);
 
        allow_setuid = 0;       /* Do not allow setuid execution */
        rmp->mp_flags &= ~TAINTED;      /* By default not tainted */
index d512e0f18362c67b97b735adf0b2c70d1abc4455..ef483e4506ef5a37d48c68a30f9c2c4187a7f297 100644 (file)
@@ -7,7 +7,7 @@
 /* Global variables. */
 EXTERN struct mproc *mp;       /* ptr to 'mproc' slot of current process */
 EXTERN int procs_in_use;       /* how many processes are marked as IN_USE */
-EXTERN char monitor_params[128*sizeof(char *)];        /* boot monitor parameters */
+EXTERN char monitor_params[MULTIBOOT_PARAM_BUF_SIZE];
 EXTERN struct kinfo kinfo;     /* kernel information */
 
 /* Misc.c */
@@ -25,7 +25,6 @@ EXTERN sigset_t noign_sset;   /* which signals cannot be ignored */
 
 EXTERN u32_t system_hz;                /* System clock frequency. */
 EXTERN int abort_flag;
-EXTERN char monitor_code[256];         
 
 EXTERN struct machine machine;         /* machine info */
 #ifdef CONFIG_SMP
index ac140b92afe3cdf31ec390e69c862e103497cd9e..72750f4b8914a25077f33c2b10a4e6bf560b84e9 100644 (file)
@@ -399,16 +399,11 @@ static void handle_vfs_reply()
    * Handle its reply first.
    */
   if (call_nr == PM_REBOOT_REPLY) {
-       vir_bytes code_addr;
-       size_t code_size;
-
        /* Ask the kernel to abort. All system services, including
         * the PM, will get a HARD_STOP notification. Await the
         * notification in the main loop.
         */
-       code_addr = (vir_bytes) monitor_code;
-       code_size = strlen(monitor_code) + 1;
-       sys_abort(abort_flag, PM_PROC_NR, code_addr, code_size);
+       sys_abort(RBT_DEFAULT);
 
        return;
   }
index 705c1088d070b6911c63f11b083d4d9c3dfb9c50..c052a7d8386ae6993925fa229c875f1db5ef933d 100644 (file)
@@ -294,17 +294,6 @@ int do_reboot()
   /* See how the system should be aborted. */
   abort_flag = (unsigned) m_in.reboot_flag;
   if (abort_flag >= RBT_INVALID) return(EINVAL); 
-  if (RBT_MONITOR == abort_flag) {
-       int r;
-       if(m_in.reboot_strlen >= sizeof(monitor_code))
-               return EINVAL;
-       if((r = sys_datacopy(who_e, (vir_bytes) m_in.reboot_code,
-               SELF, (vir_bytes) monitor_code, m_in.reboot_strlen)) != OK)
-               return r;
-       monitor_code[m_in.reboot_strlen] = '\0';
-  }
-  else
-       monitor_code[0] = '\0';
 
   /* Order matters here. When VFS is told to reboot, it exits all its
    * processes, and then would be confused if they're exited again by
index a0703299448e536e46974d2712a93f7186d38d20..faa984aaaac99fee72ad23b23c5dc58db22cb6b6 100644 (file)
@@ -112,18 +112,8 @@ static void pid_psinfo(int i)
                memset(&vui, 0, sizeof(vui));
 
                if (!is_zombie(i)) {
-                       /* We don't care if this fails. It may still return
-                        * zero memory usage for processes that don't have a
-                        * pagetable, though. Look at vui_total instead.
-                        */
+                       /* We don't care if this fails.  */
                        (void) vm_info_usage(proc[i].p_endpoint, &vui);
-
-                       if (vui.vui_total == 0L) {
-                               vui.vui_total =
-                                       (proc[i].p_memmap[T].mem_len +
-                                       proc[i].p_memmap[D].mem_len) <<
-                                       CLICK_SHIFT;
-                       }
                }
 
                if (mproc[pi].mp_flags & PAUSED)
@@ -340,7 +330,7 @@ static int dump_regions(int slot)
         */
        struct vm_region_info vri[MAX_VRI_COUNT];
        vir_bytes next;
-       int i, r, seg, count;
+       int i, r, count;
 
        count = 0;
        next = 0;
@@ -356,15 +346,8 @@ static int dump_regions(int slot)
                        break;
 
                for (i = 0; i < r; i++) {
-                       switch (vri[i].vri_seg) {
-                       case T: seg = 'T'; break;
-                       case D: seg = 'D'; break;
-                       default: seg = '?'; break;
-                       }
-
-                       buf_printf("%c %08lx-%08lx %c%c%c %c\n",
-                               seg, vri[i].vri_addr,
-                               vri[i].vri_addr + vri[i].vri_length,
+                       buf_printf("%08lx-%08lx %c%c%c %c\n",
+                               vri[i].vri_addr, vri[i].vri_addr + vri[i].vri_length,
                                (vri[i].vri_prot & PROT_READ) ? 'r' : '-',
                                (vri[i].vri_prot & PROT_WRITE) ? 'w' : '-',
                                (vri[i].vri_prot & PROT_EXEC) ? 'x' : '-',
@@ -377,26 +360,6 @@ static int dump_regions(int slot)
        return count;
 }
 
-/*===========================================================================*
- *                             dump_segments                                *
- *===========================================================================*/
-static void dump_segments(int slot)
-{
-       /* Print the memory segments of a process.
-        */
-       int i;
-
-       for (i = 0; i < NR_LOCAL_SEGS; i++) {
-               buf_printf("%c %08lx-%08lx %s -\n",
-                       i == T ? 'T' : 'D',
-                       proc[slot].p_memmap[i].mem_vir << CLICK_SHIFT,
-                       (proc[slot].p_memmap[i].mem_vir +
-                       proc[slot].p_memmap[i].mem_len) << CLICK_SHIFT,
-                       (i == T) ? "r-x" :
-                       (proc[slot].p_memmap[T].mem_len == 0) ? "rwx" : "rw-");
-       }
-}
-
 /*===========================================================================*
  *                             pid_map                                      *
  *===========================================================================*/
@@ -415,10 +378,4 @@ static void pid_map(int slot)
                if (dump_regions(slot) != 0)
                        return;
        }
-
-       /* For kernel tasks, or for processes that have no regions according to
-        * VM, we assume they are not using virtual memory, and we print their
-        * segments instead.
-        */
-       dump_segments(slot);
 }
index 87733ef6e2a506f010f5a3dc09acf26e5e091014..4df7f5b960b7ca5240b8f936b78ea570ece8f6f4 100644 (file)
@@ -68,7 +68,7 @@
 #define SRV_SF   (SF_CORE_SRV)                 /* system services */
 #define SRVR_SF  (SRV_SF | SF_NEED_REPL)       /* services needing a replica */
 #define DSRV_SF  (0)                           /* dynamic system services */
-#define VM_SF    (SRVR_SF | SF_SYNCH_BOOT)     /* vm */
+#define VM_SF    (SRVR_SF)                             /* vm */
 
 /* Define device flags for the various process types. */
 #define SRV_DF   (DRV_FORCED)            /* system services */
index 1c3117c9266c20cb619f21a3549e9b3b9fe732e6..bb9d2b8221ecf965047a76e1c422c5c8e67ee1a0 100644 (file)
@@ -9,6 +9,7 @@ static int do_exec(int proc_e, char *exec, size_t exec_len, char *progname,
 static int exec_restart(int proc_e, int result, vir_bytes pc);
 static int read_seg(struct exec_info *execi, off_t off,
         off_t seg_addr, size_t seg_bytes);
+static int exec_restart(int proc_e, int result, vir_bytes pc);
 
 /* Array of loaders for different object formats */
 static struct exec_loaders {
@@ -119,6 +120,7 @@ static int do_exec(int proc_e, char *exec, size_t exec_len, char *progname,
 
        memset(&execi, 0, sizeof(execi));
 
+       execi.stack_high = kinfo.user_sp;
        execi.stack_size = DEFAULT_STACK_LIMIT;
        execi.proc_e = proc_e;
        execi.hdr = exec;
index 4c883ad21f76b1896f4783d7d172427058db2dc7..d34a4b7ebb3a342d64a7fa6612be7b06e59fb72a 100644 (file)
@@ -52,5 +52,7 @@ EXTERN unsigned system_hz;
 
 EXTERN struct machine machine;         /* machine info */
 
+EXTERN struct kinfo kinfo;     /* kernel information */
+
 #endif /* RS_GLO_H */
 
index f7e0e910caca985b8e3e9f12c0321345b18f87f9..a4c070b43472930a205d9cd67cda7db2272a2b76 100644 (file)
@@ -49,6 +49,9 @@ int main(void)
   if (OK != (s=sys_getmachine(&machine)))
          panic("couldn't get machine info: %d", s);
 
+  if (OK != (s=sys_getkinfo(&kinfo)))
+         panic("couldn't get kernel kinfo: %d", s);
+
   /* Main loop - get work and do it, forever. */         
   while (TRUE) {              
 
@@ -272,8 +275,11 @@ static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
       fill_call_mask(calls, NR_SYS_CALLS,
           rp->r_priv.s_k_call_mask, KERNEL_CALL, TRUE);
 
-      /* Set the privilege structure. */
-      if(boot_image_priv->endpoint != RS_PROC_NR) {
+      /* Set the privilege structure. RS and VM are exceptions and are already
+       * running.
+       */
+      if(boot_image_priv->endpoint != RS_PROC_NR &&
+         boot_image_priv->endpoint != VM_PROC_NR) {
           if ((s = sys_privctl(ip->endpoint, SYS_PRIV_SET_SYS, &(rp->r_priv)))
               != OK) {
               panic("unable to set privilege structure: %d", s);
@@ -352,10 +358,11 @@ static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
       rp = &rproc[boot_image_priv - boot_image_priv_table];
       rpub = rp->r_pub;
 
-      /* RS is already running as we speak. */
-      if(boot_image_priv->endpoint == RS_PROC_NR) {
+      /* RS/VM are already running as we speak. */
+      if(boot_image_priv->endpoint == RS_PROC_NR ||
+         boot_image_priv->endpoint == VM_PROC_NR) {
           if ((s = init_service(rp, SEF_INIT_FRESH)) != OK) {
-              panic("unable to initialize RS: %d", s);
+              panic("unable to initialize %d: %d", boot_image_priv->endpoint, s);
           }
           continue;
       }
@@ -422,7 +429,7 @@ static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
       panic("couldn't set alarm: %d", s);
 
 #if USE_LIVEUPDATE
-  /* Now create a new RS instance with a private page table and let the current
+  /* Now create a new RS instance and let the current
    * instance live update into the replica. Clone RS' own slot first.
    */
   rp = rproc_ptr[_ENDPOINT_P(RS_PROC_NR)];
index ebf1c28fca47b00caeef823e85b9ea776613ac95..13ebb4b41cac01383c21494e12f08c73d93fadbc 100644 (file)
@@ -1018,7 +1018,8 @@ void terminate_service(struct rproc *rp)
   if (rp->r_flags & RS_EXITING) {
       /* If a core system service is exiting, we are in trouble. */
       if (rp->r_pub->sys_flags & SF_CORE_SRV && !shutting_down) {
-          panic("core system service died: %s", srv_to_string(rp));
+          printf("core system service died: %s\n", srv_to_string(rp));
+         _exit(1);
       }
 
       /* See if a late reply has to be sent. */
index 3e490777fff0b9bbc9cda7d5317fd93a984b30b6..d4f933acee45f50bfde722ad00fbb228078cb768 100644 (file)
@@ -216,6 +216,7 @@ int pm_exec(endpoint_t proc_e, vir_bytes path, size_t path_len,
 
   /* passed from exec() libc code */
   execi.userflags = user_exec_flags;
+  execi.args.stack_high = kinfo.user_sp;
   execi.args.stack_size = DEFAULT_STACK_LIMIT;
 
   okendpt(proc_e, &slot);
@@ -617,15 +618,15 @@ static int read_seg(struct exec_info *execi, off_t off, off_t seg_addr, size_t s
   if (off + seg_bytes > LONG_MAX) return(EIO);
   if ((unsigned long) vp->v_size < off+seg_bytes) return(EIO);
 
-       if ((r = req_readwrite(vp->v_fs_e, vp->v_inode_nr, cvul64(off), READING,
-                        execi->proc_e, (char*)seg_addr, seg_bytes,
-                        &new_pos, &cum_io)) != OK) {
-           printf("VFS: read_seg: req_readwrite failed (data)\n");
-           return(r);
-       }
+  if ((r = req_readwrite(vp->v_fs_e, vp->v_inode_nr, cvul64(off), READING,
+                execi->proc_e, (char*)seg_addr, seg_bytes,
+                &new_pos, &cum_io)) != OK) {
+    printf("VFS: read_seg: req_readwrite failed (data)\n");
+    return(r);
+  }
 
-       if (r == OK && cum_io != seg_bytes)
-               printf("VFS: read_seg segment has not been read properly\n");
+  if (r == OK && cum_io != seg_bytes)
+       printf("VFS: read_seg segment has not been read properly\n");
 
        return(r);
 }
index ac35c6d942555337d9a144bb10a4c3680ccdeeb4..dd1b6add1a1fc00bae55959c570de8e066216828 100644 (file)
@@ -52,4 +52,6 @@ extern int(*call_vec[]) (void);
 extern int(*pfs_call_vec[]) (void);
 extern char mode_map[];        /* mapping from O_ACCMODE mask to R_BIT/W_BIT flags */
 
+EXTERN struct kinfo kinfo;     /* kernel information */
+
 #endif
index 04858e8a3ff119e2b779875528eb08e3d526a54b..63d434a18ad05b8185a841b98d0b0b5457e6dc50 100644 (file)
@@ -79,6 +79,9 @@ int main(void)
 
   printf("Started VFS: %d worker thread(s)\n", NR_WTHREADS);
 
+  if (OK != (sys_getkinfo(&kinfo)))
+       panic("couldn't get kernel kinfo");
+
   /* This is the main loop that gets work, processes it, and sends replies. */
   while (TRUE) {
        yield_all();    /* let other threads run */
index cd4c3e7ba59f4b6293c38bcaedd7eb86b46565c4..8371e3498ff20a5796579351372c04916a4d823f 100644 (file)
@@ -115,7 +115,7 @@ int (*call_vec[])(void) = {
        no_sys,         /* 97 = unused */
        no_sys,         /* 98 = (sprofile) */
        no_sys,         /* 99 = (cprofile) */
-       no_sys,         /* 100 = (exec_newmem) */
+       no_sys,         /* 100 = (newexec) */
        no_sys,         /* 101 = (srv_fork) */
        no_sys,         /* 102 = (exec_restart) */
        no_sys,         /* 103 = unused */
index 993af5bc93dd78280bbcce0ceb8661709e483b25..cfe24c03898b68c876f1a2ed8431650f333d46b6 100644 (file)
@@ -2,12 +2,12 @@
 .include <bsd.own.mk>
 
 PROG=  vm
-SRCS=  main.c alloc.c utility.c exec.c exit.c fork.c break.c \
+SRCS=  main.c alloc.c utility.c exit.c fork.c break.c \
        signal.c mmap.c slaballoc.c region.c pagefaults.c addravl.c \
        physravl.c rs.c queryexit.c yieldedavl.c regionavl.c
 
 DPADD+=        ${LIBSYS}
-LDADD+=        -lsys
+LDADD+=        -lsys -lexec
 
 MAN=
 
index 68a5c11e676479d0ae1bd8973f7fd08fd18f6a57..8a71083087369a95f4a2c4ab75c847387c8faeb9 100644 (file)
@@ -358,7 +358,7 @@ struct memory *chunks;              /* list of free memory chunks */
 }
 
 #if SANITYCHECKS
-static void sanitycheck(void)
+void mem_sanitycheck(char *file, int line)
 {
        pagerange_t *p, *prevp = NULL;
        addr_iter iter;
@@ -368,8 +368,10 @@ static void sanitycheck(void)
                assert(p->size > 0);
                if(prevp) {
                        assert(prevp->addr < p->addr);
-                       assert(prevp->addr + p->addr < p->addr);
+                       assert(prevp->addr + prevp->size < p->addr);
                }
+               usedpages_add(p->addr * VM_PAGE_SIZE, p->size * VM_PAGE_SIZE);
+               prevp = p;
                addr_incr_iter(&iter);
        }
 }
@@ -383,9 +385,7 @@ void memstats(int *nodes, int *pages, int *largest)
        *nodes = 0;
        *pages = 0;
        *largest = 0;
-#if SANITYCHECKS
-       sanitycheck();
-#endif
+
        while((p=addr_get_iter(&iter))) {
                SLABSANE(p);
                (*nodes)++;
@@ -424,7 +424,6 @@ static phys_bytes alloc_pages(int pages, int memflags, phys_bytes *len)
 #endif
 
        memstats(&firstnodes, &firstpages, &largest);
-       sanitycheck();
        wantnodes = firstnodes;
        wantpages = firstpages - pages;
 #endif
@@ -513,7 +512,6 @@ static phys_bytes alloc_pages(int pages, int memflags, phys_bytes *len)
 
 #if SANITYCHECKS
        memstats(&finalnodes, &finalpages, &largest);
-       sanitycheck();
 
        assert(finalnodes == wantnodes);
        assert(finalpages == wantpages);
@@ -534,7 +532,6 @@ static void free_pages(phys_bytes pageno, int npages)
        int finalnodes, finalpages, largest;
 
        memstats(&firstnodes, &firstpages, &largest);
-       sanitycheck();
 
        wantnodes = firstnodes;
        wantpages = firstpages + npages;
@@ -561,7 +558,6 @@ static void free_pages(phys_bytes pageno, int npages)
                wantnodes = firstnodes;
                wantpages = firstpages + npages;
 
-               sanitycheck();
 #endif
                assert(npages > 0);
                USE(pr, pr->addr = pageno;
@@ -593,7 +589,6 @@ static void free_pages(phys_bytes pageno, int npages)
 
 #if SANITYCHECKS
        memstats(&finalnodes, &finalpages,  &largest);
-       sanitycheck();
 
        assert(finalnodes == wantnodes);
        assert(finalpages == wantpages);
@@ -817,7 +812,6 @@ void usedpages_reset(void)
  *===========================================================================*/
 int usedpages_add_f(phys_bytes addr, phys_bytes len, char *file, int line)
 {
-       pagerange_t *pr;
        u32_t pagestart, pages;
 
        if(!incheck)
@@ -836,7 +830,6 @@ int usedpages_add_f(phys_bytes addr, phys_bytes len, char *file, int line)
                assert(pagestart < MAXPAGES);
                thisaddr = pagestart * VM_PAGE_SIZE;
                if(GET_BIT(pagemap, pagestart)) {
-                       int i;
                        printf("%s:%d: usedpages_add: addr 0x%lx reused.\n",
                                file, line, thisaddr);
                        return EFAULT;
index 530df1a1fe628f0414f6355440be1e89af1cf343..f3d71c80b5046f8b978bb7eb75909dfb606fdc7a 100644 (file)
@@ -2,4 +2,4 @@
 
 #Arch-specific sources
 .PATH: ${.CURDIR}/arch/${MACHINE_ARCH}
-SRCS+= vm.c pagetable.c #util.S
+SRCS+= pagetable.c #util.S
diff --git a/servers/vm/arch/i386/arch_vmproc.h b/servers/vm/arch/i386/arch_vmproc.h
deleted file mode 100644 (file)
index 455e167..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-
-#include <minix/config.h>
-#include <minix/const.h>
-#include <minix/type.h>
-#include <minix/com.h>
-#include <minix/ipc.h>
-#include <minix/safecopies.h>
-#include <timers.h>
-
-struct vm_arch {
-       struct mem_map  vm_seg[NR_LOCAL_SEGS];  /* text, data, stack */
-
-       /* vm_data_top points to top of data address space, as visible
-        * from user-space, in bytes.
-        * for segments processes this is the same 
-        * as the top of vm_seg[S] segment. for paged processes this
-        * can be much higher (so more memory is available above the
-        * stack).
-        */
-       u32_t           vm_data_top;    /* virtual process space in bytes */
-};
index 6d84440cfb623646f1851200ba2647b7851f1a5f..d72de15bc06a37d9d979b79c95ee40aec2f19af4 100644 (file)
@@ -1,23 +1,12 @@
 #include <machine/vm.h>
 
 /* And what is the highest addressable piece of memory, when in paged
- * mode? Some data for kernel and stack are subtracted from this, the
- * final results stored in bytes in arch.vm_data_top.
+ * mode?
  */
-#define VM_DATATOP     0xFFFFF000
+#define VM_DATATOP     kernel_boot_info.user_end
+#define VM_STACKTOP    kernel_boot_info.user_sp
 
 #define SLAB_PAGESIZE  I386_PAGE_SIZE
 #define VM_PAGE_SIZE   I386_PAGE_SIZE
 
-/* Where do processes start in linear (i.e. page table) memory? */
-#define VM_PROCSTART   (I386_BIG_PAGE_SIZE*100)
-
 #define CLICKSPERPAGE (I386_PAGE_SIZE/CLICK_SIZE)
-
-/* Where is the kernel? */
-#define KERNEL_TEXT    CLICK2ABS(vmproc[VMP_SYSTEM].vm_arch.vm_seg[T].mem_phys)
-#define KERNEL_TEXT_LEN        CLICK2ABS(vmproc[VMP_SYSTEM].vm_arch.vm_seg[T].mem_len)
-#define KERNEL_DATA    CLICK2ABS(vmproc[VMP_SYSTEM].vm_arch.vm_seg[D].mem_phys)
-#define KERNEL_DATA_LEN        CLICK2ABS(vmproc[VMP_SYSTEM].vm_arch.vm_seg[D].mem_len \
-       + vmproc[VMP_SYSTEM].vm_arch.vm_seg[S].mem_len)
-
index 73f930ae64ac594db32b101cb79248c1f261a5fd..1fc4e2fc8487551b9c0df90a3e665fde274849db 100644 (file)
 
 #include "memory.h"
 
-/* Free PDE slots we tell kernel about */
-#define FREE_PDES      2
-static int first_free_pde = -1;
-
 /* PDE used to map in kernel, kernel physical address. */
-static int id_map_high_pde = -1, pagedir_pde = -1;
+static int pagedir_pde = -1;
 static u32_t global_bit = 0, pagedir_pde_val;
 
-static int proc_pde = 0;
+static multiboot_module_t *kern_mb_mod = NULL;
+static size_t kern_size = 0;
+static int kern_start_pde = -1;
 
 /* 4MB page size available in hardware? */
 static int bigpage_ok = 0;
@@ -56,7 +54,7 @@ struct vmproc *vmprocess = &vmproc[VM_PROC_NR];
  * circular dependency on allocating memory and writing it into VM's
  * page table.
  */
-#define SPAREPAGES 25
+#define SPAREPAGES 15
 int missing_spares = SPAREPAGES;
 static struct {
        void *page;
@@ -67,7 +65,7 @@ static struct {
 static struct {
        phys_bytes      phys_addr;      /* Physical addr. */
        phys_bytes      len;            /* Length in bytes. */
-       vir_bytes       lin_addr;       /* Offset in page table. */
+       vir_bytes       vir_addr;       /* Offset in page table. */
        int             flags;
 } kern_mappings[MAX_KERNMAPPINGS];
 int kernmappings = 0;
@@ -83,19 +81,13 @@ int kernmappings = 0;
 #error CLICK_SIZE must be page size.
 #endif
 
-/* Bytes of virtual address space one pde controls. */
-#define BYTESPERPDE (I386_VM_PT_ENTRIES * I386_PAGE_SIZE)
-
-/* Nevertheless, introduce these macros to make the code readable. */
-#define CLICK2PAGE(c) ((c) / CLICKSPERPAGE)
-
 /* Page table that contains pointers to all page directories. */
 phys_bytes page_directories_phys;
 u32_t *page_directories = NULL;
 
 #define STATIC_SPAREPAGES 10
 
-static char static_sparepages[I386_PAGE_SIZE*STATIC_SPAREPAGES + I386_PAGE_SIZE];
+static char static_sparepages[I386_PAGE_SIZE*STATIC_SPAREPAGES + I386_PAGE_SIZE] __aligned(I386_PAGE_SIZE);
 
 #if SANITYCHECKS
 /*===========================================================================*
@@ -104,7 +96,6 @@ static char static_sparepages[I386_PAGE_SIZE*STATIC_SPAREPAGES + I386_PAGE_SIZE]
 void pt_sanitycheck(pt_t *pt, char *file, int line)
 {
 /* Basic pt sanity check. */
-       int i;
        int slot;
 
        MYASSERT(pt);
@@ -121,37 +112,24 @@ void pt_sanitycheck(pt_t *pt, char *file, int line)
        }
 
        MYASSERT(usedpages_add(pt->pt_dir_phys, I386_PAGE_SIZE) == OK);
-
-       for(i = proc_pde; i < I386_VM_DIR_ENTRIES; i++) {
-               if(pt->pt_pt[i]) {
-                       int pte;
-                       MYASSERT(vm_addrok(pt->pt_pt[i], 1));
-                       if(!(pt->pt_dir[i] & I386_VM_PRESENT)) {
-                               printf("slot %d: pt->pt_pt[%d] = %p, but pt_dir entry 0x%lx\n",
-                                       slot, i, pt->pt_pt[i], pt->pt_dir[i]);
-                       }
-                       MYASSERT(pt->pt_dir[i] & I386_VM_PRESENT);
-                       MYASSERT(usedpages_add(I386_VM_PFA(pt->pt_dir[i]),
-                               I386_PAGE_SIZE) == OK);
-               } else {
-                       MYASSERT(!(pt->pt_dir[i] & I386_VM_PRESENT));
-               }
-       }
 }
 #endif
 
 /*===========================================================================*
  *                             findhole                                     *
  *===========================================================================*/
-static u32_t findhole(pt_t *pt, u32_t vmin, u32_t vmax)
+static u32_t findhole(void)
 {
-/* Find a space in the virtual address space of pageteble 'pt',
- * between page-aligned BYTE offsets vmin and vmax, to fit
- * a page in. Return byte offset.
- */
+/* Find a space in the virtual address space of VM. */
        u32_t curv;
        int pde = 0, try_restart;
        static u32_t lastv = 0;
+       pt_t *pt = &vmprocess->vm_pt;
+       extern char _end;       
+       vir_bytes vmin, vmax;
+
+       vmin = (vir_bytes) (&_end) & I386_VM_ADDR_MASK; /* marks end of VM BSS */
+       vmax = VM_STACKTOP;
 
        /* Input sanity check. */
        assert(vmin + I386_PAGE_SIZE >= vmin);
@@ -205,18 +183,20 @@ static u32_t findhole(pt_t *pt, u32_t vmin, u32_t vmax)
 static void vm_freepages(vir_bytes vir, vir_bytes phys, int pages, int reason)
 {
        assert(reason >= 0 && reason < VMP_CATEGORIES);
-       if(vir >= vmprocess->vm_stacktop) {
-               assert(!(vir % I386_PAGE_SIZE)); 
-               assert(!(phys % I386_PAGE_SIZE)); 
-               free_mem(ABS2CLICK(phys), pages);
-               if(pt_writemap(vmprocess, &vmprocess->vm_pt, arch_vir2map(vmprocess, vir),
-                       MAP_NONE, pages*I386_PAGE_SIZE, 0, WMF_OVERWRITE) != OK)
-                       panic("vm_freepages: pt_writemap failed");
-       } else {
-               printf("VM: vm_freepages not freeing VM heap pages (%d)\n",
-                       pages);
+       assert(!(vir % I386_PAGE_SIZE)); 
+       assert(!(phys % I386_PAGE_SIZE)); 
+       extern char _end;       
+
+       if(vir < (vir_bytes) &_end) {
+               printf("VM: not freeing static page\n");
+               return;
        }
 
+       free_mem(ABS2CLICK(phys), pages);
+       if(pt_writemap(vmprocess, &vmprocess->vm_pt, vir,
+               MAP_NONE, pages*I386_PAGE_SIZE, 0, WMF_OVERWRITE) != OK)
+               panic("vm_freepages: pt_writemap failed");
+
 #if SANITYCHECKS
        /* If SANITYCHECKS are on, flush tlb so accessing freed pages is
         * always trapped, also if not in tlb.
@@ -295,7 +275,7 @@ void *vm_allocpage(phys_bytes *phys, int reason)
        assert(level >= 1);
        assert(level <= 2);
 
-       if(level > 1 || !(vmprocess->vm_flags & VMF_HASPT) || !meminit_done) {
+       if(level > 1 || !meminit_done) {
                void *s;
                s=vm_getsparepage(phys);
                level--;
@@ -309,8 +289,7 @@ void *vm_allocpage(phys_bytes *phys, int reason)
        /* VM does have a pagetable, so get a page and map it in there.
         * Where in our virtual address space can we put it?
         */
-       loc = findhole(pt,  arch_vir2map(vmprocess, vmprocess->vm_stacktop),
-               vmprocess->vm_arch.vm_data_top);
+       loc = findhole();
        if(loc == NO_MEM) {
                level--;
                printf("VM: vm_allocpage: findhole failed\n");
@@ -344,7 +323,7 @@ void *vm_allocpage(phys_bytes *phys, int reason)
        level--;
 
        /* Return user-space-ready pointer to it. */
-       ret = (void *) arch_map2vir(vmprocess, loc);
+       ret = (void *) loc;
 
        return ret;
 }
@@ -355,13 +334,12 @@ void *vm_allocpage(phys_bytes *phys, int reason)
 void vm_pagelock(void *vir, int lockflag)
 {
 /* Mark a page allocated by vm_allocpage() unwritable, i.e. only for VM. */
-       vir_bytes m;
+       vir_bytes m = (vir_bytes) vir;
        int r;
        u32_t flags = I386_VM_PRESENT | I386_VM_USER;
        pt_t *pt;
 
        pt = &vmprocess->vm_pt;
-       m = arch_vir2map(vmprocess, (vir_bytes) vir);
 
        assert(!(m % I386_PAGE_SIZE));
 
@@ -386,15 +364,9 @@ void vm_pagelock(void *vir, int lockflag)
  *===========================================================================*/
 int vm_addrok(void *vir, int writeflag)
 {
-/* Mark a page allocated by vm_allocpage() unwritable, i.e. only for VM. */
        pt_t *pt = &vmprocess->vm_pt;
        int pde, pte;
-       vir_bytes v = arch_vir2map(vmprocess, (vir_bytes) vir);
-
-       /* No PT yet? Don't bother looking. */
-       if(!(vmprocess->vm_flags & VMF_HASPT)) {
-               return 1;
-       }
+       vir_bytes v = (vir_bytes) vir;
 
        pde = I386_VM_PDE(v);
        pte = I386_VM_PTE(v);
@@ -471,8 +443,8 @@ int pt_ptalloc_in_range(pt_t *pt, vir_bytes start, vir_bytes end,
 /* Allocate all the page tables in the range specified. */
        int pde, first_pde, last_pde;
 
-       first_pde = start ? I386_VM_PDE(start) : proc_pde;
-       last_pde = end ? I386_VM_PDE(end) : I386_VM_DIR_ENTRIES - 1;
+       first_pde = I386_VM_PDE(start);
+       last_pde = I386_VM_PDE(end-1);
        assert(first_pde >= 0);
        assert(last_pde < I386_VM_DIR_ENTRIES);
 
@@ -498,6 +470,7 @@ int pt_ptalloc_in_range(pt_t *pt, vir_bytes start, vir_bytes end,
                                return r;
                        }
                }
+               assert(pt->pt_dir[pde]);
                assert(pt->pt_dir[pde] & I386_VM_PRESENT);
        }
 
@@ -549,7 +522,7 @@ int pt_map_in_range(struct vmproc *src_vmp, struct vmproc *dst_vmp,
        end = end ? end : VM_DATATOP;
        assert(start % I386_PAGE_SIZE == 0);
        assert(end % I386_PAGE_SIZE == 0);
-       assert(I386_VM_PDE(start) >= proc_pde && start <= end);
+       assert(I386_VM_PDE(start) >= 0 && start <= end);
        assert(I386_VM_PDE(end) < I386_VM_DIR_ENTRIES);
 
 #if LU_DEBUG
@@ -596,7 +569,6 @@ int pt_ptmap(struct vmproc *src_vmp, struct vmproc *dst_vmp)
        vir_bytes viraddr;
        pt_t *pt;
 
-       assert(src_vmp->vm_stacktop == dst_vmp->vm_stacktop);
        pt = &src_vmp->vm_pt;
 
 #if LU_DEBUG
@@ -605,8 +577,7 @@ int pt_ptmap(struct vmproc *src_vmp, struct vmproc *dst_vmp)
 #endif
 
        /* Transfer mapping to the page directory. */
-       assert((vir_bytes) pt->pt_dir >= src_vmp->vm_stacktop);
-       viraddr = arch_vir2map(src_vmp, (vir_bytes) pt->pt_dir);
+       viraddr = (vir_bytes) pt->pt_dir;
        physaddr = pt->pt_dir_phys & I386_VM_ADDR_MASK;
        if((r=pt_writemap(dst_vmp, &dst_vmp->vm_pt, viraddr, physaddr, I386_PAGE_SIZE,
                I386_VM_PRESENT | I386_VM_USER | I386_VM_WRITE,
@@ -619,14 +590,13 @@ int pt_ptmap(struct vmproc *src_vmp, struct vmproc *dst_vmp)
 #endif
 
        /* Scan all non-reserved page-directory entries. */
-       for(pde=proc_pde; pde < I386_VM_DIR_ENTRIES; pde++) {
+       for(pde=0; pde < I386_VM_DIR_ENTRIES; pde++) {
                if(!(pt->pt_dir[pde] & I386_VM_PRESENT)) {
                        continue;
                }
 
                /* Transfer mapping to the page table. */
-               assert((vir_bytes) pt->pt_pt[pde] >= src_vmp->vm_stacktop);
-               viraddr = arch_vir2map(src_vmp, (vir_bytes) pt->pt_pt[pde]);
+               viraddr = (vir_bytes) pt->pt_pt[pde];
                physaddr = pt->pt_dir[pde] & I386_VM_ADDR_MASK;
                if((r=pt_writemap(dst_vmp, &dst_vmp->vm_pt, viraddr, physaddr, I386_PAGE_SIZE,
                        I386_VM_PRESENT | I386_VM_USER | I386_VM_WRITE,
@@ -634,24 +604,18 @@ int pt_ptmap(struct vmproc *src_vmp, struct vmproc *dst_vmp)
                        return r;
                }
        }
-#if LU_DEBUG
-       printf("VM: pt_ptmap: transferred mappings to page tables, pde range %d - %d\n",
-               proc_pde, I386_VM_DIR_ENTRIES - 1);
-#endif
 
        return OK;
 }
 
 void pt_clearmapcache(void)
 {
-       int f;
        /* Make sure kernel will invalidate tlb when using current
         * pagetable (i.e. vm's) to make new mappings before new cr3
         * is loaded.
         */
-       for(f = first_free_pde; f < first_free_pde+FREE_PDES; f++) {
-               vmprocess->vm_pt.pt_dir[f] = 0;
-       }
+       if(sys_vmctl(SELF, VMCTL_CLEARMAPCACHE, 0) != OK)
+               panic("VMCTL_CLEARMAPCACHE failed");
 }
 
 /*===========================================================================*
@@ -706,6 +670,7 @@ int pt_writemap(struct vmproc * vmp,
         */
        ret = pt_ptalloc_in_range(pt, v, v + I386_PAGE_SIZE*pages, flags, verify);
        if(ret != OK) {
+               printf("VM: writemap: pt_ptalloc_in_range failed\n");
                goto resume_exit;
        }
 
@@ -715,6 +680,9 @@ int pt_writemap(struct vmproc * vmp,
                int pde = I386_VM_PDE(v);
                int pte = I386_VM_PTE(v);
 
+               if(!v) { printf("VM: warning: making zero page for %d\n",
+                       vmp->vm_endpoint); }
+
                assert(!(v % I386_PAGE_SIZE));
                assert(pte >= 0 && pte < I386_VM_PT_ENTRIES);
                assert(pde >= 0 && pde < I386_VM_DIR_ENTRIES);
@@ -722,10 +690,12 @@ int pt_writemap(struct vmproc * vmp,
                /* Page table has to be there. */
                assert(pt->pt_dir[pde] & I386_VM_PRESENT);
 
+               /* We do not expect it to be a bigpage. */
+               assert(!(pt->pt_dir[pde] & I386_VM_BIGPAGE));
+
                /* Make sure page directory entry for this page table
                 * is marked present and page table entry is available.
                 */
-               assert((pt->pt_dir[pde] & I386_VM_PRESENT));
                assert(pt->pt_pt[pde]);
 
 #if SANITYCHECKS
@@ -770,9 +740,6 @@ int pt_writemap(struct vmproc * vmp,
                        }
                } else {
                        /* Write pagetable entry. */
-#if SANITYCHECKS
-                       assert(vm_addrok(pt->pt_pt[pde], 1));
-#endif
                        pt->pt_pt[pde][pte] = entry;
                }
 
@@ -874,53 +841,62 @@ int pt_new(pt_t *pt)
        return OK;
 }
 
+static int freepde(void)
+{
+       int p = kernel_boot_info.freepde_start++;
+       assert(kernel_boot_info.freepde_start < I386_VM_DIR_ENTRIES);
+       return p;
+}
+
 /*===========================================================================*
  *                              pt_init                                      *
  *===========================================================================*/
-void pt_init(phys_bytes usedlimit)
+void pt_init(void)
 {
-/* By default, the kernel gives us a data segment with pre-allocated
- * memory that then can't grow. We want to be able to allocate memory
- * dynamically, however. So here we copy the part of the page table
- * that's ours, so we get a private page table. Then we increase the
- * hardware segment size so we can allocate memory above our stack.
- */
         pt_t *newpt;
-        int s, r;
-        vir_bytes v;
-        phys_bytes lo, hi; 
-        vir_bytes extra_clicks;
-        u32_t moveup = 0;
+        int s, r, p;
        int global_bit_ok = 0;
-       int free_pde;
-       struct vm_ep_data ep_data;
        vir_bytes sparepages_mem;
-       phys_bytes sparepages_ph;
-       vir_bytes ptr;
-       int f = 0;
-
-        /* Shorthand. */
-        newpt = &vmprocess->vm_pt;
+       static u32_t currentpagedir[I386_VM_DIR_ENTRIES];
+       int m = kernel_boot_info.kern_mod;
+       u32_t mycr3;
+
+       /* Find what the physical location of the kernel is. */
+       assert(m >= 0);
+       assert(m < kernel_boot_info.mods_with_kernel);
+       assert(kernel_boot_info.mods_with_kernel < MULTIBOOT_MAX_MODS);
+       kern_mb_mod = &kernel_boot_info.module_list[m];
+       kern_size = kern_mb_mod->mod_end - kern_mb_mod->mod_start;
+       assert(!(kern_mb_mod->mod_start % I386_BIG_PAGE_SIZE));
+       assert(!(kernel_boot_info.vir_kern_start % I386_BIG_PAGE_SIZE));
+       kern_start_pde = kernel_boot_info.vir_kern_start / I386_BIG_PAGE_SIZE;
 
         /* Get ourselves spare pages. */
-        ptr = (vir_bytes) static_sparepages;
-        ptr += I386_PAGE_SIZE - (ptr % I386_PAGE_SIZE);
-        if(!(sparepages_mem = ptr))
-               panic("pt_init: aalloc for spare failed");
-        if((r=sys_umap(SELF, VM_D, (vir_bytes) sparepages_mem,
-                I386_PAGE_SIZE*SPAREPAGES, &sparepages_ph)) != OK)
-                panic("pt_init: sys_umap failed: %d", r);
+        sparepages_mem = (vir_bytes) static_sparepages;
+       assert(!(sparepages_mem % I386_PAGE_SIZE));
+
+       /* Spare pages are used to allocate memory before VM has its own page
+        * table that things (i.e. arbitrary physical memory) can be mapped into.
+        * We get it by pre-allocating it in our bss (allocated and mapped in by
+        * the kernel) in static_sparepages. We also need the physical addresses
+        * though; we look them up now so they are ready for use.
+        */
 
         missing_spares = 0;
         assert(STATIC_SPAREPAGES < SPAREPAGES);
         for(s = 0; s < SPAREPAGES; s++) {
+               vir_bytes v = (sparepages_mem + s*I386_PAGE_SIZE);;
+               phys_bytes ph;
+               if((r=sys_umap(SELF, VM_D, (vir_bytes) v,
+                       I386_PAGE_SIZE*SPAREPAGES, &ph)) != OK)
+                               panic("pt_init: sys_umap failed: %d", r);
                if(s >= STATIC_SPAREPAGES) {
                        sparepages[s].page = NULL;
                        missing_spares++;
                        continue;
                }
-               sparepages[s].page = (void *) (sparepages_mem + s*I386_PAGE_SIZE);
-               sparepages[s].phys = sparepages_ph + s*I386_PAGE_SIZE;
+               sparepages[s].page = (void *) v;
+               sparepages[s].phys = ph;
         }
 
        /* global bit and 4MB pages available? */
@@ -931,51 +907,6 @@ void pt_init(phys_bytes usedlimit)
        if(global_bit_ok)
                global_bit = I386_VM_GLOBAL;
 
-       /* The kernel and boot time processes need an identity mapping.
-        * We use full PDE's for this without separate page tables.
-        * Figure out which pde we can start using for other purposes.
-        */
-       id_map_high_pde = usedlimit / I386_BIG_PAGE_SIZE;
-
-       /* We have to make mappings up till here. */
-       free_pde = id_map_high_pde+1;
-
-        /* Initial (current) range of our virtual address space. */
-        lo = CLICK2ABS(vmprocess->vm_arch.vm_seg[T].mem_phys);
-        hi = CLICK2ABS(vmprocess->vm_arch.vm_seg[S].mem_phys +
-                vmprocess->vm_arch.vm_seg[S].mem_len);
-                  
-        assert(!(lo % I386_PAGE_SIZE)); 
-        assert(!(hi % I386_PAGE_SIZE));
-        if(lo < VM_PROCSTART) {
-                moveup = VM_PROCSTART - lo;
-                assert(!(VM_PROCSTART % I386_PAGE_SIZE));
-                assert(!(lo % I386_PAGE_SIZE));
-                assert(!(moveup % I386_PAGE_SIZE));
-        }
-        
-        /* Make new page table for ourselves, partly copied
-         * from the current one.
-         */     
-        if(pt_new(newpt) != OK)
-                panic("pt_init: pt_new failed"); 
-
-        /* Set up mappings for VM process. */
-        for(v = lo; v < hi; v += I386_PAGE_SIZE)  {
-                /* We have to write the new position in the PT,
-                 * so we can move our segments.
-                 */ 
-                if(pt_writemap(vmprocess, newpt, v+moveup, v, I386_PAGE_SIZE,
-                        I386_VM_PRESENT|I386_VM_WRITE|I386_VM_USER, 0) != OK)
-                        panic("pt_init: pt_writemap failed");
-        }
-       
-        /* Move segments up too. */
-        vmprocess->vm_arch.vm_seg[T].mem_phys += ABS2CLICK(moveup);
-        vmprocess->vm_arch.vm_seg[D].mem_phys += ABS2CLICK(moveup);
-        vmprocess->vm_arch.vm_seg[S].mem_phys += ABS2CLICK(moveup);
-       
        /* Allocate us a page table in which to remember page directory
         * pointers.
         */
@@ -984,28 +915,6 @@ void pt_init(phys_bytes usedlimit)
                 panic("no virt addr for vm mappings");
 
        memset(page_directories, 0, I386_PAGE_SIZE);
-       
-        /* Increase our hardware data segment to create virtual address
-         * space above our stack. We want to increase it to VM_DATATOP,
-         * like regular processes have.
-         */
-        extra_clicks = ABS2CLICK(VM_DATATOP - hi);
-        vmprocess->vm_arch.vm_seg[S].mem_len += extra_clicks;
-       
-        /* We pretend to the kernel we have a huge stack segment to
-         * increase our data segment.
-         */
-        vmprocess->vm_arch.vm_data_top =
-                (vmprocess->vm_arch.vm_seg[S].mem_vir +
-                vmprocess->vm_arch.vm_seg[S].mem_len) << CLICK_SHIFT;
-       
-        /* Where our free virtual address space starts.
-         * This is only a hint to the VM system.
-         */
-        newpt->pt_virtop = 0;
-
-        /* Let other functions know VM now has a private page table. */
-        vmprocess->vm_flags |= VMF_HASPT;
 
        /* Now reserve another pde for kernel's own mappings. */
        {
@@ -1014,7 +923,7 @@ void pt_init(phys_bytes usedlimit)
                int flags, index = 0;
                u32_t offset = 0;
 
-               kernmap_pde = free_pde++;
+               kernmap_pde = freepde();
                offset = kernmap_pde * I386_BIG_PAGE_SIZE;
 
                while(sys_vmctl_get_mapping(index, &addr, &len,
@@ -1025,17 +934,16 @@ void pt_init(phys_bytes usedlimit)
                        kern_mappings[index].phys_addr = addr;
                        kern_mappings[index].len = len;
                        kern_mappings[index].flags = flags;
-                       kern_mappings[index].lin_addr = offset;
+                       kern_mappings[index].vir_addr = offset;
                        kern_mappings[index].flags =
-                               I386_VM_PRESENT | I386_VM_USER | I386_VM_WRITE |
-                               global_bit;
+                               I386_VM_PRESENT | I386_VM_USER | I386_VM_WRITE;
                        if(flags & VMMF_UNCACHED)
                                kern_mappings[index].flags |= PTF_NOCACHE;
                        if(addr % I386_PAGE_SIZE)
                                panic("VM: addr unaligned: %d", addr);
                        if(len % I386_PAGE_SIZE)
                                panic("VM: len unaligned: %d", len);
-                       vir = arch_map2vir(&vmproc[VMP_SYSTEM], offset);
+                       vir = offset;
                        if(sys_vmctl_reply_mapping(index, vir) != OK)
                                panic("VM: reply failed");
                        offset += len;
@@ -1045,131 +953,68 @@ void pt_init(phys_bytes usedlimit)
        }
 
        /* Find a PDE below processes available for mapping in the
-        * page directories (readonly).
+        * page directories.
         */
-       pagedir_pde = free_pde++;
+       pagedir_pde = freepde();
        pagedir_pde_val = (page_directories_phys & I386_VM_ADDR_MASK) |
-                       I386_VM_PRESENT | I386_VM_USER | I386_VM_WRITE;
-
-       /* Tell kernel about free pde's. */
-       first_free_pde = free_pde;
-       while(free_pde*I386_BIG_PAGE_SIZE < VM_PROCSTART && f < FREE_PDES) {
-               if((r=sys_vmctl(SELF, VMCTL_I386_FREEPDE, free_pde++)) != OK) {
-                       panic("VMCTL_I386_FREEPDE failed: %d", r);
-               }
-               f++;
-       }
+                       I386_VM_PRESENT | I386_VM_WRITE;
+
+       /* Allright. Now. We have to make our own page directory and page tables,
+        * that the kernel has already set up, accessible to us. It's easier to
+        * understand if we just copy all the required pages (i.e. page directory
+        * and page tables), and set up the pointers as if VM had done it itself.
+        *
+        * This allocation will happen without using any page table, and just
+        * uses spare pages.
+        */
+        newpt = &vmprocess->vm_pt;
+       if(pt_new(newpt) != OK)
+               panic("vm pt_new failed");
+
+       /* Get our current pagedir so we can see it. */
+       if(sys_vmctl_get_cr3_i386(SELF, &mycr3) != OK)
+               panic("VM: sys_vmctl_get_cr3_i386 failed");
+       if(sys_vircopy(NONE, mycr3, SELF, 
+               (vir_bytes) currentpagedir, I386_PAGE_SIZE) != OK)
+               panic("VM: sys_vircopy failed");
+
+       /* We have mapped in kernel ourselves; now copy mappings for VM
+        * that kernel made, including allocations for BSS. Skip identity
+        * mapping bits; just map in VM.
+        */
+       for(p = 0; p < I386_VM_DIR_ENTRIES; p++) {
+               u32_t entry = currentpagedir[p];
+               phys_bytes ptaddr_kern, ptaddr_us;
 
-       /* first pde in use by process. */
-       proc_pde = free_pde;
+               /* BIGPAGEs are kernel mapping (do ourselves) or boot
+                * identity mapping (don't want).
+                */
+               if(!(entry & I386_VM_PRESENT)) continue;
+               if((entry & I386_VM_BIGPAGE)) continue;
 
-        /* Give our process the new, copied, private page table. */
-       pt_mapkernel(newpt);    /* didn't know about vm_dir pages earlier */
-        pt_bind(newpt, vmprocess);
-       
-       /* new segment limit for the kernel after paging is enabled */
-       ep_data.data_seg_limit = free_pde*I386_BIG_PAGE_SIZE;
-       /* the memory map which must be installed after paging is enabled */
-       ep_data.mem_map = vmprocess->vm_arch.vm_seg;
+               if(pt_ptalloc(newpt, p, 0) != OK)
+                       panic("pt_ptalloc failed");
+               assert(newpt->pt_dir[p] & I386_VM_PRESENT);
 
-       /* Now actually enable paging. */
-       if(sys_vmctl_enable_paging(&ep_data) != OK)
-               panic("pt_init: enable paging failed");
+               ptaddr_kern = entry & I386_VM_ADDR_MASK;
+               ptaddr_us = newpt->pt_dir[p] & I386_VM_ADDR_MASK;
 
-        /* Back to reality - this is where the stack actually is. */
-        vmprocess->vm_arch.vm_seg[S].mem_len -= extra_clicks;
+               /* Copy kernel-initialized pagetable contents into our
+                * normally accessible pagetable.
+                */
+                if(sys_abscopy(ptaddr_kern, ptaddr_us, I386_PAGE_SIZE) != OK)
+                       panic("pt_init: abscopy failed");
+       }
 
-        /* Pretend VM stack top is the same as any regular process, not to
-         * have discrepancies with new VM instances later on.
-         */
-        vmprocess->vm_stacktop = VM_STACKTOP;
+       /* Inform kernel vm has a newly built page table. */
+       assert(vmproc[VM_PROC_NR].vm_endpoint == VM_PROC_NR);
+       pt_mapkernel(newpt);
+       pt_bind(newpt, &vmproc[VM_PROC_NR]);
 
         /* All OK. */
         return;
 }
 
-/*===========================================================================*
- *                             pt_init_mem                                   *
- *===========================================================================*/
-void pt_init_mem()
-{
-/* Architecture-specific memory initialization. Make sure all the pages
- * shared with the kernel and VM's page tables are mapped above the stack,
- * so that we can easily transfer existing mappings for new VM instances.
- */
-        phys_bytes new_page_directories_phys;
-       u32_t *new_page_directories;
-        phys_bytes new_pt_dir_phys;
-       u32_t *new_pt_dir;
-        phys_bytes new_pt_phys;
-       u32_t *new_pt; 
-        pt_t *vmpt;
-        int i;
-
-        vmpt = &vmprocess->vm_pt;
-
-        /* We should be running this when VM has been assigned a page
-         * table and memory initialization has already been performed.
-         */
-        assert(vmprocess->vm_flags & VMF_HASPT);
-        assert(meminit_done);
-
-        /* Throw away static spare pages. */
-       vm_checkspares();
-       for(i = 0; i < SPAREPAGES; i++) {
-               if(sparepages[i].page && (vir_bytes) sparepages[i].page
-                       < vmprocess->vm_stacktop) {
-                       sparepages[i].page = NULL;
-                       missing_spares++;
-               }
-       }
-       vm_checkspares();
-
-        /* Rellocate page for page directories pointers. */
-       if(!(new_page_directories = vm_allocpage(&new_page_directories_phys,
-               VMP_PAGETABLE)))
-                panic("unable to reallocated page for page dir ptrs");
-       assert((vir_bytes) new_page_directories >= vmprocess->vm_stacktop);
-       memcpy(new_page_directories, page_directories, I386_PAGE_SIZE);
-       page_directories = new_page_directories;
-       pagedir_pde_val = (new_page_directories_phys & I386_VM_ADDR_MASK) |
-                       (pagedir_pde_val & ~I386_VM_ADDR_MASK);
-
-       /* Remap in kernel. */
-       pt_mapkernel(vmpt);
-
-       /* Reallocate VM's page directory. */
-       if((vir_bytes) vmpt->pt_dir < vmprocess->vm_stacktop) {
-               if(!(new_pt_dir= vm_allocpage(&new_pt_dir_phys, VMP_PAGEDIR))) {
-                       panic("unable to reallocate VM's page directory");
-               }
-               assert((vir_bytes) new_pt_dir >= vmprocess->vm_stacktop);
-               memcpy(new_pt_dir, vmpt->pt_dir, I386_PAGE_SIZE);
-               vmpt->pt_dir = new_pt_dir;
-               vmpt->pt_dir_phys = new_pt_dir_phys;
-               pt_bind(vmpt, vmprocess);
-       }
-
-       /* Reallocate VM's page tables. */
-       for(i = proc_pde; i < I386_VM_DIR_ENTRIES; i++) {
-               if(!(vmpt->pt_dir[i] & I386_VM_PRESENT)) {
-                       continue;
-               }
-               assert(vmpt->pt_pt[i]);
-               if((vir_bytes) vmpt->pt_pt[i] >= vmprocess->vm_stacktop) {
-                       continue;
-               }
-               vm_checkspares();
-               if(!(new_pt = vm_allocpage(&new_pt_phys, VMP_PAGETABLE)))
-                       panic("unable to reallocate VM's page table");
-               assert((vir_bytes) new_pt >= vmprocess->vm_stacktop);
-               memcpy(new_pt, vmpt->pt_pt[i], I386_PAGE_SIZE);
-               vmpt->pt_pt[i] = new_pt;
-               vmpt->pt_dir[i] = (new_pt_phys & I386_VM_ADDR_MASK) |
-                       (vmpt->pt_dir[i] & ~I386_VM_ADDR_MASK);
-       }
-}
-
 /*===========================================================================*
  *                             pt_bind                                      *
  *===========================================================================*/
@@ -1200,8 +1045,7 @@ int pt_bind(pt_t *pt, struct vmproc *who)
        /* This is where the PDE's will be visible to the kernel
         * in its address space.
         */
-       pdes = (void *) arch_map2vir(&vmproc[VMP_SYSTEM],
-               pagedir_pde*I386_BIG_PAGE_SIZE + 
+       pdes = (void *) (pagedir_pde*I386_BIG_PAGE_SIZE + 
                        slot * I386_PAGE_SIZE);
 
 #if 0
@@ -1209,9 +1053,7 @@ int pt_bind(pt_t *pt, struct vmproc *who)
                slot, who->vm_endpoint, page_directories[slot], pdes);
 #endif
        /* Tell kernel about new page table root. */
-       return sys_vmctl_set_addrspace(who->vm_endpoint,
-               pt ? pt->pt_dir_phys : 0,
-               pt ? pdes : 0);
+       return sys_vmctl_set_addrspace(who->vm_endpoint, pt->pt_dir_phys, pdes);
 }
 
 /*===========================================================================*
@@ -1236,32 +1078,34 @@ void pt_free(pt_t *pt)
 int pt_mapkernel(pt_t *pt)
 {
        int i;
+       int kern_pde = kern_start_pde;
+       phys_bytes addr, mapped = 0;
 
         /* Any i386 page table needs to map in the kernel address space. */
-        assert(vmproc[VMP_SYSTEM].vm_flags & VMF_INUSE);
-
-       if(bigpage_ok) {
-               int pde;
-               for(pde = 0; pde <= id_map_high_pde; pde++) {
-                       phys_bytes addr;
-                       addr = pde * I386_BIG_PAGE_SIZE;
-                       assert((addr & I386_VM_ADDR_MASK) == addr);
-                       pt->pt_dir[pde] = addr | I386_VM_PRESENT |
-                               I386_VM_BIGPAGE | I386_VM_USER |
-                               I386_VM_WRITE | global_bit;
-               }
-       } else {
-               panic("VM: pt_mapkernel: no bigpage");
+       assert(bigpage_ok);
+       assert(pagedir_pde >= 0);
+       assert(kern_pde >= 0);
+
+       /* pt_init() has made sure this is ok. */
+       addr = kern_mb_mod->mod_start;
+
+       /* Actually mapping in kernel */
+       while(mapped < kern_size) {
+               pt->pt_dir[kern_pde] = addr | I386_VM_PRESENT |
+                       I386_VM_BIGPAGE | I386_VM_WRITE | global_bit;
+               kern_pde++;
+               mapped += I386_BIG_PAGE_SIZE;
+               addr += I386_BIG_PAGE_SIZE;
        }
 
-       if(pagedir_pde >= 0) {
-               /* Kernel also wants to know about all page directories. */
-               pt->pt_dir[pagedir_pde] = pagedir_pde_val;
-       }
+       /* Kernel also wants to know about all page directories. */
+       assert(pagedir_pde > kern_pde);
+       pt->pt_dir[pagedir_pde] = pagedir_pde_val;
 
+       /* Kernel also wants various mappings of its own. */
        for(i = 0; i < kernmappings; i++) {
                if(pt_writemap(NULL, pt,
-                       kern_mappings[i].lin_addr,
+                       kern_mappings[i].vir_addr,
                        kern_mappings[i].phys_addr,
                        kern_mappings[i].len,
                        kern_mappings[i].flags, 0) != OK) {
diff --git a/servers/vm/arch/i386/vm.c b/servers/vm/arch/i386/vm.c
deleted file mode 100644 (file)
index 1d206f6..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-
-#define _SYSTEM 1
-
-#include <minix/callnr.h>
-#include <minix/com.h>
-#include <minix/config.h>
-#include <minix/const.h>
-#include <minix/ds.h>
-#include <minix/endpoint.h>
-#include <minix/keymap.h>
-#include <minix/minlib.h>
-#include <minix/type.h>
-#include <minix/ipc.h>
-#include <minix/sysutil.h>
-#include <minix/syslib.h>
-#include <minix/bitmap.h>
-
-#include <sys/mman.h>
-
-#include <errno.h>
-#include <assert.h>
-#include <env.h>
-
-#include "proto.h"
-#include "vm.h"
-#include "util.h"
-
-#include "memory.h"
-
-/*===========================================================================*
- *                             arch_map2vir                                 *
- *===========================================================================*/
-vir_bytes arch_map2vir(struct vmproc *vmp, vir_bytes addr)
-{
-       vir_bytes textstart = CLICK2ABS(vmp->vm_arch.vm_seg[T].mem_phys);
-       vir_bytes datastart = CLICK2ABS(vmp->vm_arch.vm_seg[D].mem_phys);
-       vir_bytes datasegbase = CLICK2ABS(vmp->vm_arch.vm_seg[D].mem_phys -
-                                         vmp->vm_arch.vm_seg[D].mem_vir);
-
-       /* Could be a text address. */
-       assert(datastart <= addr || textstart <= addr);
-
-       return addr - datasegbase;
-}
-
-/*===========================================================================*
- *                             arch_map2str                                 *
- *===========================================================================*/
-char *arch_map2str(struct vmproc *vmp, vir_bytes addr)
-{
-       static char bufstr[100];
-       vir_bytes textstart = CLICK2ABS(vmp->vm_arch.vm_seg[T].mem_phys);
-       vir_bytes datastart = CLICK2ABS(vmp->vm_arch.vm_seg[D].mem_phys);
-       vir_bytes textsegbase = CLICK2ABS(vmp->vm_arch.vm_seg[T].mem_phys -
-                                         vmp->vm_arch.vm_seg[T].mem_vir);
-       vir_bytes datasegbase = CLICK2ABS(vmp->vm_arch.vm_seg[D].mem_phys -
-                                         vmp->vm_arch.vm_seg[D].mem_vir);
-
-       if(addr < textstart) {
-               sprintf(bufstr, "<lin:0x%lx>", addr);
-       } else if(addr < datastart) {
-               sprintf(bufstr, "0x%lx (codeseg)", addr - textsegbase);
-       } else {
-               sprintf(bufstr, "0x%lx (dataseg)", addr - datasegbase);
-       }
-
-       return bufstr;
-}
-
-/*===========================================================================*
- *                             arch_map2info                                *
- *===========================================================================*/
-vir_bytes arch_map2info(struct vmproc *vmp, vir_bytes addr, int *seg,
-       int *prot)
-{
-       vir_bytes textstart = CLICK2ABS(vmp->vm_arch.vm_seg[T].mem_phys);
-       vir_bytes textend = textstart +
-               CLICK2ABS(vmp->vm_arch.vm_seg[T].mem_len);
-       vir_bytes datastart = CLICK2ABS(vmp->vm_arch.vm_seg[D].mem_phys);
-       vir_bytes textsegbase = CLICK2ABS(vmp->vm_arch.vm_seg[T].mem_phys -
-                                         vmp->vm_arch.vm_seg[T].mem_vir);
-       vir_bytes datasegbase = CLICK2ABS(vmp->vm_arch.vm_seg[D].mem_phys -
-                                         vmp->vm_arch.vm_seg[D].mem_vir);
-
-       /* The protection to be returned here is that of the segment. */
-       if(addr < textstart) {
-               *seg = D;
-               *prot = PROT_READ | PROT_WRITE | PROT_EXEC;
-               return addr;
-       } else if(addr < datastart) {
-               *seg = T;
-               *prot = PROT_READ | PROT_EXEC;
-               return addr - textsegbase;
-       } else {
-               *seg = D;
-               if (textstart == textend)       /* common I&D? */
-                       *prot = PROT_READ | PROT_WRITE | PROT_EXEC;
-               else
-                       *prot = PROT_READ | PROT_WRITE;
-               return addr - datasegbase;
-       }
-}
-
-/*===========================================================================*
- *                             arch_addrok                                  *
- *===========================================================================*/
-vir_bytes arch_addrok(struct vmproc *vmp, vir_bytes addr)
-{
-       vir_bytes textstart = CLICK2ABS(vmp->vm_arch.vm_seg[T].mem_phys);
-       vir_bytes textend = CLICK2ABS(vmp->vm_arch.vm_seg[T].mem_phys +
-               vmp->vm_arch.vm_seg[T].mem_phys);
-       vir_bytes datastart = CLICK2ABS(vmp->vm_arch.vm_seg[D].mem_phys);
-
-       if(addr >= textstart && addr < textstart+textend)
-               return 1;
-
-       if(addr >= datastart && addr < VM_DATATOP)
-               return 1;
-
-       return 0;
-}
-
-/*===========================================================================*
- *                             arch_vir2map                                 *
- *===========================================================================*/
-vir_bytes arch_vir2map(struct vmproc *vmp, vir_bytes addr)
-{
-       vir_bytes datasegbase = CLICK2ABS(vmp->vm_arch.vm_seg[D].mem_phys -
-                                         vmp->vm_arch.vm_seg[D].mem_vir);
-
-       return addr + datasegbase;
-}
-
-/*===========================================================================*
- *                             arch_vir2map_text                            *
- *===========================================================================*/
-vir_bytes arch_vir2map_text(struct vmproc *vmp, vir_bytes addr)
-{
-       vir_bytes textsegbase = CLICK2ABS(vmp->vm_arch.vm_seg[T].mem_phys -
-                                         vmp->vm_arch.vm_seg[T].mem_vir);
-
-       return addr + textsegbase;
-}
index bc4a0687a543f23adde466a7c769ed1534264d11..b8ea5f0beda2c6d4b6c36e610ed6a20a51e0069e 100644 (file)
@@ -59,107 +59,6 @@ int do_brk(message *msg)
        return real_brk(&vmproc[proc], (vir_bytes) msg->VMB_ADDR);
 }
 
-/*===========================================================================*
- *                             adjust                                       *
- *===========================================================================*/
-int adjust(rmp, data_clicks, sp)
-struct vmproc *rmp;            /* whose memory is being adjusted? */
-vir_clicks data_clicks;                /* how big is data segment to become? */
-vir_bytes sp;                  /* new value of sp */
-{
-/* See if data and stack segments can coexist, adjusting them if need be.
- * Memory is never allocated or freed.  Instead it is added or removed from the
- * gap between data segment and stack segment.  If the gap size becomes
- * negative, the adjustment of data or stack fails and ENOMEM is returned.
- */
-
-  register struct mem_map *mem_sp, *mem_dp;
-  vir_clicks sp_click, gap_base, sp_lower, old_clicks;
-  int changed, r, sp_in_dp;
-  long base_of_stack, sp_delta;        /* longs avoid certain problems */
-
-  mem_dp = &rmp->vm_arch.vm_seg[D];    /* pointer to data segment map */
-  mem_sp = &rmp->vm_arch.vm_seg[S];    /* pointer to stack segment map */
-  changed = 0;                 /* set when either segment changed */
-
-  /* See if stack size has gone negative (i.e., sp too close to 0xFFFF...) */
-  base_of_stack = (long) mem_sp->mem_vir + (long) mem_sp->mem_len;
-  sp_click = sp >> CLICK_SHIFT;        /* click containing sp */
-  if (sp_click >= base_of_stack)
-  {
-       return(ENOMEM); /* sp too high */
-  }
-
-  /* In order to support user-space libraries, processes might change sp to
-     point to somewhere inside the data segment. If that's the case, be careful
-     not to erroneously think that the data and stack have collided. */
-  sp_in_dp = (mem_dp->mem_vir <= sp_click) &&
-            (mem_dp->mem_vir + mem_dp->mem_len >= sp_click);
-
-  /* Compute size of gap between stack and data segments. */
-  sp_delta = (long) mem_sp->mem_vir - (long) sp_click;
-  sp_lower = ((sp_delta > 0 && !sp_in_dp) ? sp_click : mem_sp->mem_vir);
-
-  /* Add a safety margin for future stack growth. Impossible to do right. */
-#define SAFETY_BYTES  (384 * sizeof(char *))
-#define SAFETY_CLICKS ((vir_clicks) (CLICK_CEIL(SAFETY_BYTES) >> CLICK_SHIFT))
-  gap_base = mem_dp->mem_vir + data_clicks + SAFETY_CLICKS;
-  if (sp_lower < gap_base)
-  {
-       return(ENOMEM); /* data and stack collided */
-  }
-
-  /* Update data length (but not data orgin) on behalf of brk() system call. */
-  old_clicks = mem_dp->mem_len;
-  if (data_clicks != mem_dp->mem_len) {
-       mem_dp->mem_len = data_clicks;
-       changed |= DATA_CHANGED;
-  }
-
-  /* Update stack length and origin due to change in stack pointer. */
-  if (sp_delta > 0 && !sp_in_dp) {
-       mem_sp->mem_vir -= sp_delta;
-       mem_sp->mem_phys -= sp_delta;
-       mem_sp->mem_len += sp_delta;
-       changed |= STACK_CHANGED;
-  }
-
-  /* Do the new data and stack segment sizes fit in the address space? */
-  r = (rmp->vm_arch.vm_seg[D].mem_vir + rmp->vm_arch.vm_seg[D].mem_len > 
-          rmp->vm_arch.vm_seg[S].mem_vir) ? ENOMEM : OK;
-
-  if(r == OK && (rmp->vm_flags & VMF_HASPT) &&
-     rmp->vm_endpoint != VM_PROC_NR && rmp->vm_heap) {
-       if(old_clicks < data_clicks) {
-               vir_bytes more;
-               more = (data_clicks - old_clicks) << CLICK_SHIFT;
-               if(map_region_extend(rmp, rmp->vm_heap, more) != OK) {
-                       printf("VM: brk: map_region_extend failed\n");
-                       return ENOMEM;
-               }
-       } else if(old_clicks > data_clicks) {
-               vir_bytes less;
-               less = (old_clicks - data_clicks) << CLICK_SHIFT;
-               if(map_region_shrink(rmp->vm_heap, less) != OK) {
-                       printf("VM: brk: map_region_shrink failed\n");
-                       return ENOMEM;
-               }
-       }
-  }
-
-  if (r == OK)
-       return(OK);
-
-  /* New sizes don't fit or require too many page/segment registers. Restore.*/
-  if (changed & DATA_CHANGED) mem_dp->mem_len = old_clicks;
-  if (changed & STACK_CHANGED) {
-       mem_sp->mem_vir += sp_delta;
-       mem_sp->mem_phys += sp_delta;
-       mem_sp->mem_len -= sp_delta;
-  }
-  return(ENOMEM);
-}
-
 /*===========================================================================*
  *                             real_brk                                     *
  *===========================================================================*/
@@ -167,9 +66,6 @@ int real_brk(vmp, v)
 struct vmproc *vmp;
 vir_bytes v;
 {
-       if(!(vmp->vm_flags & VMF_HASPT))
-               return OK;
-
        if(map_region_extend_upto_v(vmp, v) == OK)
                return OK;
 
diff --git a/servers/vm/exec.c b/servers/vm/exec.c
deleted file mode 100644 (file)
index 9a05008..0000000
+++ /dev/null
@@ -1,216 +0,0 @@
-
-#define _SYSTEM 1
-
-#include <minix/callnr.h>
-#include <minix/com.h>
-#include <minix/config.h>
-#include <minix/const.h>
-#include <minix/ds.h>
-#include <minix/endpoint.h>
-#include <minix/keymap.h>
-#include <minix/minlib.h>
-#include <minix/type.h>
-#include <minix/ipc.h>
-#include <minix/sysutil.h>
-#include <minix/syslib.h>
-#include <minix/const.h>
-#include <minix/bitmap.h>
-
-#include <errno.h>
-#include <assert.h>
-#include <string.h>
-#include <env.h>
-#include <pagetable.h>
-#include <sys/param.h>
-
-#include "glo.h"
-#include "proto.h"
-#include "util.h"
-#include "vm.h"
-#include "region.h"
-#include "sanitycheck.h"
-
-#include "memory.h"
-
-/*===========================================================================*
- *                             find_kernel_top                              *
- *===========================================================================*/
-phys_bytes find_kernel_top(void)
-{
-/* Find out where the kernel is, so we know where to start mapping
- * user processes.
- */
-       u32_t kernel_top = 0;
-#define MEMTOP(v, i) \
-  (vmproc[v].vm_arch.vm_seg[i].mem_phys + vmproc[v].vm_arch.vm_seg[i].mem_len)
-       assert(vmproc[VMP_SYSTEM].vm_flags & VMF_INUSE);
-       kernel_top = MEMTOP(VMP_SYSTEM, T);
-       kernel_top = MAX(kernel_top, MEMTOP(VMP_SYSTEM, D));
-       kernel_top = MAX(kernel_top, MEMTOP(VMP_SYSTEM, S));
-       assert(kernel_top);
-
-       return CLICK2ABS(kernel_top);
-}
-
-void regular_segs(struct vmproc *vmp)
-{
-        int s;
-        memset(vmp->vm_arch.vm_seg, 0, sizeof(vmp->vm_arch.vm_seg));
-        vmp->vm_arch.vm_seg[T].mem_phys =
-               vmp->vm_arch.vm_seg[D].mem_phys = ABS2CLICK(VM_PROCSTART);
-        vmp->vm_arch.vm_seg[T].mem_len =
-               vmp->vm_arch.vm_seg[D].mem_len =
-               vmp->vm_arch.vm_seg[S].mem_len = ABS2CLICK(VM_DATATOP-VM_PROCSTART);
-        if((s=sys_newmap(vmp->vm_endpoint, vmp->vm_arch.vm_seg)) != OK)
-                panic("regular_segs: sys_newmap failed: %d", s);
-        if((s=pt_bind(&vmp->vm_pt, vmp)) != OK)
-                panic("regular_segs: pt_bind failed: %d", s);
-}
-
-/*===========================================================================*
- *                             proc_new                                     *
- *===========================================================================*/
-int proc_new(struct vmproc *vmp,
-  phys_bytes vstart,     /* where to start the process in page table */
-  phys_bytes text_addr,   /* address at which to load code */
-  phys_bytes text_bytes,  /* how much code, in bytes but page aligned */
-  phys_bytes data_addr,   /* address at which to load data */
-  phys_bytes data_bytes,  /* how much data + bss, in bytes but page aligned */
-  phys_bytes stack_bytes, /* stack space to reserve, in bytes, page aligned */
-  phys_bytes gap_bytes,   /* gap bytes, page aligned */
-  phys_bytes text_start,  /* text starts here, if preallocated, otherwise 0 */
-  phys_bytes data_start,  /* data starts here, if preallocated, otherwise 0 */
-  phys_bytes stacktop,
-  int prealloc_stack,
-  int is_elf,
-  int full_memview
-)
-{
-       int s;
-       vir_bytes hole_bytes;
-       struct vir_region *reg;
-       phys_bytes map_text_addr, map_data_addr, map_stack_addr;
-
-       assert(!(vstart % VM_PAGE_SIZE));
-       assert(!(text_addr % VM_PAGE_SIZE));
-       assert(!(text_bytes % VM_PAGE_SIZE));
-       assert(!(data_addr % VM_PAGE_SIZE));
-       assert(!(data_bytes % VM_PAGE_SIZE));
-       assert(!(stack_bytes % VM_PAGE_SIZE));
-       assert(!(gap_bytes % VM_PAGE_SIZE));
-       assert(!(text_start % VM_PAGE_SIZE));
-       assert(!(data_start % VM_PAGE_SIZE));
-       assert((!text_start && !data_start) || (text_start && data_start));
-
-       /* Place text at start of process. */
-       map_text_addr = vstart + text_addr;
-       vmp->vm_arch.vm_seg[T].mem_phys = ABS2CLICK(map_text_addr);
-       vmp->vm_arch.vm_seg[T].mem_vir = ABS2CLICK(text_addr);
-       if(full_memview) {
-               vmp->vm_arch.vm_seg[T].mem_len = ABS2CLICK(VM_DATATOP) -
-                       vmp->vm_arch.vm_seg[T].mem_phys;
-       } else {
-               vmp->vm_arch.vm_seg[T].mem_len = ABS2CLICK(text_bytes);
-       }
-
-       vmp->vm_offset = vstart;
-
-       /* page mapping flags for code */
-#define TEXTFLAGS (PTF_PRESENT | PTF_USER)
-       SANITYCHECK(SCL_DETAIL);
-       if(text_bytes > 0) {
-               if(!(reg=map_page_region(vmp, map_text_addr, 0, text_bytes,
-                 text_start ? text_start : MAP_NONE,
-                 VR_ANON | VR_WRITABLE, text_start ? 0 : MF_PREALLOC))) {
-                       SANITYCHECK(SCL_DETAIL);
-                       printf("VM: proc_new: map_page_region failed (text)\n");
-                       map_free_proc(vmp);
-                       SANITYCHECK(SCL_DETAIL);
-                       return(ENOMEM);
-               }
-
-               map_region_set_tag(reg, VRT_TEXT);
-               SANITYCHECK(SCL_DETAIL);
-       }
-       SANITYCHECK(SCL_DETAIL);
-
-       /* Allocate memory for data (including bss, but not including gap
-        * or stack), make sure it's cleared, and map it in after text
-        * (if any).
-        */
-       if (is_elf) {
-           map_data_addr = vstart + data_addr;
-       } else {
-           map_data_addr = vstart + text_bytes;
-       }
-
-       if(!(vmp->vm_heap = map_page_region(vmp, map_data_addr, 0,
-         data_bytes, data_start ? data_start : MAP_NONE, VR_ANON | VR_WRITABLE,
-               data_start ? 0 : MF_PREALLOC))) {
-               printf("VM: exec: map_page_region for data failed\n");
-               map_free_proc(vmp);
-               SANITYCHECK(SCL_DETAIL);
-               return ENOMEM;
-       }
-
-       /* Tag the heap so brk() call knows which region to extend. */
-       map_region_set_tag(vmp->vm_heap, VRT_HEAP);
-
-       /* How many address space clicks between end of data
-        * and start of stack?
-        * stacktop is the first address after the stack, as addressed
-        * from within the user process.
-        */
-       hole_bytes = stacktop - data_bytes - stack_bytes
-           - gap_bytes - data_addr;
-
-       map_stack_addr = map_data_addr + data_bytes + hole_bytes;
-
-       if(!(reg=map_page_region(vmp,
-               map_stack_addr,
-         0, stack_bytes + gap_bytes, MAP_NONE,
-         VR_ANON | VR_WRITABLE, prealloc_stack ? MF_PREALLOC : 0)) != OK) {
-               panic("map_page_region failed for stack");
-       }
-
-       map_region_set_tag(reg, VRT_STACK);
-
-       vmp->vm_arch.vm_seg[D].mem_phys = ABS2CLICK(map_data_addr);
-       vmp->vm_arch.vm_seg[D].mem_vir = ABS2CLICK(data_addr);
-       vmp->vm_arch.vm_seg[D].mem_len = ABS2CLICK(data_bytes);
-
-       vmp->vm_arch.vm_seg[S].mem_phys = ABS2CLICK(map_data_addr +
-               data_bytes + gap_bytes + hole_bytes);
-       vmp->vm_arch.vm_seg[S].mem_vir = ABS2CLICK(data_addr +
-               data_bytes + gap_bytes + hole_bytes);
-
-       /* Where are we allowed to start using the rest of the virtual
-        * address space?
-        */
-       vmp->vm_stacktop = stacktop;
-
-       vmp->vm_flags |= VMF_HASPT;
-
-       if(vmp->vm_endpoint != NONE) {
-
-               /* Pretend the stack is the full size of the data segment, so
-                * we get a full-sized data segment, up to VM_DATATOP.
-                * After sys_newmap(), change the stack to what we know the
-                * stack to be (up to stacktop).
-                */
-               vmp->vm_arch.vm_seg[S].mem_len = (VM_DATATOP >> CLICK_SHIFT) -
-                   vmp->vm_arch.vm_seg[S].mem_vir - ABS2CLICK(map_data_addr);
-
-               /* What is the final size of the data segment in bytes? */
-               vmp->vm_arch.vm_data_top =
-                   (vmp->vm_arch.vm_seg[S].mem_vir +
-                    vmp->vm_arch.vm_seg[S].mem_len) << CLICK_SHIFT;
-
-               if((s=sys_newmap(vmp->vm_endpoint, vmp->vm_arch.vm_seg)) != OK)
-                       panic("sys_newmap (vm) failed: %d", s);
-               if((s=pt_bind(&vmp->vm_pt, vmp)) != OK)
-                       panic("exec_newmem: pt_bind failed: %d", s);
-       }
-
-       return OK;
-}
index 247172bb91ca5fa1bc054e63826ef28f71b91a09..afb6993dc8911bbc0dc12079dc4bab65c00fec4a 100644 (file)
 void free_proc(struct vmproc *vmp)
 {
        map_free_proc(vmp);
-       vmp->vm_heap = NULL;
-       if(vmp->vm_flags & VMF_HASPT) {
-               vmp->vm_flags &= ~VMF_HASPT;
-               pt_free(&vmp->vm_pt);
-       }
+       pt_free(&vmp->vm_pt);
        region_init(&vmp->vm_regions_avl);
        vmp->vm_region_top = 0;
 #if VMSTATS
@@ -45,7 +41,6 @@ void clear_proc(struct vmproc *vmp)
        vmp->vm_region_top = 0;
        vmp->vm_callback = NULL;        /* No pending vfs callback. */
        vmp->vm_flags = 0;              /* Clear INUSE, so slot is free. */
-       vmp->vm_heap = NULL;
        vmp->vm_yielded = 0;
 #if VMSTATS
        vmp->vm_bytecopies = 0;
@@ -74,18 +69,12 @@ SANITYCHECK(SCL_FUNCTIONS);
 
        if(vmp->vm_flags & VMF_HAS_DMA) {
                release_dma(vmp);
-       } else if(vmp->vm_flags & VMF_HASPT) {
+       } else {
                /* Free pagetable and pages allocated by pt code. */
 SANITYCHECK(SCL_DETAIL);
                free_proc(vmp);
 SANITYCHECK(SCL_DETAIL);
-       } else {
-                 /* Free the data and stack segments. */        
-                free_mem(vmp->vm_arch.vm_seg[D].mem_phys,       
-                        vmp->vm_arch.vm_seg[S].mem_vir +        
-                        vmp->vm_arch.vm_seg[S].mem_len -        
-                        vmp->vm_arch.vm_seg[D].mem_vir);        
-       }
+       } 
 SANITYCHECK(SCL_DETAIL);
 
        /* Reset process slot fields. */
@@ -134,9 +123,7 @@ int do_procctl(message *msg)
                                return EPERM;
                        free_proc(vmp);
                        pt_new(&vmp->vm_pt);
-                       vmp->vm_flags |= VMF_HASPT;
                        pt_bind(&vmp->vm_pt, vmp);
-                       regular_segs(vmp);
                        return OK;
                default:
                        return EINVAL;
index 807fba710d3e158cee18c048507774abcfc0a6ed..d42a27c8acae63c7533671bfaf62a934b16b4efc 100644 (file)
@@ -34,7 +34,7 @@
  *===========================================================================*/
 int do_fork(message *msg)
 {
-  int r, proc, childproc, fullvm;
+  int r, proc, childproc;
   struct vmproc *vmp, *vmc;
   pt_t origpt;
   vir_bytes msgaddr;
@@ -63,8 +63,6 @@ int do_fork(message *msg)
        return EINVAL;
   }
 
-  fullvm = vmp->vm_flags & VMF_HASPT;
-
   /* The child is basically a copy of the parent. */
   origpt = vmc->vm_pt;
   *vmc = *vmp;
@@ -72,7 +70,6 @@ int do_fork(message *msg)
   region_init(&vmc->vm_regions_avl);
   vmc->vm_endpoint = NONE;     /* In case someone tries to use it. */
   vmc->vm_pt = origpt;
-  vmc->vm_flags &= ~VMF_HASPT;
 
 #if VMSTATS
   vmc->vm_bytecopies = 0;
@@ -83,136 +80,38 @@ int do_fork(message *msg)
        return ENOMEM;
   }
 
-  vmc->vm_flags |= VMF_HASPT;
-
-  if(fullvm) {
-       SANITYCHECK(SCL_DETAIL);
-
-       if(map_proc_copy(vmc, vmp) != OK) {
-               printf("VM: fork: map_proc_copy failed\n");
-               pt_free(&vmc->vm_pt);
-               return(ENOMEM);
-       }
-
-       if(vmp->vm_heap) {
-               vmc->vm_heap = map_region_lookup_tag(vmc, VRT_HEAP);
-               assert(vmc->vm_heap);
-       }
-
-       SANITYCHECK(SCL_DETAIL);
-  } else {
-       vir_bytes sp;
-       struct vir_region *heap, *stack;
-       vir_bytes text_bytes, data_bytes, stack_bytes, parent_gap_bytes,
-               child_gap_bytes;
-       vir_bytes text_addr, data_addr;
-       int is_elf = 0;
-
-       /* Get SP of new process (using parent). */
-       if(get_stack_ptr(vmp->vm_endpoint, &sp) != OK) {
-               printf("VM: fork: get_stack_ptr failed for %d\n",
-                       vmp->vm_endpoint);
-               return ENOMEM;
-       }
-
-       /* Update size of stack segment using current SP. */
-       if(adjust(vmp, vmp->vm_arch.vm_seg[D].mem_len, sp) != OK) {
-               printf("VM: fork: adjust failed for %d\n",
-                       vmp->vm_endpoint);
-               return ENOMEM;
-       }
-
-       /* Copy newly adjust()ed stack segment size to child. */
-       vmc->vm_arch.vm_seg[S] = vmp->vm_arch.vm_seg[S];
-
-       text_addr = CLICK2ABS(vmc->vm_arch.vm_seg[T].mem_vir);
-        text_bytes = CLICK2ABS(vmc->vm_arch.vm_seg[T].mem_len);
-       data_addr = CLICK2ABS(vmc->vm_arch.vm_seg[D].mem_vir);
-        data_bytes = CLICK2ABS(vmc->vm_arch.vm_seg[D].mem_len);
-       stack_bytes = CLICK2ABS(vmc->vm_arch.vm_seg[S].mem_len);
-
-       /* how much space after break and before lower end (which is the
-        * logical top) of stack for the parent
-        */
-       parent_gap_bytes = CLICK2ABS(vmc->vm_arch.vm_seg[S].mem_vir -
-               vmc->vm_arch.vm_seg[D].mem_len -
-               vmc->vm_arch.vm_seg[D].mem_vir);
-
-       /* how much space can the child stack grow downwards, below
-        * the current SP? The rest of the gap is available for the
-        * heap to grow upwards.
-        */
-       child_gap_bytes = VM_PAGE_SIZE;
-
-#if defined(__ELF__)
-       is_elf = 1;
-#endif
+  SANITYCHECK(SCL_DETAIL);
 
-        if((r=proc_new(vmc, VM_PROCSTART,
-               text_addr, text_bytes,
-               data_addr, data_bytes,
-               stack_bytes, child_gap_bytes, 0, 0,
-               CLICK2ABS(vmc->vm_arch.vm_seg[S].mem_vir +
-                         vmc->vm_arch.vm_seg[S].mem_len),
-               1, is_elf, 0)) != OK) {
-                       printf("VM: fork: proc_new failed\n");
-                       return r;
-       }
-
-       if(!(heap = map_region_lookup_tag(vmc, VRT_HEAP)))
-               panic("couldn't lookup heap");
-       assert(heap->phys);
-       if(!(stack = map_region_lookup_tag(vmc, VRT_STACK)))
-               panic("couldn't lookup stack");
-       assert(stack->phys);
-
-       /* Now copy the memory regions. */
-
-       if(vmc->vm_arch.vm_seg[T].mem_len > 0) {
-               struct vir_region *text;
-               if(!(text = map_region_lookup_tag(vmc, VRT_TEXT)))
-                       panic("couldn't lookup text");
-               assert(text->phys);
-               if(copy_abs2region(CLICK2ABS(vmp->vm_arch.vm_seg[T].mem_phys),
-                       text, 0, text_bytes) != OK)
-                               panic("couldn't copy text");
-       }
-
-       if(copy_abs2region(CLICK2ABS(vmp->vm_arch.vm_seg[D].mem_phys),
-               heap, 0, data_bytes) != OK)
-                       panic("couldn't copy heap");
-
-       if(copy_abs2region(CLICK2ABS(vmp->vm_arch.vm_seg[D].mem_phys +
-                       vmc->vm_arch.vm_seg[D].mem_len) + parent_gap_bytes,
-                       stack, child_gap_bytes, stack_bytes) != OK)
-                       panic("couldn't copy stack");
+  if(map_proc_copy(vmc, vmp) != OK) {
+       printf("VM: fork: map_proc_copy failed\n");
+       pt_free(&vmc->vm_pt);
+       return(ENOMEM);
   }
 
   /* Only inherit these flags. */
-  vmc->vm_flags &= (VMF_INUSE|VMF_SEPARATE|VMF_HASPT);
+  vmc->vm_flags &= VMF_INUSE;
 
   /* inherit the priv call bitmaps */
   memcpy(&vmc->vm_call_mask, &vmp->vm_call_mask, sizeof(vmc->vm_call_mask));
 
   /* Tell kernel about the (now successful) FORK. */
   if((r=sys_fork(vmp->vm_endpoint, childproc,
-       &vmc->vm_endpoint, vmc->vm_arch.vm_seg,
-       PFF_VMINHIBIT, &msgaddr)) != OK) {
+       &vmc->vm_endpoint, PFF_VMINHIBIT, &msgaddr)) != OK) {
         panic("do_fork can't sys_fork: %d", r);
   }
 
   if((r=pt_bind(&vmc->vm_pt, vmc)) != OK)
        panic("fork can't pt_bind: %d", r);
 
-  if(fullvm) {
+  {
        vir_bytes vir;
        /* making these messages writable is an optimisation
         * and its return value needn't be checked.
         */
-       vir = arch_vir2map(vmc, msgaddr);
+       vir = msgaddr;
        if (handle_memory(vmc, vir, sizeof(message), 1) != OK)
            panic("do_fork: handle_memory for child failed\n");
-       vir = arch_vir2map(vmp, msgaddr);
+       vir = msgaddr;
        if (handle_memory(vmp, vir, sizeof(message), 1) != OK)
            panic("do_fork: handle_memory for parent failed\n");
   }
index 8616f79a68c557af33590855818c8123d2013691..e0ba5366f4cc6179afd634e897e65148f1124936 100644 (file)
@@ -1,5 +1,6 @@
 
 #include <minix/sys_config.h>
+#include <minix/type.h>
 #include <sys/stat.h>
 #include <a.out.h>
 #include <tools.h>
 #define EXTERN
 #endif
 
-#define VMP_SYSTEM     _NR_PROCS
-#define VMP_EXECTMP    _NR_PROCS+1
-#define VMP_NR         _NR_PROCS+2
+#define VMP_EXECTMP    _NR_PROCS
+#define VMP_NR         _NR_PROCS+1
 
 EXTERN struct vmproc vmproc[VMP_NR];
 
+EXTERN kinfo_t kernel_boot_info;
+
 #if SANITYCHECKS
 EXTERN int nocheck;
 EXTERN int incheck;
index 9acc02b0cc6cca0475614c4c500a961301b4d793..4023ea4d612d5216e62992721643d52bae4bd267 100644 (file)
@@ -20,6 +20,8 @@
 #include <minix/crtso.h>
 #include <minix/rs.h>
 
+#include <libexec.h>
+#include <ctype.h>
 #include <errno.h>
 #include <string.h>
 #include <env.h>
@@ -38,6 +40,7 @@
 extern int missing_spares;
 
 #include <machine/archtypes.h>
+#include <sys/param.h>
 #include "kernel/const.h"
 #include "kernel/config.h"
 #include "kernel/proc.h"
@@ -60,12 +63,13 @@ struct {
 
 static int map_service(struct rprocpub *rpub);
 static int vm_acl_ok(endpoint_t caller, int call);
+static int do_rs_init(message *m);
 
 /* SEF functions and variables. */
-static void sef_local_startup(void);
-static int sef_cb_init_fresh(int type, sef_init_info_t *info);
 static void sef_cb_signal_handler(int signo);
 
+void init_vm(void);
+
 /*===========================================================================*
  *                             main                                         *
  *===========================================================================*/
@@ -76,8 +80,15 @@ int main(void)
   int caller_slot;
   struct vmproc *vmp_caller;
 
-  /* SEF local startup. */
-  sef_local_startup();
+  /* Initialize system so that all processes are runnable */
+  init_vm();
+
+  /* Register init callbacks. */
+  sef_setcb_init_restart(sef_cb_init_fail);
+  sef_setcb_signal_handler(sef_cb_signal_handler);
+
+  /* Let SEF perform startup. */
+  sef_startup();
 
   SANITYCHECK(SCL_TOP);
 
@@ -100,11 +111,14 @@ int main(void)
        }
        who_e = msg.m_source;
        if(vm_isokendpt(who_e, &caller_slot) != OK)
-               panic("invalid caller", who_e);
+               panic("invalid caller %d", who_e);
        vmp_caller = &vmproc[caller_slot];
        c = CALLNUMBER(msg.m_type);
        result = ENOSYS; /* Out of range or restricted calls return this. */
-       if (msg.m_type == VM_PAGEFAULT) {
+       
+       if(msg.m_type == RS_INIT && msg.m_source == RS_PROC_NR) {
+               result = do_rs_init(&msg);
+       } else if (msg.m_type == VM_PAGEFAULT) {
                if (!IPC_STATUS_FLAGS_TEST(rcv_sts, IPC_FLG_MSG_FROM_KERNEL)) {
                        printf("VM: process %d faked VM_PAGEFAULT "
                                        "message!\n", msg.m_source);
@@ -145,179 +159,214 @@ int main(void)
   return(OK);
 }
 
-/*===========================================================================*
- *                            sef_local_startup                             *
- *===========================================================================*/
-static void sef_local_startup()
+static int do_rs_init(message *m)
 {
-  /* Register init callbacks. */
-  sef_setcb_init_fresh(sef_cb_init_fresh);
-  sef_setcb_init_restart(sef_cb_init_fail);
+       int s, i;
+       static struct rprocpub rprocpub[NR_BOOT_PROCS];
+
+       /* Map all the services in the boot image. */
+       if((s = sys_safecopyfrom(RS_PROC_NR, m->RS_INIT_RPROCTAB_GID, 0,
+               (vir_bytes) rprocpub, sizeof(rprocpub))) != OK) {
+               panic("vm: sys_safecopyfrom (rs) failed: %d", s);
+       }
 
-  /* No live update support for now. */
+       for(i=0;i < NR_BOOT_PROCS;i++) {
+               if(rprocpub[i].in_use) {
+                       if((s = map_service(&rprocpub[i])) != OK) {
+                               panic("unable to map service: %d", s);
+                       }
+               }
+       }
 
-  /* Register signal callbacks. */
-  sef_setcb_signal_handler(sef_cb_signal_handler);
+       /* RS expects this response that it then again wants to reply to: */
+       m->RS_INIT_RESULT = OK;
+       sendrec(RS_PROC_NR, m);
 
-  /* Let SEF perform startup. */
-  sef_startup();
+       return(SUSPEND);
 }
 
-/*===========================================================================*
- *                             sef_cb_init_fresh                            *
- *===========================================================================*/
-static int sef_cb_init_fresh(int type, sef_init_info_t *info)
+struct vmproc *init_proc(endpoint_t ep_nr)
 {
-/* Initialize the vm server. */
-       int s, i;
-       struct memory mem_chunks[NR_MEMS];
-       struct boot_image image[NR_BOOT_PROCS];
-       struct boot_image *ip;
-       struct rprocpub rprocpub[NR_BOOT_PROCS];
-       phys_bytes limit = 0;
-       int is_elf = 0;
+       static struct boot_image *ip;
 
-#if SANITYCHECKS
-       incheck = nocheck = 0;
-#endif
+       for (ip = &kernel_boot_info.boot_procs[0];
+               ip < &kernel_boot_info.boot_procs[NR_BOOT_PROCS]; ip++) {
+               struct vmproc *vmp;
 
-#if SANITYCHECKS
-       env_parse("vm_sanitychecklevel", "d", 0, &vm_sanitychecklevel, 0, SCL_MAX);
-#endif
+               if(ip->proc_nr != ep_nr) continue;
 
-       /* Get chunks of available memory. */
-       get_mem_chunks(mem_chunks);
+               if(ip->proc_nr >= _NR_PROCS || ip->proc_nr < 0)
+                       panic("proc: %d", ip->proc_nr);
 
-       /* Initialize VM's process table. Request a copy of the system
-        * image table that is defined at the kernel level to see which
-        * slots to fill in.
-        */
-       if (OK != (s=sys_getimage(image)))
-               panic("couldn't get image table: %d", s);
+               vmp = &vmproc[ip->proc_nr];
+               assert(!(vmp->vm_flags & VMF_INUSE));   /* no double procs */
+               clear_proc(vmp);
+               vmp->vm_flags = VMF_INUSE;
+               vmp->vm_endpoint = ip->endpoint;
+               vmp->vm_boot = ip;
 
-       /* Set table to 0. This invalidates all slots (clear VMF_INUSE). */
-       memset(vmproc, 0, sizeof(vmproc));
+               return vmp;
+       }
 
-       for(i = 0; i < ELEMENTS(vmproc); i++) {
-               vmproc[i].vm_slot = i;
+       panic("no init_proc");
+}
+
+struct vm_exec_info {
+       struct exec_info execi;
+       struct boot_image *ip;
+       struct vmproc *vmp;
+};
+
+static int libexec_copy_physcopy(struct exec_info *execi,
+        off_t off, off_t vaddr, size_t len)
+{
+       vir_bytes end;
+       struct vm_exec_info *ei = execi->opaque;
+       end = ei->ip->start_addr + ei->ip->len;
+        assert(ei->ip->start_addr + off + len <= end);
+        return sys_physcopy(NONE, ei->ip->start_addr + off,
+               execi->proc_e, vaddr, len);
+}
+
+static void boot_alloc(struct exec_info *execi, off_t vaddr,
+       size_t len, int flags)
+{
+       struct vmproc *vmp = ((struct vm_exec_info *) execi->opaque)->vmp;
+
+       if(!(map_page_region(vmp, vaddr, 0,
+               len, MAP_NONE, VR_ANON | VR_WRITABLE | VR_UNINITIALIZED, flags))) {
+               panic("VM: exec: map_page_region for boot process failed");
        }
+}
 
-       /* Walk through boot-time system processes that are alive
-        * now and make valid slot entries for them.
-        */
-       for (ip = &image[0]; ip < &image[NR_BOOT_PROCS]; ip++) {
-               phys_bytes proclimit;
-               struct vmproc *vmp;
+static int libexec_alloc_vm_prealloc(struct exec_info *execi,
+       off_t vaddr, size_t len)
+{
+       boot_alloc(execi, vaddr, len, MF_PREALLOC);
+       return OK;
+}
 
-               if(ip->proc_nr >= _NR_PROCS) { panic("proc: %d", ip->proc_nr); }
-               if(ip->proc_nr < 0 && ip->proc_nr != SYSTEM) continue;
+static int libexec_alloc_vm_ondemand(struct exec_info *execi,
+       off_t vaddr, size_t len)
+{
+       boot_alloc(execi, vaddr, len, 0);
+       return OK;
+}
 
-#define GETVMP(v, nr)                                          \
-               if(nr >= 0) {                                   \
-                       vmp = &vmproc[ip->proc_nr];             \
-               } else if(nr == SYSTEM) {                       \
-                       vmp = &vmproc[VMP_SYSTEM];              \
-               } else {                                        \
-                       panic("init: crazy proc_nr: %d", nr);   \
-               }
+void exec_bootproc(struct vmproc *vmp, struct boot_image *ip)
+{
+       struct vm_exec_info vmexeci;
+       struct exec_info *execi = &vmexeci.execi;
+       char hdr[VM_PAGE_SIZE];
+
+       memset(&vmexeci, 0, sizeof(vmexeci));
+
+       if(pt_new(&vmp->vm_pt) != OK)
+               panic("VM: no new pagetable");
+
+       if(pt_bind(&vmp->vm_pt, vmp) != OK)
+               panic("VM: pt_bind failed");
+
+       if(sys_physcopy(NONE, ip->start_addr, SELF,
+               (vir_bytes) hdr, sizeof(hdr)) != OK)
+               panic("can't look at boot proc header");
+
+        execi->stack_high = kernel_boot_info.user_sp;
+        execi->stack_size = DEFAULT_STACK_LIMIT;
+        execi->proc_e = vmp->vm_endpoint;
+        execi->hdr = hdr;
+        execi->hdr_len = sizeof(hdr);
+        strcpy(execi->progname, ip->proc_name);
+        execi->frame_len = 0;
+       execi->opaque = &vmexeci;
+
+       vmexeci.ip = ip;
+       vmexeci.vmp = vmp;
+
+        /* callback functions and data */
+        execi->copymem = libexec_copy_physcopy;
+        execi->clearproc = NULL;
+        execi->clearmem = libexec_clear_sys_memset;
+        execi->allocmem_prealloc = libexec_alloc_vm_prealloc;
+        execi->allocmem_ondemand = libexec_alloc_vm_ondemand;
+
+       if(libexec_load_elf(execi) != OK)
+               panic("vm: boot process load of %d failed\n", vmp->vm_endpoint);
+
+        if(sys_exec(vmp->vm_endpoint, (char *) execi->stack_high - 12,
+               (char *) ip->proc_name, execi->pc) != OK)
+               panic("vm: boot process exec of %d failed\n", vmp->vm_endpoint);
+}
 
-               /* Initialize normal process table slot or special SYSTEM
-                * table slot. Kernel memory is already reserved.
-                */
-               GETVMP(vmp, ip->proc_nr);
+void init_vm(void)
+{
+       int s, i;
+       static struct memory mem_chunks[NR_MEMS];
+       static struct boot_image *ip;
 
-               /* reset fields as if exited */
-               clear_proc(vmp);
+#if SANITYCHECKS
+       incheck = nocheck = 0;
+#endif
 
-               /* Get memory map for this process from the kernel. */
-               if ((s=get_mem_map(ip->proc_nr, vmp->vm_arch.vm_seg)) != OK)
-                       panic("couldn't get process mem_map: %d", s);
+       /* Retrieve various crucial boot parameters */
+       if(OK != (s=sys_getkinfo(&kernel_boot_info))) {
+               panic("couldn't get bootinfo: %d", s);
+       }
 
-               /* Remove this memory from the free list. */
-               reserve_proc_mem(mem_chunks, vmp->vm_arch.vm_seg);
+       /* Sanity check */
+       assert(kernel_boot_info.mmap_size > 0);
+       assert(kernel_boot_info.mods_with_kernel > 0);
 
-               /* Set memory limit. */
-               proclimit = CLICK2ABS(vmp->vm_arch.vm_seg[S].mem_phys +
-                       vmp->vm_arch.vm_seg[S].mem_len) - 1;
+#if SANITYCHECKS
+       env_parse("vm_sanitychecklevel", "d", 0, &vm_sanitychecklevel, 0, SCL_MAX);
 
-               if(proclimit > limit)
-                       limit = proclimit;
+       vm_sanitychecklevel = 1;
+#endif
 
-               vmp->vm_flags = VMF_INUSE;
-               vmp->vm_endpoint = ip->endpoint;
-               vmp->vm_stacktop =
-                       CLICK2ABS(vmp->vm_arch.vm_seg[S].mem_vir +
-                               vmp->vm_arch.vm_seg[S].mem_len);
+       /* Get chunks of available memory. */
+       get_mem_chunks(mem_chunks);
+
+       /* Set table to 0. This invalidates all slots (clear VMF_INUSE). */
+       memset(vmproc, 0, sizeof(vmproc));
 
-               if (vmp->vm_arch.vm_seg[T].mem_len != 0)
-                       vmp->vm_flags |= VMF_SEPARATE;
+       for(i = 0; i < ELEMENTS(vmproc); i++) {
+               vmproc[i].vm_slot = i;
        }
 
        /* region management initialization. */
        map_region_init();
 
        /* Architecture-dependent initialization. */
-       pt_init(limit);
+       init_proc(VM_PROC_NR);
+       pt_init();
 
        /* Initialize tables to all physical memory. */
        mem_init(mem_chunks);
        meminit_done = 1;
 
-       /* Architecture-dependent memory initialization. */
-       pt_init_mem();
-
        /* Give these processes their own page table. */
-       for (ip = &image[0]; ip < &image[NR_BOOT_PROCS]; ip++) {
+       for (ip = &kernel_boot_info.boot_procs[0];
+               ip < &kernel_boot_info.boot_procs[NR_BOOT_PROCS]; ip++) {
                struct vmproc *vmp;
-               vir_bytes old_stacktop, old_stacklen;
 
                if(ip->proc_nr < 0) continue;
 
-               GETVMP(vmp, ip->proc_nr);
+               assert(ip->start_addr);
 
-               if(!(ip->flags & PROC_FULLVM))
-                       continue;
-
-               if(pt_new(&vmp->vm_pt) != OK)
-                       panic("VM: no new pagetable");
-#define BASICSTACK VM_PAGE_SIZE
-               old_stacktop = CLICK2ABS(vmp->vm_arch.vm_seg[S].mem_vir +
-                               vmp->vm_arch.vm_seg[S].mem_len);
-               if(sys_vmctl(vmp->vm_endpoint, VMCTL_INCSP,
-                       VM_STACKTOP - old_stacktop) != OK) {
-                       panic("VM: vmctl for new stack failed");
-               }
+               /* VM has already been set up by the kernel and pt_init().
+                * Any other boot process is already in memory and is set up
+                * here.
+                */
+               if(ip->proc_nr == VM_PROC_NR) continue;
 
-               old_stacklen =
-                       vmp->vm_arch.vm_seg[S].mem_vir +
-                       vmp->vm_arch.vm_seg[S].mem_len -
-                       vmp->vm_arch.vm_seg[D].mem_len -
-                       vmp->vm_arch.vm_seg[D].mem_vir;
+               vmp = init_proc(ip->proc_nr);
 
-               free_mem(vmp->vm_arch.vm_seg[D].mem_phys +
-                       vmp->vm_arch.vm_seg[D].mem_len,
-                       old_stacklen);
+               exec_bootproc(vmp, ip);
 
-#if defined(__ELF__)
-               is_elf = 1;
-#endif
-
-               if(proc_new(vmp,
-                       VM_PROCSTART,
-                       CLICK2ABS(vmp->vm_arch.vm_seg[T].mem_vir),
-                       CLICK2ABS(vmp->vm_arch.vm_seg[T].mem_len),
-                       CLICK2ABS(vmp->vm_arch.vm_seg[D].mem_vir),
-                       CLICK2ABS(vmp->vm_arch.vm_seg[D].mem_len),
-                       BASICSTACK,
-                       CLICK2ABS(vmp->vm_arch.vm_seg[S].mem_vir +
-                               vmp->vm_arch.vm_seg[S].mem_len -
-                               vmp->vm_arch.vm_seg[D].mem_len -
-                               vmp->vm_arch.vm_seg[D].mem_vir) - BASICSTACK,
-                       CLICK2ABS(vmp->vm_arch.vm_seg[T].mem_phys),
-                       CLICK2ABS(vmp->vm_arch.vm_seg[D].mem_phys),
-                           VM_STACKTOP, 0, is_elf, 0) != OK) {
-                       panic("failed proc_new for boot process");
-               }
+               /* Free the file blob */
+               assert(!(ip->start_addr % VM_PAGE_SIZE));
+               ip->len = roundup(ip->len, VM_PAGE_SIZE);
+               free_mem(ABS2CLICK(ip->start_addr), ABS2CLICK(ip->len));
        }
 
        /* Set up table of calls. */
@@ -372,27 +421,8 @@ static int sef_cb_init_fresh(int type, sef_init_info_t *info)
        CALLMAP(VM_FORGETBLOCK, do_forgetblock);
        CALLMAP(VM_YIELDBLOCKGETBLOCK, do_yieldblockgetblock);
 
-       /* Sanity checks */
-       if(find_kernel_top() >= VM_PROCSTART)
-               panic("kernel loaded too high");
-
        /* Initialize the structures for queryexit */
        init_query_exit();
-
-       /* Map all the services in the boot image. */
-       if((s = sys_safecopyfrom(RS_PROC_NR, info->rproctab_gid, 0,
-               (vir_bytes) rprocpub, sizeof(rprocpub))) != OK) {
-               panic("sys_safecopyfrom failed: %d", s);
-       }
-       for(i=0;i < NR_BOOT_PROCS;i++) {
-               if(rprocpub[i].in_use) {
-                       if((s = map_service(&rprocpub[i])) != OK) {
-                               panic("unable to map service: %d", s);
-                       }
-               }
-       }
-
-       return(OK);
 }
 
 /*===========================================================================*
index 2110cccda91de3e39a73c2e9f6327bd30e91ec16..a54f9b2b4ba6806cf05b82ba697f06e946d203fb 100644 (file)
@@ -62,9 +62,6 @@ int do_mmap(message *m)
 
        vmp = &vmproc[n];
 
-       if(!(vmp->vm_flags & VMF_HASPT))
-               return ENXIO;
-
        if(m->VMM_FD == -1 || (m->VMM_FLAGS & MAP_ANON)) {
                u32_t vrflags = VR_ANON | VR_WRITABLE;
                size_t len = (vir_bytes) m->VMM_LEN;
@@ -102,7 +99,7 @@ int do_mmap(message *m)
                vr = NULL;
                if (m->VMM_ADDR || (m->VMM_FLAGS & MAP_FIXED)) {
                        /* An address is given, first try at that address. */
-                       addr = arch_vir2map(vmp, m->VMM_ADDR);
+                       addr = m->VMM_ADDR;
                        vr = map_page_region(vmp, addr, 0, len, MAP_NONE,
                                vrflags, mfflags);
                        if(!vr && (m->VMM_FLAGS & MAP_FIXED))
@@ -110,8 +107,7 @@ int do_mmap(message *m)
                }
                if (!vr) {
                        /* No address given or address already in use. */
-                       addr = arch_vir2map(vmp, vmp->vm_stacktop);
-                       vr = map_page_region(vmp, addr, VM_DATATOP, len,
+                       vr = map_page_region(vmp, 0, VM_DATATOP, len,
                                MAP_NONE, vrflags, mfflags);
                }
                if (!vr) {
@@ -123,7 +119,7 @@ int do_mmap(message *m)
 
        /* Return mapping, as seen from process. */
        assert(vr);
-       m->VMM_RETADDR = arch_map2vir(vmp, vr->vaddr);
+       m->VMM_RETADDR = vr->vaddr;
 
 
        return OK;
@@ -194,9 +190,6 @@ int do_map_phys(message *m)
 
        vmp = &vmproc[n];
 
-       if(!(vmp->vm_flags & VMF_HASPT))
-               return ENXIO;
-
        offset = startaddr % VM_PAGE_SIZE;
        len += offset;
        startaddr -= offset;
@@ -204,13 +197,12 @@ int do_map_phys(message *m)
        if(len % VM_PAGE_SIZE)
                len += VM_PAGE_SIZE - (len % VM_PAGE_SIZE);
 
-       if(!(vr = map_page_region(vmp, arch_vir2map(vmp, vmp->vm_stacktop),
-               VM_DATATOP, len, startaddr,
+       if(!(vr = map_page_region(vmp, 0, VM_DATATOP, len, startaddr,
                VR_DIRECT | VR_NOPF | VR_WRITABLE, 0))) {
                return ENOMEM;
        }
 
-       m->VMMP_VADDR_REPLY = (void *) (arch_map2vir(vmp, vr->vaddr) + offset);
+       m->VMMP_VADDR_REPLY = (void *) (vr->vaddr + offset);
 
        return OK;
 }
@@ -234,8 +226,7 @@ int do_unmap_phys(message *m)
 
        vmp = &vmproc[n];
 
-       if(!(region = map_lookup(vmp,
-         arch_vir2map(vmp, (vir_bytes) m->VMUM_ADDR)))) {
+       if(!(region = map_lookup(vmp, (vir_bytes) m->VMUM_ADDR))) {
                return EINVAL;
        }
 
@@ -289,8 +280,6 @@ int do_remap(message *m)
         * about whether the user needs to bind to
         * THAT address or be chosen by the system.
         */
-       sa = arch_vir2map(svmp, sa);
-
        if (!(region = map_lookup(svmp, sa)))
                return EINVAL;
 
@@ -315,7 +304,7 @@ int do_remap(message *m)
        if ((r = map_remap(dvmp, da, size, region, &startv, readonly)) != OK)
                return r;
 
-       m->VMRE_RETA = (char *) arch_map2vir(dvmp, startv);
+       m->VMRE_RETA = (char *) startv;
        return OK;
 }
 
@@ -339,7 +328,7 @@ int do_shared_unmap(message *m)
 
        vmp = &vmproc[n];
 
-       addr = arch_vir2map(vmp, m->VMUN_ADDR);
+       addr = m->VMUN_ADDR;
 
        if(!(vr = map_lookup(vmp, addr))) {
                printf("VM: addr 0x%lx not found.\n", m->VMUN_ADDR);
@@ -380,7 +369,6 @@ int do_get_phys(message *m)
                return EINVAL;
 
        vmp = &vmproc[n];
-       addr = arch_vir2map(vmp, addr);
 
        r = map_get_phys(vmp, addr, &ret);
 
@@ -406,7 +394,6 @@ int do_get_refcount(message *m)
                return EINVAL;
 
        vmp = &vmproc[n];
-       addr = arch_vir2map(vmp, addr);
 
        r = map_get_ref(vmp, addr, &cnt);
 
@@ -430,13 +417,10 @@ int do_munmap(message *m)
  
         vmp = &vmproc[n];
 
-       if(!(vmp->vm_flags & VMF_HASPT))
-               return ENXIO;
-
        if(m->m_type == VM_MUNMAP) {
-               addr = (vir_bytes) arch_vir2map(vmp, (vir_bytes) m->VMUM_ADDR);
+               addr = (vir_bytes) (vir_bytes) m->VMUM_ADDR;
        } else if(m->m_type == VM_MUNMAP_TEXT) {
-               addr = (vir_bytes) arch_vir2map_text(vmp, (vir_bytes) m->VMUM_ADDR);
+               addr = (vir_bytes) (vir_bytes) m->VMUM_ADDR;
        } else {
                panic("do_munmap: strange type");
        }
@@ -495,7 +479,7 @@ int minix_munmap(void *addr, size_t len)
        vir_bytes laddr;
        if(!unmap_ok)
                return ENOSYS;
-       laddr = (vir_bytes) arch_vir2map(&vmproc[VM_PROC_NR], (vir_bytes) addr);
+       laddr = (vir_bytes) (vir_bytes) addr;
        return munmap_lin(laddr, len);
 }
 
@@ -507,8 +491,7 @@ int minix_munmap_text(void *addr, size_t len)
        vir_bytes laddr;
        if(!unmap_ok)
                return ENOSYS;
-       laddr = (vir_bytes) arch_vir2map_text(&vmproc[VM_PROC_NR],
-               (vir_bytes) addr);
+       laddr = (vir_bytes) addr;
        return munmap_lin(laddr, len);
 }
 
index ed0aeae62a05f0806d0c4e78bb5b7bc758b838f4..6b2f0ebab30da7ad6e95e5f0e6edcc478ec67e77 100644 (file)
@@ -72,8 +72,8 @@ 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 %s; %s\n",
-                               ep, arch_map2str(vmp, addr), pf_errstr(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)
@@ -88,8 +88,8 @@ void do_pagefaults(message *m)
 
        /* If process was writing, see if it's writable. */
        if(!(region->flags & VR_WRITABLE) && wr) {
-               printf("VM: pagefault: SIGSEGV %d ro map 0x%lx %s\n",
-                               ep, arch_map2vir(vmp, addr), pf_errstr(err));
+               printf("VM: pagefault: SIGSEGV %d ro map 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)
@@ -203,8 +203,7 @@ int handle_memory(struct vmproc *vmp, vir_bytes mem, vir_bytes len, int wrflag)
                if(r != OK) {
 #if VERBOSE
                        printf("VM: memory range 0x%lx-0x%lx not available in %d\n",
-                               arch_map2vir(vmp, mem), arch_map2vir(vmp, mem+len),
-                               vmp->vm_endpoint);
+                               mem, mem+len, vmp->vm_endpoint);
 #endif
                        return r;
                }
index 8cc9a2e3739e03f22a7cc50d2fa322a60e95a656..01d9a7c1e25aa0f7126b5284bf596911b8497b33 100644 (file)
@@ -2,7 +2,6 @@
 
 struct vmproc;
 struct stat;
-struct mem_map;
 struct memory;
 struct vir_region;
 struct phys_region;
@@ -19,6 +18,7 @@ struct phys_region;
 #include "yielded.h"
 
 /* alloc.c */
+void mem_sanitycheck(char *file, int line);
 phys_clicks alloc_mem(phys_clicks clicks, u32_t flags);
 struct memlist *alloc_mem_in_list(phys_bytes bytes, u32_t flags);
 int do_adddma(message *msg);
@@ -38,7 +38,6 @@ void print_mem_list(struct memlist *ml);
 void mem_init(struct memory *chunks);
 
 /* utility.c */
-int get_mem_map(int proc_nr, struct mem_map *mem_map);
 void get_mem_chunks(struct memory *mem_chunks);
 void reserve_proc_mem(struct memory *mem_chunks, struct mem_map
        *map_ptr);
@@ -58,15 +57,6 @@ void free_proc(struct vmproc *vmp);
 /* fork.c */
 int do_fork(message *msg);
 
-/* exec.c */
-int do_exec_newmem(message *msg);
-int proc_new(struct vmproc *vmp, phys_bytes start, phys_bytes text_addr,
-       phys_bytes text_bytes, phys_bytes data_addr, phys_bytes data_bytes,
-       phys_bytes stack, phys_bytes gap, phys_bytes text_here, phys_bytes
-       data_here, vir_bytes stacktop, int prealloc_stack, int is_elf, int full);
-phys_bytes find_kernel_top(void);
-void regular_segs(struct vmproc *);
-
 /* break.c */
 int do_brk(message *msg);
 int adjust(struct vmproc *rmp, vir_clicks data_clicks, vir_bytes sp);
@@ -99,7 +89,7 @@ int handle_memory(struct vmproc *vmp, vir_bytes mem, vir_bytes len, int
        wrflag);
 
 /* $(ARCH)/pagetable.c */
-void pt_init(phys_bytes limit);
+void pt_init();
 void pt_init_mem(void);
 void pt_check(struct vmproc *vmp);
 int pt_new(pt_t *pt);
@@ -192,15 +182,6 @@ int do_forgetblock(message *m);
 int do_yieldblockgetblock(message *m);
 vir_bytes free_yielded(vir_bytes bytes);
 
-/* $(ARCH)/vm.c */
-vir_bytes arch_map2vir(struct vmproc *vmp, vir_bytes addr);
-char *arch_map2str(struct vmproc *vmp, vir_bytes addr);
-vir_bytes arch_map2info(struct vmproc *vmp, vir_bytes addr, int *space,
-       int *prot);
-vir_bytes arch_vir2map(struct vmproc *vmp, vir_bytes addr);
-vir_bytes arch_vir2map_text(struct vmproc *vmp, vir_bytes addr);
-vir_bytes arch_addrok(struct vmproc *vmp, vir_bytes addr);
-
 /* rs.c */
 int do_rs_set_priv(message *m);
 int do_rs_update(message *m);
index e315107298912a14f5f30082cc6ddc7a834fac55..a7edf146438c0da4abfddb40abbeb61981573d13 100644 (file)
@@ -133,14 +133,13 @@ void map_printregion(struct vmproc *vmp, struct vir_region *vr)
        physr_iter iter;
        struct phys_region *ph;
        printf("map_printmap: map_name: %s\n", map_name(vr));
-       printf("\t%s (len 0x%lx, %lukB), %s\n",
-               arch_map2str(vmp, vr->vaddr), vr->length,
-                       vr->length/1024, map_name(vr));
+       printf("\t%lx (len 0x%lx, %lukB), %p\n",
+               vr->vaddr, vr->length, vr->length/1024, map_name(vr));
        printf("\t\tphysblocks:\n");
        physr_start_iter_least(vr->phys, &iter);
        while((ph = physr_get_iter(&iter))) {
-               printf("\t\t@ %s (refs %d): phys 0x%lx len 0x%lx\n",
-                       arch_map2str(vmp, vr->vaddr + ph->offset),
+               printf("\t\t@ %lx (refs %d): phys 0x%lx len 0x%lx\n",
+                       (vr->vaddr + ph->offset),
                        ph->ph->refcount, ph->ph->phys, ph->ph->length);
                physr_incr_iter(&iter);
        }
@@ -194,9 +193,6 @@ static int map_sanitycheck_pt(struct vmproc *vmp,
        int rw;
        int r;
 
-       if(!(vmp->vm_flags & VMF_HASPT))
-               return OK;
-
        if(WRITABLE(vr, pb))
                rw = PTF_WRITE;
        else
@@ -406,7 +402,7 @@ static int map_ph_writept(struct vmproc *vmp, struct vir_region *vr,
 static vir_bytes region_find_slot_range(struct vmproc *vmp,
                vir_bytes minv, vir_bytes maxv, vir_bytes length)
 {
-       struct vir_region *firstregion;
+       struct vir_region *lastregion;
        vir_bytes startv = 0;
        int foundflag = 0;
        region_iter iter;
@@ -439,40 +435,50 @@ static vir_bytes region_find_slot_range(struct vmproc *vmp,
        assert(minv < maxv);
        assert(minv + length <= maxv);
 
-#define FREEVRANGE(rangestart, rangeend) {             \
+#define FREEVRANGE_TRY(rangestart, rangeend) {         \
        vir_bytes frstart = (rangestart), frend = (rangeend);   \
        frstart = MAX(frstart, minv);                           \
        frend   = MIN(frend, maxv);                             \
        if(frend > frstart && (frend - frstart) >= length) {    \
-               startv = frstart;                               \
+               startv = frend-length;                          \
                foundflag = 1;                                  \
        } }
 
-       /* find region before minv. */
-       region_start_iter(&vmp->vm_regions_avl, &iter, minv, AVL_LESS_EQUAL);
-       firstregion = region_get_iter(&iter);
+#define FREEVRANGE(start, end) {                                       \
+       assert(!foundflag);                                             \
+       FREEVRANGE_TRY(((start)+VM_PAGE_SIZE), ((end)-VM_PAGE_SIZE));   \
+       if(!foundflag) {                                                \
+               FREEVRANGE_TRY((start), (end));                         \
+       }                                                               \
+}
 
-       if(!firstregion) {
-               /* This is the free virtual address space before the first region. */
-               region_start_iter(&vmp->vm_regions_avl, &iter, minv, AVL_GREATER_EQUAL);
-               firstregion = region_get_iter(&iter);
-               FREEVRANGE(0, firstregion ? firstregion->vaddr : VM_DATATOP);
+       /* find region after maxv. */
+       region_start_iter(&vmp->vm_regions_avl, &iter, maxv, AVL_GREATER_EQUAL);
+       lastregion = region_get_iter(&iter);
+
+       if(!lastregion) {
+               /* This is the free virtual address space after the last region. */
+               region_start_iter(&vmp->vm_regions_avl, &iter, maxv, AVL_LESS);
+               lastregion = region_get_iter(&iter);
+               FREEVRANGE(lastregion ?
+                       lastregion->vaddr+lastregion->length : 0, VM_DATATOP);
        }
 
        if(!foundflag) {
                struct vir_region *vr;
                while((vr = region_get_iter(&iter)) && !foundflag) {
                        struct vir_region *nextvr;
-                       region_incr_iter(&iter);
+                       region_decr_iter(&iter);
                        nextvr = region_get_iter(&iter);
-                       FREEVRANGE(vr->vaddr + vr->length,
-                         nextvr ? nextvr->vaddr : VM_DATATOP);
+                       FREEVRANGE(nextvr ? nextvr->vaddr+nextvr->length : 0,
+                         vr->vaddr);
                }
        }
 
        if(!foundflag) {
                printf("VM: region_find_slot: no 0x%lx bytes found for %d between 0x%lx and 0x%lx\n",
                        length, vmp->vm_endpoint, minv, maxv);
+               util_stacktrace();
                return SLOT_FAIL;
        }
 
@@ -500,7 +506,7 @@ static vir_bytes region_find_slot(struct vmproc *vmp,
         */
 
        if(maxv && hint < maxv && hint >= minv) {
-               v = region_find_slot_range(vmp, hint, maxv, length);
+               v = region_find_slot_range(vmp, minv, hint, length);
 
                if(v != SLOT_FAIL)
                        return v;
@@ -530,6 +536,11 @@ int mapflags;
 
        SANITYCHECK(SCL_FUNCTIONS);
 
+       if((flags & VR_CONTIG) && !(mapflags & MF_PREALLOC)) {
+               printf("map_page_region: can't make contiguous allocation without preallocating\n");
+               return NULL;
+       }
+
        startv = region_find_slot(vmp, minv, maxv, length);
        if (startv == SLOT_FAIL)
                return NULL;
@@ -977,7 +988,10 @@ int written;
 
        if((region->flags & VR_CONTIG) &&
                (start_offset > 0 || length < region->length)) {
-               printf("VM: map_new_physblock: non-full allocation requested\n");
+               printf("VM: region length 0x%lx, offset 0x%lx length 0x%lx\n",
+                       region->length, start_offset, length);
+               map_printmap(vmp);
+               printf("VM: map_new_physblock: non-full contig allocation requested\n");
                return EFAULT;
        }
 
@@ -1379,8 +1393,8 @@ int write;
 
 #if SANITYCHECKS
        if(OK != pt_checkrange(&vmp->vm_pt, region->vaddr+offset, length, write)) {
-               printf("handle mem %s-", arch_map2str(vmp, region->vaddr+offset));
-               printf("%s failed\n", arch_map2str(vmp, region->vaddr+offset+length));
+               printf("handle mem 0x%lx-0x%lx failed\n",
+                       region->vaddr+offset,region->vaddr+offset+length);
                map_printregion(vmp, region);
                panic("checkrange failed");
        }
@@ -1647,46 +1661,13 @@ struct vir_region *start_src_vr;
        return OK;
 }
 
-/*========================================================================*
- *                             map_proc_kernel                         *
- *========================================================================*/
-struct vir_region *map_proc_kernel(struct vmproc *vmp)
-{
-       struct vir_region *vr;
-
-       /* We assume these are the first regions to be mapped to
-        * make the function a bit simpler (free all regions on error).
-        */
-       assert(!region_search_root(&vmp->vm_regions_avl));
-       assert(vmproc[VMP_SYSTEM].vm_flags & VMF_INUSE);
-       assert(!(KERNEL_TEXT % VM_PAGE_SIZE));
-       assert(!(KERNEL_TEXT_LEN % VM_PAGE_SIZE));
-       assert(!(KERNEL_DATA % VM_PAGE_SIZE));
-       assert(!(KERNEL_DATA_LEN % VM_PAGE_SIZE));
-
-       if(!(vr = map_page_region(vmp, KERNEL_TEXT, 0, KERNEL_TEXT_LEN, 
-               KERNEL_TEXT, VR_DIRECT | VR_WRITABLE | VR_NOPF, 0)) ||
-          !(vr = map_page_region(vmp, KERNEL_DATA, 0, KERNEL_DATA_LEN, 
-               KERNEL_DATA, VR_DIRECT | VR_WRITABLE | VR_NOPF, 0))) {
-               map_free_proc(vmp);
-               return NULL;
-       }
-
-       return vr; /* Return pointer not useful, just non-NULL. */
-}
-
 int map_region_extend_upto_v(struct vmproc *vmp, vir_bytes v)
 {
-       vir_bytes offset, o, end;
+       vir_bytes offset = v, end;
        struct vir_region *vr, *nextvr;
+       int r = OK;
 
-       offset = arch_vir2map(vmp, v);
-
-       if((o=(offset % VM_PAGE_SIZE))) {
-               offset+= VM_PAGE_SIZE - o;
-       }
-
-       if(!(vr = region_search(&vmp->vm_regions_avl, offset, AVL_LESS_EQUAL))) {
+       if(!(vr = region_search(&vmp->vm_regions_avl, offset, AVL_LESS))) {
                printf("VM: nothing to extend\n");
                return ENOMEM;
        }
@@ -1698,17 +1679,17 @@ int map_region_extend_upto_v(struct vmproc *vmp, vir_bytes v)
 
        assert(vr->vaddr <= offset);
        if((nextvr = getnextvr(vr))) {
-               assert(offset < nextvr->vaddr);
+               assert(offset <= nextvr->vaddr);
        }
 
        end = vr->vaddr + vr->length;
 
-       if(offset < end)
-               return map_region_shrink(vr, end - offset);
+       offset = roundup(offset, VM_PAGE_SIZE);
 
-       return map_region_extend(vmp, vr, offset - end);
+       if(end < offset)
+               r = map_region_extend(vmp, vr, offset - end);
 
-       return ENOMEM;
+       return r;
 }
 
 /*========================================================================*
@@ -1723,6 +1704,10 @@ int map_region_extend(struct vmproc *vmp, struct vir_region *vr,
        assert(vr);
        assert(vr->flags & VR_ANON);
        assert(!(delta % VM_PAGE_SIZE));
+       if(vr->flags & VR_CONTIG) {
+               printf("VM: can't grow contig region\n");
+               return EFAULT;
+       }
 
        if(!delta) return OK;
        end = vr->vaddr + vr->length;
@@ -1868,10 +1853,9 @@ int map_remap(struct vmproc *dvmp, vir_bytes da, size_t size,
 
        /* da is handled differently */
        if (!da)
-               dst_addr = dvmp->vm_stacktop;
+               dst_addr = 0;
        else
                dst_addr = da;
-       dst_addr = arch_vir2map(dvmp, dst_addr);
 
        /* round up to page size */
        assert(!(size % VM_PAGE_SIZE));
@@ -2054,8 +2038,8 @@ int get_region_info(struct vmproc *vmp, struct vm_region_info *vri,
                if(!ph1 || !ph2) { assert(!ph1 && !ph2); continue; }
 
                /* Report start+length of region starting from lowest use. */
-               vri->vri_addr = arch_map2info(vmp, vr->vaddr + ph1->offset,
-                       &vri->vri_seg, &vri->vri_prot);
+               vri->vri_addr = vr->vaddr + ph1->offset;
+               vri->vri_prot = 0;
                vri->vri_length = ph2->offset + ph2->ph->length - ph1->offset;
 
                /* "AND" the provided protection with per-page protection. */
@@ -2434,7 +2418,7 @@ get_clean_phys_region(struct vmproc *vmp, vir_bytes vaddr, vir_bytes length,
        vir_bytes regionoffset, mapaddr;
        struct phys_region *ph;
 
-       mapaddr = arch_vir2map(vmp, vaddr);
+       mapaddr = vaddr;
 
         if(!(region = map_lookup(vmp, mapaddr))) {
                printf("VM: get_clean_phys_region: 0x%lx not found\n", vaddr);
@@ -2638,11 +2622,6 @@ int do_forgetblocks(message *m)
 
        vmp = &vmproc[n];
 
-       if(!(vmp->vm_flags & VMF_HASPT)) {
-               printf("do_forgetblocks: no pt\n");
-               return EFAULT;
-       }
-
        free_yielded_proc(vmp);
 
        return OK;
@@ -2667,11 +2646,6 @@ int do_forgetblock(message *m)
 
        vmp = &vmproc[n];
 
-       if(!(vmp->vm_flags & VMF_HASPT)) {
-               printf("do_forgetblock: no pt\n");
-               return EFAULT;
-       }
-
        id = make64(m->VMFB_IDLO, m->VMFB_IDHI);
 
        blockid.id = id;
@@ -2703,11 +2677,6 @@ int do_yieldblockgetblock(message *m)
 
        vmp = &vmproc[n];
 
-       if(!(vmp->vm_flags & VMF_HASPT)) {
-               printf("do_yieldblockgetblock: no pt\n");
-               return EFAULT;
-       }
-
        len = m->VMYBGB_LEN;
 
        if((len % VM_PAGE_SIZE)) {
index 6a126483af0b46c5cd92649737c6bb59b8f8b80c..e41e80d174a945c42aaf835bf63f31cf0d8cd201 100644 (file)
@@ -124,10 +124,6 @@ static int rs_memctl_make_vm_instance(struct vmproc *new_vm_vmp)
 
        this_vm_vmp = &vmproc[VM_PROC_NR];
 
-       /* Copy settings from current VM. */
-       new_vm_vmp->vm_stacktop = this_vm_vmp->vm_stacktop;
-       new_vm_vmp->vm_arch.vm_data_top = this_vm_vmp->vm_arch.vm_data_top;
-
        /* Pin memory for the new VM instance. */
        r = map_pin_memory(new_vm_vmp);
        if(r != OK) {
index 60c8a1eb66cc493ff2bb70db1d283377d65bc94e..a3f7d7fd20e0ade58a5a530de8c19f0c6e15b5a3 100644 (file)
                usedpages_reset();      \
        slab_sanitycheck(__FILE__, __LINE__);   \
        for(vmpr = vmproc; vmpr < &vmproc[VMP_NR]; vmpr++) { \
-               if((vmpr->vm_flags & (VMF_INUSE | VMF_HASPT)) == \
-                       (VMF_INUSE | VMF_HASPT)) { \
+               if((vmpr->vm_flags & (VMF_INUSE))) { \
                        PT_SANE(&vmpr->vm_pt); \
                } \
        } \
        map_sanitycheck(__FILE__, __LINE__); \
+       mem_sanitycheck(__FILE__, __LINE__); \
        assert(incheck == 1);   \
        incheck = 0;            \
+       /* printf("(%s:%d OK) ", __FILE__, __LINE__); */ \
        } 
 
 #define SLABSANE(ptr) { \
index fecb86ee29498823ae5a12a5b34698d9ded7e799..1711a318c90837ee7a17ee8b0f95e57f7601dd5f 100644 (file)
@@ -552,7 +552,7 @@ void slabunlock(void *mem, int bytes)
  *===========================================================================*/
 void slabstats(void)
 {
-       int s, total = 0, totalbytes = 0;
+       int s, totalbytes = 0;
        static int n;
        n++;
        if(n%1000) return;
index 691d1807d691770214f166d7636dc0cfbc1a1870..a02a38ee5cafe8b33a74d3e534028379e382b30c 100644 (file)
 #include "kernel/type.h"
 #include "kernel/proc.h"
 
-/*===========================================================================*
- *                              get_mem_map                                  *
- *===========================================================================*/
-int get_mem_map(proc_nr, mem_map)
-int proc_nr;                                    /* process to get map of */
-struct mem_map *mem_map;                        /* put memory map here */
-{
-       struct proc p;
-       int s;
-
-       if ((s=sys_getproc(&p, proc_nr)) != OK)
-               return(s);
-
-       memcpy(mem_map, p.p_memmap, sizeof(p.p_memmap));
-       return(OK);
-}
-
 /*===========================================================================*
  *                              get_mem_chunks                               *
  *===========================================================================*/
@@ -89,6 +72,7 @@ struct memory *mem_chunks;                      /* store mem chunks here */
   }
 }  
 
+#if 0
 /*===========================================================================*
  *                              reserve_proc_mem                             *
  *===========================================================================*/
@@ -135,6 +119,7 @@ struct mem_map *map_ptr;                        /* memory to remove */
                        map_ptr[T].mem_phys);
   }
 } 
+#endif
 
 /*===========================================================================*
  *                              vm_isokendpt                                        *
@@ -243,7 +228,7 @@ int do_info(message *m)
         * deadlock. Note that no memory mapping can be undone without the
         * involvement of VM, so we are safe until we're done.
         */
-       r = handle_memory(vmp, arch_vir2map(vmp, ptr), size, 1 /*wrflag*/);
+       r = handle_memory(vmp, ptr, size, 1 /*wrflag*/);
        if (r != OK) return r;
 
        /* Now that we know the copy out will succeed, perform the actual copy
@@ -305,9 +290,7 @@ int swap_proc_dyn_data(struct vmproc *src_vmp, struct vmproc *dst_vmp)
                printf("VM: swap_proc_dyn_data: tranferring regions above the stack from old VM (%d) to new VM (%d)\n",
                        src_vmp->vm_endpoint, dst_vmp->vm_endpoint);
 #endif
-               assert(src_vmp->vm_stacktop == dst_vmp->vm_stacktop);
-               r = pt_map_in_range(src_vmp, dst_vmp,
-                       arch_vir2map(src_vmp, src_vmp->vm_stacktop), 0);
+               r = pt_map_in_range(src_vmp, dst_vmp, VM_STACKTOP, 0);
                if(r != OK) {
                        printf("swap_proc_dyn_data: pt_map_in_range failed\n");
                        return r;
@@ -329,15 +312,14 @@ int swap_proc_dyn_data(struct vmproc *src_vmp, struct vmproc *dst_vmp)
         * new instance and prevent state corruption on rollback, we share all
         * the regions between the two instances as COW.
         */
-       if(!is_vm && (dst_vmp->vm_flags & VMF_HASPT)) {
+       if(!is_vm) {
                struct vir_region *vr;
-               vr = map_lookup(dst_vmp, arch_vir2map(dst_vmp, dst_vmp->vm_stacktop));
-               if(vr && !map_lookup(src_vmp, arch_vir2map(src_vmp, src_vmp->vm_stacktop))) {
+               vr = map_lookup(dst_vmp, VM_STACKTOP);
+               if(vr && !map_lookup(src_vmp, VM_STACKTOP)) {
 #if LU_DEBUG
                        printf("VM: swap_proc_dyn_data: tranferring regions above the stack from %d to %d\n",
                                src_vmp->vm_endpoint, dst_vmp->vm_endpoint);
 #endif
-                       assert(src_vmp->vm_stacktop == dst_vmp->vm_stacktop);
                        r = map_proc_copy_from(src_vmp, dst_vmp, vr);
                        if(r != OK) {
                                return r;
index 8dd0ed62e90b4c86e89bc7739a1aa3f3ddb5e1a8..b2ee8fd6f4cc59b6e05da5d9137c19765941c2b0 100644 (file)
@@ -3,7 +3,6 @@
 #define _VMPROC_H 1
 
 #include <pagetable.h>
-#include <arch_vmproc.h>
 #include <minix/bitmap.h>
 #include <machine/archtypes.h>
 
@@ -17,25 +16,15 @@ struct vmproc;
 typedef void (*callback_t)(struct vmproc *who, message *m);
 
 struct vmproc {
-       struct vm_arch  vm_arch; /* architecture-specific data */
        int             vm_flags;
        endpoint_t      vm_endpoint;
-       pt_t            vm_pt;  /* page table data, if VMF_HASPT is set */
-       vir_bytes       vm_stacktop;    /* top of stack as seen from process */
-       vir_bytes       vm_offset;      /* offset of addr 0 for process */
-
-       /* File identification for cs sharing. */
-       ino_t vm_ino;           /* inode number of file */
-       dev_t vm_dev;           /* device number of file system */
-       time_t vm_ctime;        /* inode changed time */
+       pt_t            vm_pt;  /* page table data */
+       struct boot_image *vm_boot; /* if boot time process */
 
        /* Regions in virtual address space. */
        region_avl vm_regions_avl;
        vir_bytes  vm_region_top;       /* highest vaddr last inserted */
 
-       /* Heap for brk() to extend. */
-       struct vir_region *vm_heap;
-
        bitchunk_t vm_call_mask[VM_CALL_MASK_SIZE];
 
        /* State for requests pending to be done to vfs on behalf of
@@ -59,12 +48,10 @@ struct vmproc {
 
 /* Bits for vm_flags */
 #define VMF_INUSE      0x001   /* slot contains a process */
-#define VMF_SEPARATE   0x002   /* separate i&d */
-#define VMF_HASPT      0x004   /* has private page table */
-#define VMF_EXITING    0x008   /* PM is cleaning up this process */
-#define VMF_HAS_DMA    0x010   /* Process directly or indirectly granted
+#define VMF_EXITING    0x002   /* PM is cleaning up this process */
+#define VMF_HAS_DMA    0x004   /* Process directly or indirectly granted
                                 * DMA buffers.
                                 */
-#define VMF_WATCHEXIT  0x020   /* Store in queryexit table */
+#define VMF_WATCHEXIT  0x008   /* Store in queryexit table */
 
 #endif
index 0fe175f7c403dd98225e61f5c6c77e05f1d6d529..4926f04b30ee36d4decb2d31aa819d6efa95dfc6 100644 (file)
@@ -59,7 +59,8 @@ MKDEP_SUFFIXES?=      .o .ln
 #      rumpfs_tmpfs rumpfs_udf rumpfs_ufs
 .for _lib in \
        c curses blockdriver chardriver netdriver edit end m sys timers util \
-       bz2 l audiodriver exec ddekit devman usb elf bdev sffs hgfs vboxfs
+       bz2 l audiodriver exec ddekit devman usb elf bdev sffs hgfs vboxfs \
+       minc minlib
 .ifndef LIB${_lib:tu}
 LIB${_lib:tu}= ${DESTDIR}/usr/lib/lib${_lib}.a
 .MADE:         ${LIB${_lib:tu}}        # Note: ${DESTDIR} will be expanded
index 654b0e8ce6fdba2538370efee2a3f94638319a5f..36f7397b2e673ab2d0862ba7b812d2531894c488 100644 (file)
@@ -1,6 +1,4 @@
 # MINIX-specific boot program options
 .include <bsd.own.mk>
 
-LDFLAGS+= -Wl,--section-start=.init=0x0
-
 .include <minix.service.mk>
index 29b4e90423ad69b55cfd0134ecb77b257f3d62b1..73183dc344dd768441390862e744c0a5794971fc 100644 (file)
@@ -11,6 +11,6 @@ SUBDIR= login indent m4 make mktemp stat tic sed mkdep uniq seq du man \
 SUBDIR+= ministat
 
 # Minix commands
-SUBDIR+= top mkimage
+SUBDIR+= top 
 
 .include <bsd.subdir.mk>
diff --git a/usr.bin/mkimage/Makefile b/usr.bin/mkimage/Makefile
deleted file mode 100644 (file)
index 622d5c9..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-PROG=  mkimage
-SRCS=  mkimage.c
-MAN=
-
-DPADD+=        ${LIBELF}
-LDADD+=        -lelf
-
-.include <bsd.prog.mk>
diff --git a/usr.bin/mkimage/mkimage.c b/usr.bin/mkimage/mkimage.c
deleted file mode 100644 (file)
index 0228ed2..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Update physical addresses of boot services
- */
-
-#include <sys/param.h>
-
-#include <err.h>
-#include <fcntl.h>
-
-#include <gelf.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sysexits.h>
-#include <unistd.h>
-#include <getopt.h>
-
-#define BOOTPROG_LOAD_START 0x01000000ULL
-
-int nflag = 0;
-
-int stack_kbytes[] = {
-    /*  ds  rs    pm  sched  vfs  memory  log  tty  mfs  vm   pfs  init */
-       16, 8125, 32, 32, 16, 8, 32, 16, 128, 128, 128, 64
-};
-
-static void usage(void);
-
-GElf_Addr
-update_paddr(int nr, char *fname, GElf_Addr startaddr)
-{
-       int i, fd;
-       Elf *e;
-       size_t n;
-
-       GElf_Phdr phdr;
-       GElf_Addr endaddr = 0;
-
-       if ((fd = open(fname, O_RDWR, 0)) < 0)
-               err(EX_NOINPUT, "open \"%s\" failed", fname);
-
-       if ((e = elf_begin(fd, ELF_C_RDWR, NULL)) == NULL)
-               errx(EX_SOFTWARE, "elf_begin() failed: %s.", elf_errmsg(-1));
-
-       if (elf_kind(e) != ELF_K_ELF)
-               errx(EX_DATAERR, "\"%s\" is not an ELF object.", fname);
-
-       if (elf_getphdrnum(e, &n) != 0)
-               errx(EX_DATAERR, "elf_getphdrnum() failed: %s.", elf_errmsg(-1));
-
-       for (i = 0; i < n; i++) {
-               if (gelf_getphdr(e, i, &phdr) != &phdr)
-                       errx(EX_SOFTWARE, "getphdr() failed: %s.",
-                           elf_errmsg(-1));
-
-               if (phdr.p_type == PT_LOAD) {
-                       phdr.p_paddr = startaddr + phdr.p_vaddr;
-
-                       endaddr = round_page(phdr.p_paddr + phdr.p_memsz)
-                           + round_page(stack_kbytes[nr] * 1024);
-
-                       if (gelf_update_phdr(e, i, &phdr) < 0)
-                               errx(EX_SOFTWARE,
-                                   "gelf_update_phdr failed: %s.",
-                                   elf_errmsg(-1));
-               }
-
-       }
-
-       if (elf_update(e, ELF_C_WRITE) < 0)
-               errx(EX_SOFTWARE, "elf_update failed: %s.", elf_errmsg(-1));
-
-       (void) elf_end(e);
-       (void) close(fd);
-
-       return endaddr;
-
-}
-
-int
-main(int argc, char **argv)
-{
-       int i, ch;
-       GElf_Addr startaddr;
-
-       startaddr = BOOTPROG_LOAD_START;
-
-       while ((ch = getopt(argc, argv, "n")) != -1) {
-               switch (ch) {
-               case 'n':
-                       nflag = 1;
-                       break;
-               case '?':
-               default:
-                       usage();
-                       exit(EX_USAGE);
-               }
-       }
-       argc -= optind;
-       argv += optind;
-
-       if (argc < 1)
-               usage();
-
-       if (elf_version(EV_CURRENT) == EV_NONE)
-               errx(EX_SOFTWARE, "ELF library intialization failed: %s",
-                   elf_errmsg(-1));
-
-       startaddr = BOOTPROG_LOAD_START;
-       for (i = 0; i < argc; i++) {
-               startaddr = update_paddr(i, argv[i], startaddr);
-       }
-
-       exit(EX_OK);
-}
-
-static void
-usage(void)
-{
-       (void) fprintf(stderr, "usage: %s [-n] elf1 elf2...\n", getprogname());
-}