Skip to content
Snippets Groups Projects
Commit c3dcf479 authored by Frans Kaashoek's avatar Frans Kaashoek
Browse files

Clean up memlayout.h

Get rid of last instances of linear address and "la"
Get ready for detecting physical memory dynamically
parent 427958cb
No related branches found
No related tags found
No related merge requests found
......@@ -66,6 +66,7 @@ char* enter_alloc(void);
char* kalloc(void);
void kfree(char*);
void kinit(void);
uint detect_memory(void);
// kbd.c
void kbdintr(void);
......
......@@ -19,7 +19,8 @@ struct {
} kmem;
extern char end[]; // first address after kernel loaded from ELF file
char *newend;
extern uint maxpa; // Maximum physical address
static char *newend;
// simple page allocator to get off the ground during entry
char *
......@@ -36,6 +37,12 @@ enter_alloc(void)
return p;
}
uint
detect_memory(void)
{
return 0xE000000;
}
// Initialize free list of physical pages.
void
kinit(void)
......@@ -44,7 +51,7 @@ kinit(void)
initlock(&kmem.lock, "kmem");
p = (char*)PGROUNDUP((uint)newend);
for(; p + PGSIZE <= (char*)p2v(PHYSTOP); p += PGSIZE)
for(; p + PGSIZE <= (char*)p2v(maxpa); p += PGSIZE)
kfree(p);
}
......@@ -58,7 +65,7 @@ kfree(char *v)
{
struct run *r;
if((uint)v % PGSIZE || v < end || v2p(v) >= PHYSTOP)
if((uint)v % PGSIZE || v < end || v2p(v) >= maxpa)
panic("kfree");
// Fill with junk to catch dangling refs.
......
......@@ -135,7 +135,6 @@ microdelay(int us)
// Start additional processor running entry code at addr.
// See Appendix B of MultiProcessor Specification.
void
lapicstartap(uchar apicid, uint addr)
{
int i;
......@@ -169,3 +168,5 @@ lapicstartap(uchar apicid, uint addr)
microdelay(200);
}
}
// Memory layout
#define PGSIZE 4096 // bytes mapped by a page
#define PGSHIFT 12 // log2(PGSIZE)
#define KSTKSIZE (8*PGSIZE) // size of a kernel stack
#define DEVSPACE 0xFE000000 // other devices are in the top of the phys address space
#define PHYSTOP 0xE000000 // use phys mem up to here as free pool
#define EXTMEM 0x100000 // Start of extended memory
#define DEVSPACE 0xFE000000 // Other devices are at high addresses
// Key addresses for address space layout (see kmap in vm.c for the layout)
#define KERNBASE 0xF0000000 // First kernel virtual address
#define KERNBASE 0xF0000000 // First kernel virtual address
#define USERTOP (KERNBASE-PGSIZE) // Highest user virtual address
#define KERNLINK 0xF0100000 // Address where kernel is linked
#define KERNLINK (KERNBASE+EXTMEM) // Address where kernel is linked
#ifndef __ASSEMBLER__
......
......@@ -100,32 +100,34 @@ struct segdesc {
#define STS_IG32 0xE // 32-bit Interrupt Gate
#define STS_TG32 0xF // 32-bit Trap Gate
// A linear address 'la' has a three-part structure as follows:
// A virtual address 'la' has a three-part structure as follows:
//
// +--------10------+-------10-------+---------12----------+
// | Page Directory | Page Table | Offset within Page |
// | Index | Index | |
// +----------------+----------------+---------------------+
// \--- PDX(la) --/ \--- PTX(la) --/
// \--- PDX(va) --/ \--- PTX(va) --/
// page directory index
#define PDX(la) (((uint)(la) >> PDXSHIFT) & 0x3FF)
#define PDX(va) (((uint)(va) >> PDXSHIFT) & 0x3FF)
// page table index
#define PTX(la) (((uint)(la) >> PTXSHIFT) & 0x3FF)
#define PTX(va) (((uint)(va) >> PTXSHIFT) & 0x3FF)
// construct linear address from indexes and offset
// construct virtual address from indexes and offset
#define PGADDR(d, t, o) ((uint)((d) << PDXSHIFT | (t) << PTXSHIFT | (o)))
// 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
#define PGROUNDUP(sz) (((sz)+PGSIZE-1) & ~(PGSIZE-1))
#define PGROUNDDOWN(a) ((char*)((((unsigned int)(a)) & ~(PGSIZE-1))))
#define PGROUNDDOWN(a) (((a)) & ~(PGSIZE-1))
// Page table/directory entry flags.
#define PTE_P 0x001 // Present
......
......@@ -8,6 +8,7 @@
#include "elf.h"
extern char data[]; // defined in data.S
uint maxpa; // max physical address
pde_t *kpgdir; // for use in scheduler()
struct segdesc gdt[NSEGS];
......@@ -64,8 +65,8 @@ walkpgdir(pde_t *pgdir, const void *va, char* (*alloc)(void))
return &pgtab[PTX(va)];
}
// Create PTEs for virtual addresses starting at la that refer to
// physical addresses starting at pa. la and size might not
// Create PTEs for virtual addresses starting at va that refer to
// physical addresses starting at pa. va and size might not
// be page-aligned.
static int
mappages(pde_t *pgdir, void *va, uint size, uint pa, int perm, char* (*alloc)(void))
......@@ -73,8 +74,8 @@ mappages(pde_t *pgdir, void *va, uint size, uint pa, int perm, char* (*alloc)(vo
char *a, *last;
pte_t *pte;
a = PGROUNDDOWN(va);
last = PGROUNDDOWN(va + size - 1);
a = (char *) PGROUNDDOWN((uint) va);
last = (char *) PGROUNDDOWN(((uint) va) + size - 1);
for(;;){
pte = walkpgdir(pgdir, a, alloc);
if(pte == 0)
......@@ -100,13 +101,13 @@ mappages(pde_t *pgdir, void *va, uint size, uint pa, int perm, char* (*alloc)(vo
//
// setupkvm() and exec() set up every page table like this:
// 0..USERTOP : user memory (text, data, stack, heap), mapped to some unused phys mem
// KERNBASE..KERNBASE+1M: mapped to 0..1M
// KERNBASE+1M..KERNBASE+end : mapped to 1M..end (mapped without write permission)
// KERNBASE+end..KERBASE+PHYSTOP : mapped to end..PHYSTOP (rw data + free memory)
// KERNBASE..KERNBASE+EXTMEM: mapped to 0..EXTMEM (below extended memory)
// KERNBASE+EXTMEM..KERNBASE+end : mapped to EXTMEM..end (mapped without write permission)
// KERNBASE+end..KERBASE+maxpa : mapped to end..maxpa (rw data + 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).
// between kernend and the end of physical memory (maxpa).
// The virtual address space of each user program includes the kernel
// (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.
......@@ -118,7 +119,7 @@ static struct kmap {
} kmap[] = {
{ P2V(0), 0, 1024*1024, PTE_W}, // First 1Mbyte contains BIOS and some IO devices
{ (void *)KERNLINK, V2P(KERNLINK), V2P(data), 0}, // kernel text, rodata
{ data, V2P(data), PHYSTOP, PTE_W}, // kernel data, memory
{ data, V2P(data), 0, PTE_W}, // kernel data, memory
{ (void*)DEVSPACE, DEVSPACE, 0, PTE_W}, // more devices
};
......@@ -129,6 +130,13 @@ setupkvm(char* (*alloc)(void))
pde_t *pgdir;
struct kmap *k;
if (kmap[2].phys_end == 0) {
maxpa = detect_memory();
kmap[2].phys_end = maxpa;
if (p2v(maxpa) > kmap[3].virt)
panic("detect_memory: too much memory");
}
if((pgdir = (pde_t*)alloc()) == 0)
return 0;
memset(pgdir, 0, PGSIZE);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment