2018-08-30 12:17:20 -07:00
|
|
|
#ifndef JOS_INC_MEMLAYOUT_H
|
|
|
|
#define JOS_INC_MEMLAYOUT_H
|
|
|
|
|
|
|
|
#ifndef __ASSEMBLER__
|
|
|
|
#include <inc/types.h>
|
|
|
|
#include <inc/mmu.h>
|
|
|
|
#endif /* not __ASSEMBLER__ */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This file contains definitions for memory management in our OS,
|
|
|
|
* which are relevant to both the kernel and user-mode software.
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Global descriptor numbers
|
|
|
|
#define GD_KT 0x08 // kernel text
|
|
|
|
#define GD_KD 0x10 // kernel data
|
|
|
|
#define GD_UT 0x18 // user text
|
|
|
|
#define GD_UD 0x20 // user data
|
|
|
|
#define GD_TSS0 0x28 // Task segment selector for CPU 0
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Virtual memory map: Permissions
|
|
|
|
* kernel/user
|
|
|
|
*
|
|
|
|
* 4 Gig --------> +------------------------------+
|
|
|
|
* | | RW/--
|
|
|
|
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
* : . :
|
|
|
|
* : . :
|
|
|
|
* : . :
|
|
|
|
* |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| RW/--
|
|
|
|
* | | RW/--
|
|
|
|
* | Remapped Physical Memory | RW/--
|
|
|
|
* | | RW/--
|
|
|
|
* KERNBASE, ----> +------------------------------+ 0xf0000000 --+
|
|
|
|
* KSTACKTOP | CPU0's Kernel Stack | RW/-- KSTKSIZE |
|
|
|
|
* | - - - - - - - - - - - - - - -| |
|
|
|
|
* | Invalid Memory (*) | --/-- KSTKGAP |
|
|
|
|
* +------------------------------+ |
|
|
|
|
* | CPU1's Kernel Stack | RW/-- KSTKSIZE |
|
|
|
|
* | - - - - - - - - - - - - - - -| PTSIZE
|
|
|
|
* | Invalid Memory (*) | --/-- KSTKGAP |
|
|
|
|
* +------------------------------+ |
|
|
|
|
* : . : |
|
|
|
|
* : . : |
|
|
|
|
* MMIOLIM ------> +------------------------------+ 0xefc00000 --+
|
|
|
|
* | Memory-mapped I/O | RW/-- PTSIZE
|
|
|
|
* ULIM, MMIOBASE --> +------------------------------+ 0xef800000
|
|
|
|
* | Cur. Page Table (User R-) | R-/R- PTSIZE
|
|
|
|
* UVPT ----> +------------------------------+ 0xef400000
|
|
|
|
* | RO PAGES | R-/R- PTSIZE
|
|
|
|
* UPAGES ----> +------------------------------+ 0xef000000
|
|
|
|
* | RO ENVS | R-/R- PTSIZE
|
|
|
|
* UTOP,UENVS ------> +------------------------------+ 0xeec00000
|
|
|
|
* UXSTACKTOP -/ | User Exception Stack | RW/RW PGSIZE
|
|
|
|
* +------------------------------+ 0xeebff000
|
|
|
|
* | Empty Memory (*) | --/-- PGSIZE
|
|
|
|
* USTACKTOP ---> +------------------------------+ 0xeebfe000
|
|
|
|
* | Normal User Stack | RW/RW PGSIZE
|
|
|
|
* +------------------------------+ 0xeebfd000
|
|
|
|
* | |
|
|
|
|
* | |
|
|
|
|
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
* . .
|
|
|
|
* . .
|
|
|
|
* . .
|
|
|
|
* |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|
|
|
|
|
* | Program Data & Heap |
|
|
|
|
* UTEXT --------> +------------------------------+ 0x00800000
|
|
|
|
* PFTEMP -------> | Empty Memory (*) | PTSIZE
|
|
|
|
* | |
|
|
|
|
* UTEMP --------> +------------------------------+ 0x00400000 --+
|
|
|
|
* | Empty Memory (*) | |
|
|
|
|
* | - - - - - - - - - - - - - - -| |
|
|
|
|
* | User STAB Data (optional) | PTSIZE
|
|
|
|
* USTABDATA ----> +------------------------------+ 0x00200000 |
|
|
|
|
* | Empty Memory (*) | |
|
|
|
|
* 0 ------------> +------------------------------+ --+
|
|
|
|
*
|
|
|
|
* (*) Note: The kernel ensures that "Invalid Memory" is *never* mapped.
|
|
|
|
* "Empty Memory" is normally unmapped, but user programs may map pages
|
|
|
|
* there if desired. JOS user programs map pages temporarily at UTEMP.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
// All physical memory mapped at this address
|
|
|
|
#define KERNBASE 0xF0000000
|
|
|
|
|
|
|
|
// At IOPHYSMEM (640K) there is a 384K hole for I/O. From the kernel,
|
|
|
|
// IOPHYSMEM can be addressed at KERNBASE + IOPHYSMEM. The hole ends
|
|
|
|
// at physical address EXTPHYSMEM.
|
|
|
|
#define IOPHYSMEM 0x0A0000
|
|
|
|
#define EXTPHYSMEM 0x100000
|
|
|
|
|
|
|
|
// Kernel stack.
|
|
|
|
#define KSTACKTOP KERNBASE
|
|
|
|
#define KSTKSIZE (8*PGSIZE) // size of a kernel stack
|
|
|
|
#define KSTKGAP (8*PGSIZE) // size of a kernel stack guard
|
|
|
|
|
|
|
|
// Memory-mapped IO.
|
|
|
|
#define MMIOLIM (KSTACKTOP - PTSIZE)
|
|
|
|
#define MMIOBASE (MMIOLIM - PTSIZE)
|
|
|
|
|
|
|
|
#define ULIM (MMIOBASE)
|
|
|
|
|
|
|
|
/*
|
|
|
|
* User read-only mappings! Anything below here til UTOP are readonly to user.
|
|
|
|
* They are global pages mapped in at env allocation time.
|
|
|
|
*/
|
|
|
|
|
|
|
|
// User read-only virtual page table (see 'uvpt' below)
|
|
|
|
#define UVPT (ULIM - PTSIZE)
|
|
|
|
// Read-only copies of the Page structures
|
|
|
|
#define UPAGES (UVPT - PTSIZE)
|
|
|
|
// Read-only copies of the global env structures
|
|
|
|
#define UENVS (UPAGES - PTSIZE)
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Top of user VM. User can manipulate VA from UTOP-1 and down!
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Top of user-accessible VM
|
|
|
|
#define UTOP UENVS
|
|
|
|
// Top of one-page user exception stack
|
|
|
|
#define UXSTACKTOP UTOP
|
|
|
|
// Next page left invalid to guard against exception stack overflow; then:
|
|
|
|
// Top of normal user stack
|
|
|
|
#define USTACKTOP (UTOP - 2*PGSIZE)
|
|
|
|
|
|
|
|
// Where user programs generally begin
|
|
|
|
#define UTEXT (2*PTSIZE)
|
|
|
|
|
|
|
|
// Used for temporary page mappings. Typed 'void*' for convenience
|
|
|
|
#define UTEMP ((void*) PTSIZE)
|
|
|
|
// Used for temporary page mappings for the user page-fault handler
|
|
|
|
// (should not conflict with other temporary page mappings)
|
|
|
|
#define PFTEMP (UTEMP + PTSIZE - PGSIZE)
|
|
|
|
// The location of the user-level STABS data structure
|
|
|
|
#define USTABDATA (PTSIZE / 2)
|
|
|
|
|
2018-10-06 06:52:47 -07:00
|
|
|
// Physical address of startup code for non-boot CPUs (APs)
|
|
|
|
#define MPENTRY_PADDR 0x7000
|
|
|
|
|
2018-08-30 12:17:20 -07:00
|
|
|
#ifndef __ASSEMBLER__
|
|
|
|
|
|
|
|
typedef uint32_t pte_t;
|
|
|
|
typedef uint32_t pde_t;
|
|
|
|
|
2018-09-12 11:55:07 -07:00
|
|
|
#if JOS_USER
|
|
|
|
/*
|
|
|
|
* The page directory entry corresponding to the virtual address range
|
|
|
|
* [UVPT, UVPT + PTSIZE) points to the page directory itself. Thus, the page
|
|
|
|
* directory is treated as a page table as well as a page directory.
|
|
|
|
*
|
|
|
|
* One result of treating the page directory as a page table is that all PTEs
|
|
|
|
* can be accessed through a "virtual page table" at virtual address UVPT (to
|
|
|
|
* which uvpt is set in lib/entry.S). The PTE for page number N is stored in
|
|
|
|
* uvpt[N]. (It's worth drawing a diagram of this!)
|
|
|
|
*
|
|
|
|
* A second consequence is that the contents of the current page directory
|
|
|
|
* will always be available at virtual address (UVPT + (UVPT >> PGSHIFT)), to
|
|
|
|
* which uvpd is set in lib/entry.S.
|
|
|
|
*/
|
|
|
|
extern volatile pte_t uvpt[]; // VA of "virtual page table"
|
|
|
|
extern volatile pde_t uvpd[]; // VA of current page directory
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Page descriptor structures, mapped at UPAGES.
|
|
|
|
* Read/write to the kernel, read-only to user programs.
|
|
|
|
*
|
|
|
|
* Each struct PageInfo stores metadata for one physical page.
|
|
|
|
* Is it NOT the physical page itself, but there is a one-to-one
|
|
|
|
* correspondence between physical pages and struct PageInfo's.
|
|
|
|
* You can map a struct PageInfo * to the corresponding physical address
|
|
|
|
* with page2pa() in kern/pmap.h.
|
|
|
|
*/
|
|
|
|
struct PageInfo {
|
|
|
|
// Next page on the free list.
|
|
|
|
struct PageInfo *pp_link;
|
|
|
|
|
|
|
|
// pp_ref is the count of pointers (usually in page table entries)
|
|
|
|
// to this page, for pages allocated using page_alloc.
|
|
|
|
// Pages allocated at boot time using pmap.c's
|
|
|
|
// boot_alloc do not have valid reference count fields.
|
|
|
|
|
|
|
|
uint16_t pp_ref;
|
|
|
|
};
|
|
|
|
|
2018-08-30 12:17:20 -07:00
|
|
|
#endif /* !__ASSEMBLER__ */
|
|
|
|
#endif /* !JOS_INC_MEMLAYOUT_H */
|