PUBLIC void vm_init(struct proc *newptproc) { if(vm_running) minix_panic("vm_init: vm_running", NO_NUM); vm_set_cr3(newptproc); level0(vm_enable_paging); vm_running = 1; }
PUBLIC void vm_set_cr3(struct proc *newptproc) { int u = 0; if(!intr_disabled()) { lock; u = 1; } vm_cr3= newptproc->p_seg.p_cr3; if(vm_cr3) { level0(set_cr3); ptproc = newptproc; } if(u) { unlock; } }
PUBLIC void vm_init(void) { int o; phys_bytes p, pt_size; phys_bytes vm_dir_base, vm_pt_base, phys_mem; u32_t entry; unsigned pages; struct proc* rp; struct proc *sys = proc_addr(SYSTEM); static int init_done = 0; if (!vm_size) minix_panic("i386_vm_init: no space for page tables", NO_NUM); if(init_done) return; /* Align page directory */ o= (vm_base % I386_PAGE_SIZE); if (o != 0) o= I386_PAGE_SIZE-o; vm_dir_base= vm_base+o; /* Page tables start after the page directory */ vm_pt_base= vm_dir_base+I386_PAGE_SIZE; pt_size= (vm_base+vm_size)-vm_pt_base; pt_size -= (pt_size % I386_PAGE_SIZE); /* Compute the number of pages based on vm_mem_high */ pages= (vm_mem_high-1)/I386_PAGE_SIZE + 1; if (pages * I386_VM_PT_ENT_SIZE > pt_size) minix_panic("i386_vm_init: page table too small", NO_NUM); for (p= 0; p*I386_VM_PT_ENT_SIZE < pt_size; p++) { phys_mem= p*I386_PAGE_SIZE; entry= phys_mem | I386_VM_USER | I386_VM_WRITE | I386_VM_PRESENT; if (phys_mem >= vm_mem_high) entry= 0; #if VM_KERN_NOPAGEZERO if (phys_mem == (sys->p_memmap[T].mem_phys << CLICK_SHIFT) || phys_mem == (sys->p_memmap[D].mem_phys << CLICK_SHIFT)) { entry = 0; } #endif phys_put32(vm_pt_base + p*I386_VM_PT_ENT_SIZE, entry); } for (p= 0; p < I386_VM_DIR_ENTRIES; p++) { phys_mem= vm_pt_base + p*I386_PAGE_SIZE; entry= phys_mem | I386_VM_USER | I386_VM_WRITE | I386_VM_PRESENT; if (phys_mem >= vm_pt_base + pt_size) entry= 0; phys_put32(vm_dir_base + p*I386_VM_PT_ENT_SIZE, entry); } /* Set this cr3 in all currently running processes for * future context switches. */ for (rp=BEG_PROC_ADDR; rp<END_PROC_ADDR; rp++) { u32_t mycr3; if(isemptyp(rp)) continue; rp->p_seg.p_cr3 = vm_dir_base; } kernel_cr3 = vm_dir_base; /* Set this cr3 now (not active until paging enabled). */ vm_set_cr3(vm_dir_base); /* Actually enable paging (activating cr3 load above). */ level0(vm_enable_paging); /* Don't do this init in the future. */ init_done = 1; vm_running = 1; }