Jos - lab2 Memory Management

           Selector  +--------------+         +-----------+
          ---------->|              |         |           |
                     | Segmentation |         |  Paging   |
Software             |              |-------->|           |---------->  RAM
            Offset   |  Mechanism   |         | Mechanism |
          ---------->|              |         |           |
                     +--------------+         +-----------+
            Virtual                   Linear                Physical

1. Key data structure:

178 struct PageInfo {
179         // Next page on the free list.
180         struct PageInfo *pp_link;
187         uint16_t pp_ref;
188 };

// These variables are set by i386_detect_memory()
size_t npages;                  // Amount of physical memory (in pages)
static size_t npages_basemem;   // Amount of base memory (in pages)
// These variables are set in mem_init()
pde_t *kern_pgdir;              // Kernel's initial page directory
struct PageInfo *pages;         // Physical page state array
static struct PageInfo *page_free_list; // Free list of physical pages

2. Memory initialize:

mem_init()
|--> i386_detect_memory()         // use CMOS call to measure available base & extend memory, initialize global variable size_t npages
|--> kern_pgdir = boot_alloc(PGSIZE);    // For kernel page directory
|--> kern_pgdir[PDX(UVPT)] = PADDR(kern_pgdir) | PTE_U | PTE_P;    // Form a virtual page table at virtual addr UVPT, for userspace to access.
|--> pages = (struct PageInfo *)boot_alloc(npages * sizeof(struct PageInfo)); // An array to keep track of physical pages
|--> envs = (struct Env *)boot_alloc(NENV * sizeof(struct Env));    // An array to keep track of all the envs,
|--> page_init()    //  set up the page_free_list to access pages[],
|--> boot_map_region(kern_pgdir, UPAGES, ROUNDUP(npages*sizeof(struct PageInfo), PGSIZE), PADDR(pages), PTE_U); // Map "pages" read-only by user at UPAGES
|--> boot_map_region(kern_pgdir, UENVS, ROUNDUP(NENV*sizeof(struct PageInfo), PGSIZE), PADDR(envs), PTE_U); // Map "envs" read-only by user at UENVS
|--> boot_map_region(kern_pgdir, KSTACKTOP-KSTKSIZE, KSTKSIZE, PADDR(bootstack), PTE_W);    // Map for kernel stack
|--> boot_map_region(kern_pgdir, KERNBASE, ROUNDUP((0xffffffff - KERNBASE), PGSIZE), 0, PTE_W);
|--> mem_init_mp();    // Map the SMP cpu stack
|--> lcr3(PADDR(kern_pgdir));    // Now switch to full kern_pgdir page table

3. Key APIs

struct PageInfo *page_alloc(int alloc_flags);

void  page_free(struct PageInfo *pp);

pte_t* pgdir_walk(pde_t *pgdir, void *va, int create);

int page_insert(pde_t *pgdir, struct PageInfo *pp, void *va, int perm);

struct PageInfo *page_lookup(pde_t *pgdir, void *va, pte_t **pte_store);

void page_remove(pde_t *pgdir, void *va);

void  tlb_invalidate(pde_t *pgdir, void *va);




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章