remove some unused vm #defines
fix corner cases with alignment when mapping kernel ELF file
This commit is contained in:
parent
2cf6b32d4d
commit
c99599784e
4 changed files with 28 additions and 66 deletions
2
defs.h
2
defs.h
|
@ -156,8 +156,6 @@ void pminit(void);
|
||||||
void ksegment(void);
|
void ksegment(void);
|
||||||
void kvmalloc(void);
|
void kvmalloc(void);
|
||||||
void vminit(void);
|
void vminit(void);
|
||||||
void printstack(void);
|
|
||||||
void printpgdir(pde_t *);
|
|
||||||
pde_t* setupkvm(void);
|
pde_t* setupkvm(void);
|
||||||
char* uva2ka(pde_t*, char*);
|
char* uva2ka(pde_t*, char*);
|
||||||
int allocuvm(pde_t*, char*, uint);
|
int allocuvm(pde_t*, char*, uint);
|
||||||
|
|
30
mmu.h
30
mmu.h
|
@ -85,32 +85,20 @@ struct segdesc {
|
||||||
// | Page Directory | Page Table | Offset within Page |
|
// | Page Directory | Page Table | Offset within Page |
|
||||||
// | Index | Index | |
|
// | Index | Index | |
|
||||||
// +----------------+----------------+---------------------+
|
// +----------------+----------------+---------------------+
|
||||||
// \--- PDX(la) --/ \--- PTX(la) --/ \---- PGOFF(la) ----/
|
// \--- PDX(la) --/ \--- PTX(la) --/
|
||||||
// \----------- PPN(la) -----------/
|
|
||||||
//
|
|
||||||
// The PDX, PTX, PGOFF, and PPN macros decompose linear addresses as shown.
|
|
||||||
// To construct a linear address la from PDX(la), PTX(la), and PGOFF(la),
|
|
||||||
// use PGADDR(PDX(la), PTX(la), PGOFF(la)).
|
|
||||||
|
|
||||||
// page number field of address
|
|
||||||
#define PPN(la) (((uint) (la)) >> PTXSHIFT)
|
|
||||||
#define VPN(la) PPN(la) // used to index into vpt[]
|
|
||||||
|
|
||||||
// page directory index
|
// page directory index
|
||||||
#define PDX(la) ((((uint) (la)) >> PDXSHIFT) & 0x3FF)
|
#define PDX(la) ((((uint) (la)) >> PDXSHIFT) & 0x3FF)
|
||||||
#define VPD(la) PDX(la) // used to index into vpd[]
|
|
||||||
|
|
||||||
// page table index
|
// page table index
|
||||||
#define PTX(la) ((((uint) (la)) >> PTXSHIFT) & 0x3FF)
|
#define PTX(la) ((((uint) (la)) >> PTXSHIFT) & 0x3FF)
|
||||||
|
|
||||||
// offset in page
|
|
||||||
#define PGOFF(la) (((uint) (la)) & 0xFFF)
|
|
||||||
|
|
||||||
// construct linear address from indexes and offset
|
// construct linear address from indexes and offset
|
||||||
#define PGADDR(d, t, o) ((uint) ((d) << PDXSHIFT | (t) << PTXSHIFT | (o)))
|
#define PGADDR(d, t, o) ((uint) ((d) << PDXSHIFT | (t) << PTXSHIFT | (o)))
|
||||||
|
|
||||||
// mapping from physical addresses to virtual addresses is the identity one
|
// turn a kernel linear address into a physical address.
|
||||||
// (really linear addresses, but we map linear to physical also directly)
|
// all of the kernel data structures have linear and
|
||||||
|
// physical addresses that are equal.
|
||||||
#define PADDR(a) ((uint) a)
|
#define PADDR(a) ((uint) a)
|
||||||
|
|
||||||
// Page directory and page table constants.
|
// Page directory and page table constants.
|
||||||
|
@ -120,9 +108,6 @@ struct segdesc {
|
||||||
#define PGSIZE 4096 // bytes mapped by a page
|
#define PGSIZE 4096 // bytes mapped by a page
|
||||||
#define PGSHIFT 12 // log2(PGSIZE)
|
#define PGSHIFT 12 // log2(PGSIZE)
|
||||||
|
|
||||||
#define PTSIZE (PGSIZE*NPTENTRIES) // bytes mapped by a page directory entry
|
|
||||||
#define PTSHIFT 22 // log2(PTSIZE)
|
|
||||||
|
|
||||||
#define PTXSHIFT 12 // offset of PTX in a linear address
|
#define PTXSHIFT 12 // offset of PTX in a linear address
|
||||||
#define PDXSHIFT 22 // offset of PDX in a linear address
|
#define PDXSHIFT 22 // offset of PDX in a linear address
|
||||||
|
|
||||||
|
@ -140,13 +125,6 @@ struct segdesc {
|
||||||
#define PTE_PS 0x080 // Page Size
|
#define PTE_PS 0x080 // Page Size
|
||||||
#define PTE_MBZ 0x180 // Bits must be zero
|
#define PTE_MBZ 0x180 // Bits must be zero
|
||||||
|
|
||||||
// The PTE_AVAIL bits aren't used by the kernel or interpreted by the
|
|
||||||
// hardware, so user processes are allowed to set them arbitrarily.
|
|
||||||
#define PTE_AVAIL 0xE00 // Available for software use
|
|
||||||
|
|
||||||
// Only flags in PTE_USER may be used in system calls.
|
|
||||||
#define PTE_USER (PTE_AVAIL | PTE_P | PTE_W | PTE_U)
|
|
||||||
|
|
||||||
// Address in page table or page directory entry
|
// Address in page table or page directory entry
|
||||||
#define PTE_ADDR(pte) ((uint) (pte) & ~0xFFF)
|
#define PTE_ADDR(pte) ((uint) (pte) & ~0xFFF)
|
||||||
|
|
||||||
|
|
2
proc.c
2
proc.c
|
@ -414,9 +414,9 @@ wait(void)
|
||||||
// Found one.
|
// Found one.
|
||||||
pid = p->pid;
|
pid = p->pid;
|
||||||
kfree(p->kstack, KSTACKSIZE);
|
kfree(p->kstack, KSTACKSIZE);
|
||||||
|
p->kstack = 0;
|
||||||
freevm(p->pgdir);
|
freevm(p->pgdir);
|
||||||
p->state = UNUSED;
|
p->state = UNUSED;
|
||||||
p->kstack = 0;
|
|
||||||
p->pid = 0;
|
p->pid = 0;
|
||||||
p->parent = 0;
|
p->parent = 0;
|
||||||
p->name[0] = 0;
|
p->name[0] = 0;
|
||||||
|
|
58
vm.c
58
vm.c
|
@ -33,27 +33,6 @@ static uint kernend;
|
||||||
static uint freesz;
|
static uint freesz;
|
||||||
pde_t *kpgdir; // One kernel page table for scheduler procs
|
pde_t *kpgdir; // One kernel page table for scheduler procs
|
||||||
|
|
||||||
void
|
|
||||||
printpgdir(pde_t *pgdir)
|
|
||||||
{
|
|
||||||
uint i;
|
|
||||||
uint j;
|
|
||||||
|
|
||||||
cprintf("printpgdir 0x%x\n", pgdir);
|
|
||||||
for (i = 0; i < NPDENTRIES; i++) {
|
|
||||||
if (pgdir[i] != 0 && i < 100) {
|
|
||||||
cprintf("pgdir %d, v=0x%x\n", i, pgdir[i]);
|
|
||||||
pte_t *pgtab = (pte_t*) PTE_ADDR(pgdir[i]);
|
|
||||||
for (j = 0; j < NPTENTRIES; j++) {
|
|
||||||
if (pgtab[j] != 0)
|
|
||||||
cprintf("pgtab %d, v=0x%x, addr=0x%x\n", j, PGADDR(i, j, 0),
|
|
||||||
PTE_ADDR(pgtab[j]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cprintf("printpgdir done\n", pgdir);
|
|
||||||
}
|
|
||||||
|
|
||||||
// return the address of the PTE in page table pgdir
|
// return the address of the PTE in page table pgdir
|
||||||
// that corresponds to linear address va. if create!=0,
|
// that corresponds to linear address va. if create!=0,
|
||||||
// create any required page table pages.
|
// create any required page table pages.
|
||||||
|
@ -84,19 +63,25 @@ walkpgdir(pde_t *pgdir, const void *va, int create)
|
||||||
}
|
}
|
||||||
|
|
||||||
// create PTEs for linear addresses starting at la that refer to
|
// create PTEs for linear addresses starting at la that refer to
|
||||||
// physical addresses starting at pa.
|
// physical addresses starting at pa. la and size might not
|
||||||
|
// be page-aligned.
|
||||||
static int
|
static int
|
||||||
mappages(pde_t *pgdir, void *la, uint size, uint pa, int perm)
|
mappages(pde_t *pgdir, void *la, uint size, uint pa, int perm)
|
||||||
{
|
{
|
||||||
uint i;
|
char *first = PGROUNDDOWN(la);
|
||||||
pte_t *pte;
|
char *last = PGROUNDDOWN(la + size - 1);
|
||||||
|
char *a = first;
|
||||||
for (i = 0; i < size; i += PGSIZE) {
|
while(1){
|
||||||
if (!(pte = walkpgdir(pgdir, (void*)(la + i), 1)))
|
pte_t *pte = walkpgdir(pgdir, a, 1);
|
||||||
|
if(pte == 0)
|
||||||
return 0;
|
return 0;
|
||||||
if(*pte & PTE_P)
|
if(*pte & PTE_P)
|
||||||
panic("remap");
|
panic("remap");
|
||||||
*pte = (pa + i) | perm | PTE_P;
|
*pte = pa | perm | PTE_P;
|
||||||
|
if(a == last)
|
||||||
|
break;
|
||||||
|
a += PGSIZE;
|
||||||
|
pa += PGSIZE;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -160,10 +145,10 @@ setupkvm(void)
|
||||||
// Map IO space from 640K to 1Mbyte
|
// Map IO space from 640K to 1Mbyte
|
||||||
if (!mappages(pgdir, (void *)USERTOP, 0x60000, USERTOP, PTE_W))
|
if (!mappages(pgdir, (void *)USERTOP, 0x60000, USERTOP, PTE_W))
|
||||||
return 0;
|
return 0;
|
||||||
// Map kernel text from kern text addr read-only
|
// Map kernel text read-only
|
||||||
if (!mappages(pgdir, (void *) kerntext, kerntsz, kerntext, 0))
|
if (!mappages(pgdir, (void *) kerntext, kerntsz, kerntext, 0))
|
||||||
return 0;
|
return 0;
|
||||||
// Map kernel data form kern data addr R/W
|
// Map kernel data read/write
|
||||||
if (!mappages(pgdir, (void *) kerndata, kerndsz, kerndata, PTE_W))
|
if (!mappages(pgdir, (void *) kerndata, kerndsz, kerndata, PTE_W))
|
||||||
return 0;
|
return 0;
|
||||||
// Map dynamically-allocated memory read/write (kernel stacks, user mem)
|
// Map dynamically-allocated memory read/write (kernel stacks, user mem)
|
||||||
|
@ -194,10 +179,10 @@ allocuvm(pde_t *pgdir, char *addr, uint sz)
|
||||||
{
|
{
|
||||||
if (addr + sz >= (char*)USERTOP)
|
if (addr + sz >= (char*)USERTOP)
|
||||||
return 0;
|
return 0;
|
||||||
char *start = PGROUNDDOWN(addr);
|
char *first = PGROUNDDOWN(addr);
|
||||||
char *last = PGROUNDDOWN(addr + sz - 1);
|
char *last = PGROUNDDOWN(addr + sz - 1);
|
||||||
char *a;
|
char *a;
|
||||||
for(a = start; a <= last; a += PGSIZE){
|
for(a = first; a <= last; a += PGSIZE){
|
||||||
pte_t *pte = walkpgdir(pgdir, a, 0);
|
pte_t *pte = walkpgdir(pgdir, a, 0);
|
||||||
if(pte == 0 || (*pte & PTE_P) == 0){
|
if(pte == 0 || (*pte & PTE_P) == 0){
|
||||||
char *mem = kalloc(PGSIZE);
|
char *mem = kalloc(PGSIZE);
|
||||||
|
@ -212,6 +197,8 @@ allocuvm(pde_t *pgdir, char *addr, uint sz)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// free a page table and all the physical memory pages
|
||||||
|
// in the user part.
|
||||||
void
|
void
|
||||||
freevm(pde_t *pgdir)
|
freevm(pde_t *pgdir)
|
||||||
{
|
{
|
||||||
|
@ -227,8 +214,7 @@ freevm(pde_t *pgdir)
|
||||||
if (pgtab[j] != 0) {
|
if (pgtab[j] != 0) {
|
||||||
uint pa = PTE_ADDR(pgtab[j]);
|
uint pa = PTE_ADDR(pgtab[j]);
|
||||||
uint va = PGADDR(i, j, 0);
|
uint va = PGADDR(i, j, 0);
|
||||||
if (va >= USERTOP) // done with user part?
|
if (va < USERTOP) // user memory
|
||||||
break;
|
|
||||||
kfree((void *) pa, PGSIZE);
|
kfree((void *) pa, PGSIZE);
|
||||||
pgtab[j] = 0;
|
pgtab[j] = 0;
|
||||||
}
|
}
|
||||||
|
@ -314,8 +300,8 @@ pminit(void)
|
||||||
kernend = ((uint)end + PGSIZE) & ~(PGSIZE-1);
|
kernend = ((uint)end + PGSIZE) & ~(PGSIZE-1);
|
||||||
kerntext = ph[0].va;
|
kerntext = ph[0].va;
|
||||||
kerndata = ph[1].va;
|
kerndata = ph[1].va;
|
||||||
kerntsz = kerndata - kerntext;
|
kerntsz = ph[0].memsz;
|
||||||
kerndsz = kernend - kerndata;
|
kerndsz = ph[1].memsz;
|
||||||
freesz = PHYSTOP - kernend;
|
freesz = PHYSTOP - kernend;
|
||||||
|
|
||||||
cprintf("kerntext@0x%x(sz=0x%x), kerndata@0x%x(sz=0x%x), kernend 0x%x freesz = 0x%x\n",
|
cprintf("kerntext@0x%x(sz=0x%x), kerndata@0x%x(sz=0x%x), kernend 0x%x freesz = 0x%x\n",
|
||||||
|
|
Loading…
Reference in a new issue