From: Peter H. Froehlich Date: Fri, 16 Oct 2015 21:41:17 +0000 (-0400) Subject: Small changes related to memlayout.h primarily. X-Git-Url: https://hydra-www.ietfng.org/gitweb/?a=commitdiff_plain;h=55543c55679695705f89bab7cd8ddea7924f1e7b;p=xv6-public Small changes related to memlayout.h primarily. Resolved v2p/p2v/V2P/P2V duplication, minimized memlayout.h use, clarified entry.S "indirect jump" confusion, nits. --- diff --git a/bootasm.S b/bootasm.S index 91a595e..d84d4ab 100644 --- a/bootasm.S +++ b/bootasm.S @@ -1,5 +1,4 @@ #include "asm.h" -#include "memlayout.h" #include "mmu.h" # Start the first CPU: switch to 32-bit protected mode, jump into C. @@ -18,7 +17,7 @@ start: movw %ax,%es # -> Extra Segment movw %ax,%ss # -> Stack Segment - # Physical address line A20 is tied to zero so that the first PCs + # Physical address line A20 is tied to zero so that the first PCs # with 2 MB would run software that assumed 1 MB. Undo that. seta20.1: inb $0x64,%al # Wait for not busy diff --git a/bootmain.c b/bootmain.c index 6c6f080..3d3603d 100644 --- a/bootmain.c +++ b/bootmain.c @@ -8,7 +8,6 @@ #include "types.h" #include "elf.h" #include "x86.h" -#include "memlayout.h" #include "ide.h" void readseg(uchar*, uint, uint); diff --git a/entry.S b/entry.S index 5f4e124..5017a49 100644 --- a/entry.S +++ b/entry.S @@ -52,13 +52,13 @@ entry: movl %eax, %cr0 # Set up the stack pointer. - movl $(stack + KSTACKSIZE), %esp + movl $(stack + KSTACKSIZE), %esp - # Jump to main(), and switch to executing at - # high addresses. The indirect call is needed because - # the assembler produces a PC-relative instruction - # for a direct jump. - mov $main, %eax - jmp *%eax + # Jump to main() and switch to executing at high addresses. + # Need an explicit long jump (indirect jump would work as + # well, as would a push/ret trick to save 1 byte) because + # the assembler produces a PC-relative instruction for a + # direct jump. + ljmp $(SEG_KCODE<<3), $main .comm stack, KSTACKSIZE diff --git a/entryother.S b/entryother.S index 9f94cd3..a745a41 100644 --- a/entryother.S +++ b/entryother.S @@ -1,7 +1,6 @@ #include "asm.h" -#include "memlayout.h" #include "mmu.h" - + # Each non-boot CPU ("AP") is started up in response to a STARTUP # IPI from the boot CPU. Section B.4.2 of the Multi-Processor # Specification says that the AP will start in real mode with CS:IP @@ -21,10 +20,10 @@ # - it does not need to enable A20 # - it uses the address at start-4, start-8, and start-12 -.code16 +.code16 .globl start start: - cli + cli xorw %ax,%ax movw %ax,%ds @@ -37,7 +36,7 @@ start: movl %eax, %cr0 //PAGEBREAK! - ljmpl $(SEG_KCODE<<3), $(start32) + ljmp $(SEG_KCODE<<3), $start32 .code32 start32: @@ -58,13 +57,13 @@ start32: movl %eax, %cr3 # Turn on paging. movl %cr0, %eax - orl $(CR0_PE|CR0_PG|CR0_WP), %eax + orl $(CR0_PG|CR0_WP), %eax movl %eax, %cr0 # Switch to the stack allocated by startothers() movl (start-4), %esp # Call mpenter() - call *(start-8) + call *(start-8) movw $0x8a00, %ax movw %ax, %dx @@ -80,7 +79,6 @@ gdt: SEG_ASM(STA_X|STA_R, 0, 0xffffffff) SEG_ASM(STA_W, 0, 0xffffffff) - gdtdesc: .word (gdtdesc - gdt - 1) .long gdt diff --git a/exec.c b/exec.c index 8dbbdb6..0d4ac4f 100644 --- a/exec.c +++ b/exec.c @@ -1,6 +1,5 @@ #include "types.h" #include "param.h" -#include "memlayout.h" #include "mmu.h" #include "proc.h" #include "defs.h" diff --git a/ide.c b/ide.c index b713433..e904e61 100644 --- a/ide.c +++ b/ide.c @@ -3,7 +3,6 @@ #include "types.h" #include "defs.h" #include "param.h" -#include "memlayout.h" #include "mmu.h" #include "proc.h" #include "x86.h" diff --git a/kalloc.c b/kalloc.c index 417c20f..ca30d55 100644 --- a/kalloc.c +++ b/kalloc.c @@ -61,7 +61,7 @@ kfree(char *v) { struct run *r; - if((uint)v % PGSIZE || v < end || v2p(v) >= PHYSTOP) + if((uint)v % PGSIZE || v < end || V2P(v) >= PHYSTOP) panic("kfree"); // Fill with junk to catch dangling refs. diff --git a/main.c b/main.c index 40facc4..c958e51 100644 --- a/main.c +++ b/main.c @@ -8,7 +8,6 @@ static void startothers(void); static void mpmain(void) __attribute__((noreturn)); -extern pde_t *kpgdir; extern char end[]; // first address after kernel loaded from ELF file // Bootstrap processor starts running C code here. @@ -45,7 +44,7 @@ main(void) static void mpenter(void) { - switchkvm(); + switchkvm(); seginit(); lapicinit(); mpmain(); @@ -75,22 +74,22 @@ startothers(void) // Write entry code to unused memory at 0x7000. // The linker has placed the image of entryother.S in // _binary_entryother_start. - code = p2v(0x7000); + code = P2V(0x7000); memmove(code, _binary_entryother_start, (uint)_binary_entryother_size); for(c = cpus; c < cpus+ncpu; c++){ if(c == cpus+cpunum()) // We've started already. continue; - // Tell entryother.S what stack to use, where to enter, and what + // Tell entryother.S what stack to use, where to enter, and what // pgdir to use. We cannot use kpgdir yet, because the AP processor // is running in low memory, so we use entrypgdir for the APs too. stack = kalloc(); *(void**)(code-4) = stack + KSTACKSIZE; *(void**)(code-8) = mpenter; - *(int**)(code-12) = (void *) v2p(entrypgdir); + *(int**)(code-12) = (void *) V2P(entrypgdir); - lapicstartap(c->id, v2p(code)); + lapicstartap(c->id, V2P(code)); // wait for cpu to finish mpmain() while(c->started == 0) @@ -100,7 +99,7 @@ startothers(void) // Boot page table used in entry.S and entryother.S. // Page directories (and page tables), must start on a page boundary, -// hence the "__aligned__" attribute. +// hence the "__aligned__" attribute. // Use PTE_PS in page directory entry to enable 4Mbyte pages. __attribute__((__aligned__(PGSIZE))) pde_t entrypgdir[NPDENTRIES] = { diff --git a/memlayout.h b/memlayout.h index 6a62cd7..e5093fb 100644 --- a/memlayout.h +++ b/memlayout.h @@ -1,7 +1,7 @@ // Memory layout -#define EXTMEM 0x100000 // Start of extended memory -#define PHYSTOP 0xE000000 // Top physical memory +#define EXTMEM 0x100000 // Start of extended memory, 1 MB +#define PHYSTOP 0xE000000 // Top physical memory, 224 MB #define DEVSPACE 0xFE000000 // Other devices are at high addresses // Key addresses for address space layout (see kmap in vm.c for layout) @@ -10,13 +10,14 @@ #ifndef __ASSEMBLER__ -static inline uint v2p(void *a) { return ((uint) (a)) - KERNBASE; } -static inline void *p2v(uint a) { return (void *) ((a) + KERNBASE); } - -#endif - +// Convert virtual and physical addresses (from kernel's perspective) #define V2P(a) (((uint) (a)) - KERNBASE) #define P2V(a) (((void *) (a)) + KERNBASE) -#define V2P_WO(x) ((x) - KERNBASE) // same as V2P, but without casts -#define P2V_WO(x) ((x) + KERNBASE) // same as V2P, but without casts +#else + +// The same without casts (for use in assembly) +#define V2P_WO(x) ((x) - KERNBASE) +#define P2V_WO(x) ((x) + KERNBASE) + +#endif diff --git a/mp.c b/mp.c index a257749..90fa48a 100644 --- a/mp.c +++ b/mp.c @@ -33,7 +33,7 @@ mpsearch1(uint a, int len) { uchar *e, *p, *addr; - addr = p2v(a); + addr = P2V(a); e = addr+len; for(p = addr; p < e; p += sizeof(struct mp)) if(memcmp(p, "_MP_", 4) == 0 && sum(p, sizeof(struct mp)) == 0) @@ -78,7 +78,7 @@ mpconfig(struct mp **pmp) if((mp = mpsearch()) == 0 || mp->physaddr == 0) return 0; - conf = (struct mpconf*) p2v((uint) mp->physaddr); + conf = (struct mpconf*) P2V((uint) mp->physaddr); if(memcmp(conf, "PCMP", 4) != 0) return 0; if(conf->version != 1 && conf->version != 4) diff --git a/proc.c b/proc.c index 3ac41f6..d983233 100644 --- a/proc.c +++ b/proc.c @@ -1,7 +1,6 @@ #include "types.h" #include "defs.h" #include "param.h" -#include "memlayout.h" #include "mmu.h" #include "x86.h" #include "proc.h" @@ -55,11 +54,11 @@ found: return 0; } sp = p->kstack + KSTACKSIZE; - + // Leave room for trap frame. sp -= sizeof *p->tf; p->tf = (struct trapframe*)sp; - + // Set up new context to start executing at forkret, // which returns to trapret. sp -= 4; @@ -80,7 +79,7 @@ userinit(void) { struct proc *p; extern char _binary_initcode_start[], _binary_initcode_size[]; - + p = allocproc(); initproc = p; if((p->pgdir = setupkvm()) == 0) @@ -108,7 +107,7 @@ int growproc(int n) { uint sz; - + sz = proc->sz; if(n > 0){ if((sz = allocuvm(proc->pgdir, sz, sz + n)) == 0) @@ -155,14 +154,14 @@ fork(void) np->cwd = idup(proc->cwd); safestrcpy(np->name, proc->name, sizeof(proc->name)); - + pid = np->pid; // lock to force the compiler to emit the np->state write last. acquire(&ptable.lock); np->state = RUNNABLE; release(&ptable.lock); - + return pid; } @@ -336,13 +335,13 @@ forkret(void) if (first) { // Some initialization functions must be run in the context - // of a regular process (e.g., they call sleep), and thus cannot + // of a regular process (e.g., they call sleep), and thus cannot // be run from main(). first = 0; iinit(ROOTDEV); initlog(ROOTDEV); } - + // Return to "caller", actually trapret (see allocproc). } @@ -447,7 +446,7 @@ procdump(void) struct proc *p; char *state; uint pc[10]; - + for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ if(p->state == UNUSED) continue; diff --git a/syscall.c b/syscall.c index 799ebc2..9ef66a1 100644 --- a/syscall.c +++ b/syscall.c @@ -1,7 +1,6 @@ #include "types.h" #include "defs.h" #include "param.h" -#include "memlayout.h" #include "mmu.h" #include "proc.h" #include "x86.h" @@ -55,7 +54,7 @@ int argptr(int n, char **pp, int size) { int i; - + if(argint(n, &i) < 0) return -1; if((uint)i >= proc->sz || (uint)i+size > proc->sz) diff --git a/sysproc.c b/sysproc.c index 027a5e5..26c232c 100644 --- a/sysproc.c +++ b/sysproc.c @@ -3,7 +3,6 @@ #include "defs.h" #include "date.h" #include "param.h" -#include "memlayout.h" #include "mmu.h" #include "proc.h" @@ -61,7 +60,7 @@ sys_sleep(void) { int n; uint ticks0; - + if(argint(0, &n) < 0) return -1; acquire(&tickslock); @@ -83,7 +82,7 @@ int sys_uptime(void) { uint xticks; - + acquire(&tickslock); xticks = ticks; release(&tickslock); diff --git a/trap.c b/trap.c index 3f80145..6118f81 100644 --- a/trap.c +++ b/trap.c @@ -1,7 +1,6 @@ #include "types.h" #include "defs.h" #include "param.h" -#include "memlayout.h" #include "mmu.h" #include "proc.h" #include "x86.h" @@ -9,7 +8,7 @@ #include "spinlock.h" // Interrupt descriptor table (shared by all CPUs). -struct gatedesc idt[256]; +static struct gatedesc idt[256]; extern uint vectors[]; // in vectors.S: array of 256 entry pointers struct spinlock tickslock; uint ticks; @@ -22,7 +21,7 @@ tvinit(void) for(i = 0; i < 256; i++) SETGATE(idt[i], 0, SEG_KCODE<<3, vectors[i], 0); SETGATE(idt[T_SYSCALL], 1, SEG_KCODE<<3, vectors[T_SYSCALL], DPL_USER); - + initlock(&tickslock, "time"); } @@ -77,7 +76,7 @@ trap(struct trapframe *tf) cpu->id, tf->cs, tf->eip); lapiceoi(); break; - + //PAGEBREAK: 13 default: if(proc == 0 || (tf->cs&3) == 0){ @@ -89,13 +88,13 @@ trap(struct trapframe *tf) // In user space, assume process misbehaved. cprintf("pid %d %s: trap %d err %d on cpu %d " "eip 0x%x addr 0x%x--kill proc\n", - proc->pid, proc->name, tf->trapno, tf->err, cpu->id, tf->eip, + proc->pid, proc->name, tf->trapno, tf->err, cpu->id, tf->eip, rcr2()); proc->killed = 1; } // Force process exit if it has been killed and is in user space. - // (If it is still executing in the kernel, let it keep running + // (If it is still executing in the kernel, let it keep running // until it gets to the regular system call return.) if(proc && proc->killed && (tf->cs&3) == DPL_USER) exit(); diff --git a/vm.c b/vm.c index fc61781..8f34f58 100644 --- a/vm.c +++ b/vm.c @@ -49,7 +49,7 @@ walkpgdir(pde_t *pgdir, const void *va, int alloc) pde = &pgdir[PDX(va)]; if(*pde & PTE_P){ - pgtab = (pte_t*)p2v(PTE_ADDR(*pde)); + pgtab = (pte_t*)P2V(PTE_ADDR(*pde)); } else { if(!alloc || (pgtab = (pte_t*)kalloc()) == 0) return 0; @@ -58,7 +58,7 @@ walkpgdir(pde_t *pgdir, const void *va, int alloc) // The permissions here are overly generous, but they can // be further restricted by the permissions in the page table // entries, if necessary. - *pde = v2p(pgtab) | PTE_P | PTE_W | PTE_U; + *pde = V2P(pgtab) | PTE_P | PTE_W | PTE_U; } return &pgtab[PTX(va)]; } @@ -133,7 +133,7 @@ setupkvm(void) if((pgdir = (pde_t*)kalloc()) == 0) return 0; memset(pgdir, 0, PGSIZE); - if (p2v(PHYSTOP) > (void*)DEVSPACE) + if (P2V(PHYSTOP) > (void*)DEVSPACE) panic("PHYSTOP too high"); for(k = kmap; k < &kmap[NELEM(kmap)]; k++) if(mappages(pgdir, k->virt, k->phys_end - k->phys_start, @@ -156,7 +156,7 @@ kvmalloc(void) void switchkvm(void) { - lcr3(v2p(kpgdir)); // switch to the kernel page table + lcr3(V2P(kpgdir)); // switch to the kernel page table } // Switch TSS and h/w page table to correspond to process p. @@ -171,7 +171,7 @@ switchuvm(struct proc *p) ltr(SEG_TSS << 3); if(p->pgdir == 0) panic("switchuvm: no pgdir"); - lcr3(v2p(p->pgdir)); // switch to new address space + lcr3(V2P(p->pgdir)); // switch to new address space popcli(); } @@ -187,7 +187,7 @@ inituvm(pde_t *pgdir, char *init, uint sz) if ((mem = kalloc()) == 0) panic("inituvm: cannot allocate memory"); memset(mem, 0, PGSIZE); - if (mappages(pgdir, 0, PGSIZE, v2p(mem), PTE_W|PTE_U) < 0) + if (mappages(pgdir, 0, PGSIZE, V2P(mem), PTE_W|PTE_U) < 0) panic("inituvm: cannot create pagetable"); memmove(mem, init, sz); } @@ -210,7 +210,7 @@ loaduvm(pde_t *pgdir, char *addr, struct inode *ip, uint offset, uint sz) n = sz - i; else n = PGSIZE; - if(readi(ip, p2v(pa), offset+i, n) != n) + if(readi(ip, P2V(pa), offset+i, n) != n) return -1; } return 0; @@ -238,7 +238,7 @@ allocuvm(pde_t *pgdir, uint oldsz, uint newsz) return 0; } memset(mem, 0, PGSIZE); - if (mappages(pgdir, (char*)a, PGSIZE, v2p(mem), PTE_W|PTE_U) < 0) + if (mappages(pgdir, (char*)a, PGSIZE, V2P(mem), PTE_W|PTE_U) < 0) panic("allocuvm: cannot create pagetable"); } return newsz; @@ -266,7 +266,7 @@ deallocuvm(pde_t *pgdir, uint oldsz, uint newsz) pa = PTE_ADDR(*pte); if(pa == 0) panic("kfree"); - char *v = p2v(pa); + char *v = P2V(pa); kfree(v); *pte = 0; } @@ -286,7 +286,7 @@ freevm(pde_t *pgdir) deallocuvm(pgdir, KERNBASE, 0); for(i = 0; i < NPDENTRIES; i++){ if(pgdir[i] & PTE_P){ - char * v = p2v(PTE_ADDR(pgdir[i])); + char * v = P2V(PTE_ADDR(pgdir[i])); kfree(v); } } @@ -327,8 +327,8 @@ copyuvm(pde_t *pgdir, uint sz) flags = PTE_FLAGS(*pte); if((mem = kalloc()) == 0) goto bad; - memmove(mem, (char*)p2v(pa), PGSIZE); - if(mappages(d, (void*)i, PGSIZE, v2p(mem), flags) < 0) + memmove(mem, (char*)P2V(pa), PGSIZE); + if(mappages(d, (void*)i, PGSIZE, V2P(mem), flags) < 0) goto bad; } return d; @@ -350,7 +350,7 @@ uva2ka(pde_t *pgdir, char *uva) return 0; if((*pte & PTE_U) == 0) return 0; - return (char*)p2v(PTE_ADDR(*pte)); + return (char*)P2V(PTE_ADDR(*pte)); } // Copy len bytes from p to user address va in page table pgdir.