diff --git a/Makefile b/Makefile index f67c88c271..d52c97666f 100644 --- a/Makefile +++ b/Makefile @@ -109,7 +109,7 @@ initcode: initcode.S $(OBJDUMP) -S initcode.o > initcode.asm kernel: $(OBJS) multiboot.o data.o bootother initcode - $(LD) $(LDFLAGS) -Ttext 0x100000 -e main -o kernel multiboot.o data.o $(OBJS) -b binary initcode bootother + $(LD) $(LDFLAGS) -T kernel.ld -e multiboot_entry -o kernel multiboot.o data.o $(OBJS) -b binary initcode bootother $(OBJDUMP) -S kernel > kernel.asm $(OBJDUMP) -t kernel | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > kernel.sym @@ -200,7 +200,7 @@ QEMUGDB = $(shell if $(QEMU) -help | grep -q '^-gdb'; \ ifndef CPUS CPUS := 2 endif -QEMUOPTS = -hdb fs.img xv6.img -smp $(CPUS) +QEMUOPTS = -hdb fs.img xv6.img -smp $(CPUS) -m 512 qemu: fs.img xv6.img $(QEMU) -serial mon:stdio $(QEMUOPTS) diff --git a/bootmain.c b/bootmain.c index 7cd469fee6..fa2725df22 100644 --- a/bootmain.c +++ b/bootmain.c @@ -8,6 +8,7 @@ #include "types.h" #include "elf.h" #include "x86.h" +#include "memlayout.h" #define SECTSIZE 512 @@ -19,7 +20,7 @@ bootmain(void) struct elfhdr *elf; struct proghdr *ph, *eph; void (*entry)(void); - uchar* va; + uchar* pa; elf = (struct elfhdr*)0x10000; // scratch space @@ -34,15 +35,15 @@ bootmain(void) ph = (struct proghdr*)((uchar*)elf + elf->phoff); eph = ph + elf->phnum; for(; ph < eph; ph++){ - va = (uchar*)ph->va; - readseg(va, ph->filesz, ph->offset); + pa = (uchar*)ph->pa; + readseg(pa, ph->filesz, ph->offset); if(ph->memsz > ph->filesz) - stosb(va + ph->filesz, 0, ph->memsz - ph->filesz); + stosb(pa + ph->filesz, 0, ph->memsz - ph->filesz); } // Call the entry point from the ELF header. // Does not return! - entry = (void(*)(void))(elf->entry); + entry = (void(*)(void))(elf->entry & 0xFFFFFF); entry(); } diff --git a/bootother.S b/bootother.S index 37b899b909..2c9720750e 100644 --- a/bootother.S +++ b/bootother.S @@ -1,4 +1,5 @@ #include "asm.h" +#include "memlayout.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 @@ -24,6 +25,8 @@ #define CR0_PE 1 +#define RELOC1(x) ((x) + KERNBASE) // same as V2P, but without casts + .code16 .globl start start: @@ -40,7 +43,7 @@ start: movl %eax, %cr0 //PAGEBREAK! - ljmp $(SEG_KCODE<<3), $start32 + ljmpl $(SEG_KCODE<<3), $(start32+KERNBASE) .code32 start32: @@ -53,10 +56,10 @@ start32: movw %ax, %gs # switch to the stack allocated by bootothers() - movl start-4, %esp + movl RELOC1(start-4), %esp # call mpmain() - call *(start-8) + call *(RELOC1(start)-8) movw $0x8a00, %ax movw %ax, %dx @@ -69,8 +72,9 @@ spin: .p2align 2 gdt: SEG_NULLASM - SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff) - SEG_ASM(STA_W, 0x0, 0xffffffff) + SEG_ASM(STA_X|STA_R, -KERNBASE, 0xffffffff) + SEG_ASM(STA_W, -KERNBASE, 0xffffffff) + gdtdesc: .word (gdtdesc - gdt - 1) diff --git a/console.c b/console.c index 27649e68ed..394176bf3f 100644 --- a/console.c +++ b/console.c @@ -9,6 +9,7 @@ #include "spinlock.h" #include "fs.h" #include "file.h" +#include "memlayout.h" #include "mmu.h" #include "proc.h" #include "x86.h" @@ -60,6 +61,9 @@ cprintf(char *fmt, ...) if(locking) acquire(&cons.lock); + if (fmt == 0) + panic("null fmt"); + argp = (uint*)(void*)(&fmt + 1); state = 0; for(i = 0; (c = fmt[i] & 0xff) != 0; i++){ @@ -121,7 +125,7 @@ panic(char *s) //PAGEBREAK: 50 #define BACKSPACE 0x100 #define CRTPORT 0x3d4 -static ushort *crt = (ushort*)0xb8000; // CGA memory +static ushort *crt = (ushort*)P2V(0xb8000); // CGA memory static void cgaputc(int c) diff --git a/defs.h b/defs.h index bbe4ae4f58..54ea14d895 100644 --- a/defs.h +++ b/defs.h @@ -62,6 +62,7 @@ extern uchar ioapicid; void ioapicinit(void); // kalloc.c +char* pgalloc(void); char* kalloc(void); void kfree(char*); void kinit(void); @@ -160,6 +161,7 @@ void uartintr(void); void uartputc(int); // vm.c +void pginit(char* (*alloc)()); void seginit(void); void kvmalloc(void); void vmenable(void); diff --git a/exec.c b/exec.c index 05f80f8f3f..9186cfbe6d 100644 --- a/exec.c +++ b/exec.c @@ -1,5 +1,6 @@ #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 53293a7207..054bb764dc 100644 --- a/ide.c +++ b/ide.c @@ -3,6 +3,7 @@ #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 bf1616afc0..83ed7e812c 100644 --- a/kalloc.c +++ b/kalloc.c @@ -5,6 +5,7 @@ #include "types.h" #include "defs.h" #include "param.h" +#include "memlayout.h" #include "mmu.h" #include "spinlock.h" @@ -18,6 +19,20 @@ struct { } kmem; extern char end[]; // first address after kernel loaded from ELF file +char *newend; + +// simple page allocator to get off the ground during boot +char * +pgalloc(void) +{ + if (newend == 0) + newend = end; + + void *p = (void*)PGROUNDUP((uint)newend); + memset(p, 0, PGSIZE); + newend = newend + PGSIZE; + return p; +} // Initialize free list of physical pages. void @@ -26,8 +41,8 @@ kinit(void) char *p; initlock(&kmem.lock, "kmem"); - p = (char*)PGROUNDUP((uint)end); - for(; p + PGSIZE <= (char*)PHYSTOP; p += PGSIZE) + p = (char*)PGROUNDUP((uint)newend); + for(; p + PGSIZE <= (char*)p2v(PHYSTOP); p += PGSIZE) kfree(p); } @@ -41,7 +56,7 @@ kfree(char *v) { struct run *r; - if((uint)v % PGSIZE || v < end || (uint)v >= PHYSTOP) + if((uint)v % PGSIZE || v < end || v2p(v) >= PHYSTOP) panic("kfree"); // Fill with junk to catch dangling refs. @@ -67,6 +82,7 @@ kalloc(void) if(r) kmem.freelist = r->next; release(&kmem.lock); + cprintf("kalloc: 0x%x\n", r); return (char*)r; } diff --git a/main.c b/main.c index a27c4ffa2e..d596cecc83 100644 --- a/main.c +++ b/main.c @@ -1,6 +1,7 @@ #include "types.h" #include "defs.h" #include "param.h" +#include "memlayout.h" #include "mmu.h" #include "proc.h" #include "x86.h" @@ -9,6 +10,8 @@ static void bootothers(void); static void mpmain(void); void jmpkstack(void) __attribute__((noreturn)); void mainc(void); +static volatile int newpgdir; + // Bootstrap processor starts running C code here. // Allocate a real stack and switch to it, first @@ -16,6 +19,7 @@ void mainc(void); int main(void) { + pginit(pgalloc); mpinit(); // collect info about this machine lapicinit(mpbcpu()); seginit(); // set up segments @@ -46,7 +50,6 @@ mainc(void) ioapicinit(); // another interrupt controller consoleinit(); // I/O devices & their interrupts uartinit(); // serial port - kvmalloc(); // initialize the kernel page table pinit(); // process table tvinit(); // trap vectors binit(); // buffer cache @@ -57,7 +60,8 @@ mainc(void) timerinit(); // uniprocessor timer userinit(); // first user process bootothers(); // start other processors - + kvmalloc(); // new kernel page table wo. bottom mapped + newpgdir = 1; // Finish setting up this processor in mpmain. mpmain(); } @@ -66,16 +70,25 @@ mainc(void) // Bootstrap CPU comes here from mainc(). // Other CPUs jump here from bootother.S. static void -mpmain(void) +mpboot(void) { - if(cpunum() != mpbcpu()){ - seginit(); - lapicinit(cpunum()); - } vmenable(); // turn on paging + seginit(); + lapicinit(cpunum()); + mpmain(); +} + +// Common CPU setup code. +// Bootstrap CPU comes here from mainc(). +// Other CPUs jump here from bootother.S. +static void +mpmain(void) +{ cprintf("cpu%d: starting\n", cpu->id); idtinit(); // load idt register xchg(&cpu->booted, 1); // tell bootothers() we're up + while (!newpgdir) ; // wait until we have new page dir + switchkvm(); // switch to new page dir scheduler(); // start running processes } @@ -91,7 +104,7 @@ bootothers(void) // Write bootstrap code to unused memory at 0x7000. // The linker has placed the image of bootother.S in // _binary_bootother_start. - code = (uchar*)0x7000; + code = p2v(0x7000); memmove(code, _binary_bootother_start, (uint)_binary_bootother_size); for(c = cpus; c < cpus+ncpu; c++){ @@ -103,9 +116,9 @@ bootothers(void) // its first instruction. stack = kalloc(); *(void**)(code-4) = stack + KSTACKSIZE; - *(void**)(code-8) = mpmain; + *(void**)(code-8) = mpboot; - lapicstartap(c->id, (uint)code); + lapicstartap(c->id, v2p(code)); // Wait for cpu to finish mpmain() while(c->booted == 0) diff --git a/mmu.h b/mmu.h index 2d88a52128..86879d2550 100644 --- a/mmu.h +++ b/mmu.h @@ -106,18 +106,10 @@ struct segdesc { // construct linear address from indexes and offset #define PGADDR(d, t, o) ((uint)((d) << PDXSHIFT | (t) << PTXSHIFT | (o))) -// turn a kernel linear address into a physical address. -// all of the kernel data structures have linear and -// physical addresses that are equal. -#define PADDR(a) ((uint)(a)) - // Page directory and page table constants. #define NPDENTRIES 1024 // page directory entries per page directory #define NPTENTRIES 1024 // page table entries per page table -#define PGSIZE 4096 // bytes mapped by a page -#define PGSHIFT 12 // log2(PGSIZE) - #define PTXSHIFT 12 // offset of PTX in a linear address #define PDXSHIFT 22 // offset of PDX in a linear address diff --git a/mp.c b/mp.c index 5ab348ef9e..b1e2813374 100644 --- a/mp.c +++ b/mp.c @@ -5,6 +5,7 @@ #include "types.h" #include "defs.h" #include "param.h" +#include "memlayout.h" #include "mp.h" #include "x86.h" #include "mmu.h" @@ -39,6 +40,7 @@ mpsearch1(uchar *addr, int len) { uchar *e, *p; + addr = p2v((uint) addr); e = addr+len; for(p = addr; p < e; p += sizeof(struct mp)) if(memcmp(p, "_MP_", 4) == 0 && sum(p, sizeof(struct mp)) == 0) @@ -83,7 +85,7 @@ mpconfig(struct mp **pmp) if((mp = mpsearch()) == 0 || mp->physaddr == 0) return 0; - conf = (struct mpconf*)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/multiboot.S b/multiboot.S index 2579b6d9ae..84ab638eaf 100644 --- a/multiboot.S +++ b/multiboot.S @@ -15,6 +15,9 @@ # } #include "asm.h" +#include "memlayout.h" + +#define RELOC(x) ((x) - KERNBASE) // same as V2P, but without casts #define STACK 4096 @@ -42,7 +45,7 @@ multiboot_header: # boot loader - bootasm.S - sets up. .globl multiboot_entry multiboot_entry: - lgdt gdtdesc + lgdt RELOC(gdtdesc) ljmp $(SEG_KCODE<<3), $mbstart32 mbstart32: @@ -65,11 +68,11 @@ spin: .p2align 2 # force 4 byte alignment gdt: SEG_NULLASM # null seg - SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff) # code seg - SEG_ASM(STA_W, 0x0, 0xffffffff) # data seg + SEG_ASM(STA_X|STA_R, -KERNBASE, 0xffffffff) # code seg + SEG_ASM(STA_W, -KERNBASE, 0xffffffff) # data seg gdtdesc: .word (gdtdesc - gdt - 1) # sizeof(gdt) - 1 - .long gdt # address gdt + .long RELOC(gdt) # address gdt .comm stack, STACK diff --git a/param.h b/param.h index ab1b9fe921..03c05f92d9 100644 --- a/param.h +++ b/param.h @@ -7,8 +7,6 @@ #define NINODE 50 // maximum number of active i-nodes #define NDEV 10 // maximum major device number #define ROOTDEV 1 // device number of file system root disk -#define USERTOP 0xA0000 // end of user address space -#define PHYSTOP 0x1000000 // use phys mem up to here as free pool #define MAXARG 32 // max exec arguments #define LOGSIZE 10 // size of log diff --git a/proc.c b/proc.c index eb334d0086..626d03e28f 100644 --- a/proc.c +++ b/proc.c @@ -1,6 +1,7 @@ #include "types.h" #include "defs.h" #include "param.h" +#include "memlayout.h" #include "mmu.h" #include "x86.h" #include "proc.h" diff --git a/spinlock.c b/spinlock.c index e668598aa8..a16621cb54 100644 --- a/spinlock.c +++ b/spinlock.c @@ -4,6 +4,7 @@ #include "defs.h" #include "param.h" #include "x86.h" +#include "memlayout.h" #include "mmu.h" #include "proc.h" #include "spinlock.h" @@ -71,7 +72,7 @@ getcallerpcs(void *v, uint pcs[]) ebp = (uint*)v - 2; for(i = 0; i < 10; i++){ - if(ebp == 0 || ebp < (uint*)0x100000 || ebp == (uint*)0xffffffff) + if(ebp == 0 || ebp < (uint*)KERNBASE || ebp == (uint*)0xffffffff) break; pcs[i] = ebp[1]; // saved %eip ebp = (uint*)ebp[0]; // saved %ebp diff --git a/syscall.c b/syscall.c index ce50a59b2d..b848716e14 100644 --- a/syscall.c +++ b/syscall.c @@ -1,6 +1,7 @@ #include "types.h" #include "defs.h" #include "param.h" +#include "memlayout.h" #include "mmu.h" #include "proc.h" #include "x86.h" diff --git a/sysproc.c b/sysproc.c index efaa372d84..2a92c48074 100644 --- a/sysproc.c +++ b/sysproc.c @@ -2,6 +2,7 @@ #include "x86.h" #include "defs.h" #include "param.h" +#include "memlayout.h" #include "mmu.h" #include "proc.h" diff --git a/trap.c b/trap.c index 6651f8e5f3..3f80145f12 100644 --- a/trap.c +++ b/trap.c @@ -1,6 +1,7 @@ #include "types.h" #include "defs.h" #include "param.h" +#include "memlayout.h" #include "mmu.h" #include "proc.h" #include "x86.h" diff --git a/vm.c b/vm.c index 1fe64d24fa..b14a863288 100644 --- a/vm.c +++ b/vm.c @@ -2,20 +2,71 @@ #include "types.h" #include "defs.h" #include "x86.h" +#include "memlayout.h" #include "mmu.h" #include "proc.h" #include "elf.h" extern char data[]; // defined in data.S - static pde_t *kpgdir; // for use in scheduler() +struct segdesc gdt[NSEGS]; -// Allocate one page table for the machine for the kernel address -// space for scheduler processes. + +// page map for during boot +// XXX build a static page table in assembly +static void +pgmap(void *va, void *last, uint pa) +{ + pde_t *pde; + pte_t *pgtab; + pte_t *pte; + + for(;;){ + pde = &kpgdir[PDX(va)]; + pde_t pdev = *pde; + if (pdev == 0) { + pgtab = (pte_t *) pgalloc(); + *pde = v2p(pgtab) | PTE_P | PTE_W; + } else { + pgtab = (pte_t*)p2v(PTE_ADDR(pdev)); + } + pte = &pgtab[PTX(va)]; + *pte = pa | PTE_W | PTE_P; + if(va == last) + break; + va += PGSIZE; + pa += PGSIZE; + } +} + +// set up a page table to get off the ground void -kvmalloc(void) +pginit(char* (*alloc)(void)) { - kpgdir = setupkvm(); + uint cr0; + + kpgdir = (pde_t *) alloc(); + pgmap((void *) 0, (void *) PHYSTOP, 0); // map pa 0 at va 0 + pgmap((void *) KERNBASE, (void *) (KERNBASE+PHYSTOP), 0); // map pa 0 at va KERNBASE + pgmap((void*)0xFE000000, 0, 0xFE000000); + + switchkvm(); // load kpgdir into cr3 + + cr0 = rcr0(); + cr0 |= CR0_PG; + lcr0(cr0); // paging on + + // new gdt + gdt[SEG_KCODE] = SEG(STA_X|STA_R, 0, 0xffffffff, 0); + gdt[SEG_KDATA] = SEG(STA_W, 0, 0xffffffff, 0); + lgdt((void *)v2p(gdt), sizeof(gdt)); + loadgs(SEG_KDATA << 3); + loadfs(SEG_KDATA << 3); + loades(SEG_KDATA << 3); + loadds(SEG_KDATA << 3); + loadss(SEG_KDATA << 3); + + __asm volatile("ljmp %0,$1f\n 1:\n" :: "i" (SEG_KCODE << 3)); // reload cs } // Set up CPU's kernel segment descriptors. @@ -57,7 +108,7 @@ walkpgdir(pde_t *pgdir, const void *va, int create) pde = &pgdir[PDX(va)]; if(*pde & PTE_P){ - pgtab = (pte_t*)PTE_ADDR(*pde); + pgtab = (pte_t*)p2v(PTE_ADDR(*pde)); } else { if(!create || (pgtab = (pte_t*)kalloc()) == 0) return 0; @@ -66,7 +117,7 @@ walkpgdir(pde_t *pgdir, const void *va, int create) // The permissions here are overly generous, but they can // be further restricted by the permissions in the page table // entries, if necessary. - *pde = PADDR(pgtab) | PTE_P | PTE_W | PTE_U; + *pde = v2p(pgtab) | PTE_P | PTE_W | PTE_U; } return &pgtab[PTX(va)]; } @@ -105,29 +156,30 @@ mappages(pde_t *pgdir, void *la, uint size, uint pa, int perm) // page protection bits prevent it from using anything other // than its memory. // +// // setupkvm() and exec() set up every page table like this: -// 0..640K : user memory (text, data, stack, heap) -// 640K..1M : mapped direct (for IO space) -// 1M..end : mapped direct (for the kernel's text and data) -// end..PHYSTOP : mapped direct (kernel heap and user pages) +// 0..KERNBASE : user memory (text, data, stack, heap), mapped to some phys mem +// KERNBASE+640K..KERNBASE+1M: mapped to 640K..1M +// KERNBASE+1M..KERNBASE+end : mapped to 1M..end +// KERNBASE+end..KERBASE+PHYSTOP : mapped to end..PHYSTOP (free memory) // 0xfe000000..0 : mapped direct (devices such as ioapic) // // The kernel allocates memory for its heap and for user memory // between kernend and the end of physical memory (PHYSTOP). // The virtual address space of each user program includes the kernel -// (which is inaccessible in user mode). The user program addresses -// range from 0 till 640KB (USERTOP), which where the I/O hole starts -// (both in physical memory and in the kernel's virtual address -// space). +// (which is inaccessible in user mode). The user program sits in +// the bottom of the address space, and the kernel at the top at KERNBASE. static struct kmap { - void *p; - void *e; + void *l; + uint p; + uint e; int perm; } kmap[] = { - {(void*)USERTOP, (void*)0x100000, PTE_W}, // I/O space - {(void*)0x100000, data, 0 }, // kernel text, rodata - {data, (void*)PHYSTOP, PTE_W}, // kernel data, memory - {(void*)0xFE000000, 0, PTE_W}, // device mappings + { (void *)IOSPACEB, IOSPACEB, IOSPACEE, PTE_W}, // I/O space + { P2V(IOSPACEB), IOSPACEB, IOSPACEE, PTE_W}, // I/O space + { (void *)KERNLINK, V2P(KERNLINK), V2P(data), 0}, // kernel text, rodata + { data, V2P(data), PHYSTOP, PTE_W}, // kernel data, memory + { (void*)0xFE000000, 0xFE000000, 0, PTE_W}, // device mappings }; // Set up kernel part of a page table. @@ -142,12 +194,21 @@ setupkvm(void) memset(pgdir, 0, PGSIZE); k = kmap; for(k = kmap; k < &kmap[NELEM(kmap)]; k++) - if(mappages(pgdir, k->p, k->e - k->p, (uint)k->p, k->perm) < 0) + if(mappages(pgdir, k->l, k->e - k->p, (uint)k->p, k->perm) < 0) return 0; return pgdir; } +// Allocate one page table for the machine for the kernel address +// space for scheduler processes. +void +kvmalloc(void) +{ + kpgdir = setupkvm(); + switchkvm(); +} + // Turn on paging. void vmenable(void) @@ -158,6 +219,16 @@ vmenable(void) cr0 = rcr0(); cr0 |= CR0_PG; lcr0(cr0); + + struct cpu *c = &cpus[0]; + lgdt((void *)v2p((void *)(c->gdt)), sizeof(c->gdt)); + loadgs(SEG_KCPU << 3); + loadfs(SEG_KDATA << 3); + loades(SEG_KDATA << 3); + loadds(SEG_KDATA << 3); + loadss(SEG_KDATA << 3); + + __asm volatile("ljmp %0,$1f\n 1:\n" :: "i" (SEG_KCODE << 3)); // reload cs } // Switch h/w page table register to the kernel-only page table, @@ -165,7 +236,7 @@ vmenable(void) void switchkvm(void) { - lcr3(PADDR(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. @@ -180,7 +251,7 @@ switchuvm(struct proc *p) ltr(SEG_TSS << 3); if(p->pgdir == 0) panic("switchuvm: no pgdir"); - lcr3(PADDR(p->pgdir)); // switch to new address space + lcr3(v2p(p->pgdir)); // switch to new address space popcli(); } @@ -195,7 +266,7 @@ inituvm(pde_t *pgdir, char *init, uint sz) panic("inituvm: more than a page"); mem = kalloc(); memset(mem, 0, PGSIZE); - mappages(pgdir, 0, PGSIZE, PADDR(mem), PTE_W|PTE_U); + mappages(pgdir, 0, PGSIZE, v2p(mem), PTE_W|PTE_U); memmove(mem, init, sz); } @@ -245,7 +316,7 @@ allocuvm(pde_t *pgdir, uint oldsz, uint newsz) return 0; } memset(mem, 0, PGSIZE); - mappages(pgdir, (char*)a, PGSIZE, PADDR(mem), PTE_W|PTE_U); + mappages(pgdir, (char*)a, PGSIZE, v2p(mem), PTE_W|PTE_U); } return newsz; } @@ -289,7 +360,7 @@ freevm(pde_t *pgdir) deallocuvm(pgdir, USERTOP, 0); for(i = 0; i < NPDENTRIES; i++){ if(pgdir[i] & PTE_P) - kfree((char*)PTE_ADDR(pgdir[i])); + kfree(p2v(PTE_ADDR(pgdir[i]))); } kfree((char*)pgdir); } @@ -315,7 +386,7 @@ copyuvm(pde_t *pgdir, uint sz) if((mem = kalloc()) == 0) goto bad; memmove(mem, (char*)pa, PGSIZE); - if(mappages(d, (void*)i, PGSIZE, PADDR(mem), PTE_W|PTE_U) < 0) + if(mappages(d, (void*)i, PGSIZE, v2p(mem), PTE_W|PTE_U) < 0) goto bad; } return d; diff --git a/x86.h b/x86.h index 5a59cc2043..828d5bc0f3 100644 --- a/x86.h +++ b/x86.h @@ -96,6 +96,30 @@ loadgs(ushort v) asm volatile("movw %0, %%gs" : : "r" (v)); } +static inline void +loadfs(ushort v) +{ + __asm volatile("movw %0, %%fs" : : "r" (v)); +} + +static inline void +loades(ushort v) +{ + __asm volatile("movw %0, %%es" : : "r" (v)); +} + +static inline void +loadds(ushort v) +{ + __asm volatile("movw %0, %%ds" : : "r" (v)); +} + +static inline void +loadss(ushort v) +{ + __asm volatile("movw %0, %%ss" : : "r" (v)); +} + static inline uint rebp(void) {