2012-08-22 12:32:13 +08:00
# ifndef __KERN_MM_MEMLAYOUT_H__
# define __KERN_MM_MEMLAYOUT_H__
/* This file contains the definitions for memory management in our OS. */
/* global segment number */
# define SEG_KTEXT 1
# define SEG_KDATA 2
# define SEG_UTEXT 3
# define SEG_UDATA 4
# define SEG_TSS 5
/* global descrptor numbers */
# define GD_KTEXT ((SEG_KTEXT) << 3) // kernel text
# define GD_KDATA ((SEG_KDATA) << 3) // kernel data
# define GD_UTEXT ((SEG_UTEXT) << 3) // user text
# define GD_UDATA ((SEG_UDATA) << 3) // user data
# define GD_TSS ((SEG_TSS) << 3) // task segment selector
# define DPL_KERNEL (0)
# define DPL_USER (3)
# define KERNEL_CS ((GD_KTEXT) | DPL_KERNEL)
# define KERNEL_DS ((GD_KDATA) | DPL_KERNEL)
# define USER_CS ((GD_UTEXT) | DPL_USER)
# define USER_DS ((GD_UDATA) | DPL_USER)
/* *
* Virtual memory map : Permissions
* kernel / user
*
* 4 G - - - - - - - - - - - - - - - - - - > + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
* | |
* | Empty Memory ( * ) |
* | |
* + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + 0xFB000000
* | Cur . Page Table ( Kern , RW ) | RW / - - PTSIZE
* VPT - - - - - - - - - - - - - - - - - > + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + 0xFAC00000
* | Invalid Memory ( * ) | - - / - -
* KERNTOP - - - - - - - - - - - - - > + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + 0xF8000000
* | |
* | Remapped Physical Memory | RW / - - KMEMSIZE
* | |
* KERNBASE - - - - - - - - - - - - > + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + 0xC0000000
* | Invalid Memory ( * ) | - - / - -
* USERTOP - - - - - - - - - - - - - > + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + 0xB0000000
* | User stack |
* + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
* | |
* : :
* | ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ |
* : :
* | |
* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
* | User Program & Heap |
* UTEXT - - - - - - - - - - - - - - - > + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + 0x00800000
* | Invalid Memory ( * ) | - - / - -
* | - - - - - - - - - - - - - - - |
* | User STAB Data ( optional ) |
* USERBASE , USTAB - - - - - - > + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + 0x00200000
* | Invalid Memory ( * ) | - - / - -
* 0 - - - - - - - - - - - - - - - - - - - > + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + 0x00000000
* ( * ) Note : The kernel ensures that " Invalid Memory " is * never * mapped .
* " Empty Memory " is normally unmapped , but user programs may map pages
* there if desired .
*
* */
/* All physical memory mapped at this address */
# define KERNBASE 0xC0000000
# define KMEMSIZE 0x38000000 // the maximum amount of physical memory
# define KERNTOP (KERNBASE + KMEMSIZE)
/* *
* Virtual page table . Entry PDX [ VPT ] in the PD ( Page Directory ) contains
* a pointer to the page directory itself , thereby turning the PD into a page
* table , which maps all the PTEs ( Page Table Entry ) containing the page mappings
* for the entire virtual address space into that 4 Meg region starting at VPT .
* */
# define VPT 0xFAC00000
# define KSTACKPAGE 2 // # of pages in kernel stack
# define KSTACKSIZE (KSTACKPAGE * PGSIZE) // sizeof kernel stack
# define USERTOP 0xB0000000
# define USTACKTOP USERTOP
# define USTACKPAGE 256 // # of pages in user stack
# define USTACKSIZE (USTACKPAGE * PGSIZE) // sizeof user stack
# define USERBASE 0x00200000
# define UTEXT 0x00800000 // where user programs generally begin
# define USTAB USERBASE // the location of the user STABS data structure
# define USER_ACCESS(start, end) \
( USERBASE < = ( start ) & & ( start ) < ( end ) & & ( end ) < = USERTOP )
# define KERN_ACCESS(start, end) \
( KERNBASE < = ( start ) & & ( start ) < ( end ) & & ( end ) < = KERNTOP )
# ifndef __ASSEMBLER__
# include <defs.h>
# include <atomic.h>
# include <list.h>
typedef uintptr_t pte_t ;
typedef uintptr_t pde_t ;
typedef pte_t swap_entry_t ; //the pte can also be a swap entry
// some constants for bios interrupt 15h AX = 0xE820
# define E820MAX 20 // number of entries in E820MAP
# define E820_ARM 1 // address range memory
# define E820_ARR 2 // address range reserved
struct e820map {
int nr_map ;
struct {
uint64_t addr ;
uint64_t size ;
uint32_t type ;
} __attribute__ ( ( packed ) ) map [ E820MAX ] ;
} ;
/* *
* struct Page - Page descriptor structures . Each Page describes one
* physical page . In kern / mm / pmm . h , you can find lots of useful functions
* that convert Page to other data types , such as phyical address .
* */
struct Page {
2012-09-14 21:36:57 +08:00
int ref ; // page frame's reference counter
2012-08-22 12:32:13 +08:00
uint32_t flags ; // array of flags that describe the status of the page frame
2012-10-01 22:21:31 +08:00
unsigned int property ; // the num of free block, used in first fit pm manager
2012-08-22 12:32:13 +08:00
list_entry_t page_link ; // free list link
list_entry_t pra_page_link ; // used for pra (page replace algorithm)
uintptr_t pra_vaddr ; // used for pra (page replace algorithm)
} ;
/* Flags describing the status of a page frame */
2012-10-01 22:21:31 +08:00
# define PG_reserved 0 // if this bit=1: the Page is reserved for kernel, cannot be used in alloc/free_pages; otherwise, this bit=0
# define PG_property 1 // if this bit=1: the Page is the head page of a free memory block(contains some continuous_addrress pages), and can be used in alloc_pages; if this bit=0: if the Page is the the head page of a free memory block, then this Page and the memory block is alloced. Or this Page isn't the head page.
2012-08-22 12:32:13 +08:00
# define SetPageReserved(page) set_bit(PG_reserved, &((page)->flags))
# define ClearPageReserved(page) clear_bit(PG_reserved, &((page)->flags))
# define PageReserved(page) test_bit(PG_reserved, &((page)->flags))
# define SetPageProperty(page) set_bit(PG_property, &((page)->flags))
# define ClearPageProperty(page) clear_bit(PG_property, &((page)->flags))
# define PageProperty(page) test_bit(PG_property, &((page)->flags))
// convert list entry to page
# define le2page(le, member) \
to_struct ( ( le ) , struct Page , member )
/* free_area_t - maintains a doubly linked list to record free (unused) pages */
typedef struct {
list_entry_t free_list ; // the list header
unsigned int nr_free ; // # of free pages in this free list
} free_area_t ;
/* for slab style kmalloc */
# define PG_slab 2 // page frame is included in a slab
# define SetPageSlab(page) set_bit(PG_slab, &((page)->flags))
# define ClearPageSlab(page) clear_bit(PG_slab, &((page)->flags))
# define PageSlab(page) test_bit(PG_slab, &((page)->flags))
# endif /* !__ASSEMBLER__ */
# endif /* !__KERN_MM_MEMLAYOUT_H__ */