Linux Kernel Explorer memory management (III): Page table

Source: Internet
Author: User

The main reference is "deep Linux kernel Architecture", "deep understanding of Linux kernel" and kernel linux-3.18.3

The page table is used to establish a mapping between the virtual address space of the user process and the physical memory (memory, page frame) of the system. IA-32 The system uses a two-level paging system by default, but the kernel always uses a Level four page table, and the third and fourth level page tables are modeled by architecture-specific code.

Page table management is divided into two parts, the first part depends on the architecture, the second part of the architecture is independent. But almost all of the data structures and operations data structures are defined in architecture-specific files. These data structures and functions are usually found in include/asm-arch/page.h and include/asm-arch/pgtable.h , referred to as PAGH.H and pgtable.h. However , the files for the IA-32 and AMD64 platforms are:arch/asm-x86/page_32.h, arch/asm-x86/page_64.h .

Data

1. Decomposition of memory addresses

Virtual memory addresses are divided into 5 PartsAccording to the needs of the four-level page table (4 table entries are used to select the page, and1 indexes represent the in-page location). Each architecture not only has different address Zichang, but also the address word splitting method, the kernel defines a macro that is used to decompose the address into components.



More Intuitive Description:


Each process has its own page global catalog and its own set of page tables. When a process switch occurs, Linux stores the contents of the CR3 control register in the descriptor of the current execution process. Then load the value of the next descriptor to execute into the CR3 Register, and beware that the paging unit can point to the correct page table when the process restarts on the CPU .

Bit_per_long: Represents the number of bits used to unsigned a LONG variable

Page_shift: Represents several bits at the end of each pointer to specify the position within the selected page frame

Pmd_shift: Specifies the total number of bits required for the in-page offset and last-level page table. This value subtracts the number of bits required for the last-level index that page_shift can have. This value indicates the size of a partial address space that is managed by a middle-tier page table entry, which is 2^pmd_shift bytes.

Pud_shift: The bit length required by the pmd_shift plus the middle-tier page table index.

Pgdir_shift is the bit length required by Pud_shift plus the upper page table index. Calculates the base 2 logarithm of a portion of the address space that can be addressed by an item in the global catalog , that is, pgdir_shift.

The number of pointers that can be stored in a directory / page table on all levels of the page can be determined by the macro definition. PTRS_PER_PGD Specifies the number of items in the Global page catalog. ptrs_per_pmd corresponds to the middle page directory,ptrs_per_pud corresponds to the number of items in the upper page directory,ptrs_per_pte is the number of items in the page table. PTRS_PER_PMD and ptrs_per_pud are defined as 1in the architecture of the Level two page table. This makes the rest of the kernel feel that the architecture also provides a four-level page conversion structure, although there is actually only a Level two page table. The middle-tier page directory and the upper-level page directory are virtually eliminated.


Related header files:

Include/asm-generic/pgtable-nopud.h is used to provide all the declarations required to simulate the upper-level page directory;

The Include/asm-generic/pgtable-nopmd.h is used to emulate a middle-tier page table on a system with only level two address translation.

N -bit-long address addressable address area length is 2^n bytes. The kernel defines additional macro variables to hold the computed values to avoid repeated calculations. The relevant macro definitions are as follows:


Include/asm-generic/page.h: #define Page_shift 12#ifdef __assembly__#define page_size (1 << page_shift) #el Se#define page_size (1UL << page_shift) #endif # define PAGE_MASK (~ (page_size-1)) Include/asm-generic/pgtab Le-nopud.h: #define Pud_shift pgdir_shift#define ptrs_per_pud 1#define pud_size (1UL << Pud_shift) Inc Lude/asm-generic/pgtable-nopmd.h: #define Pmd_shift pud_shift#define PTRS_PER_PMD 1#define PMD_SIZE (1UL &l t;< pmd_shift) #define PMD_MASK (~ (pmd_size-1))./include/asm/pgtable_32_types.h: #define PGDIR_SIZE (1UL <& Lt Pgdir_shift)./include/asm/pgtable-2level_types.h: #define Pgdir_shift 22#define PTRS_PER_PGD 1024./include/asm /pgtable-3level_types.h: #define Pgdir_shift 30#define PTRS_PER_PGD 4./include/asm/pgtable_64_types.h: #define Pgdir_shift 39#define PTRS_PER_PGD 512

Ptr_per_xxx Specifies how many pointers a given catalog item can represent. Because x64 uses 9 bits per page table index , each page table can hold 2^9=512 pointers.

The kernel also needs a way to extract individual components from a given address. The kernel uses a bitmask defined below to do the work.

#define PAGE_MASK (~ (page_size-1)) #define PUD_MASK (~ (pud_size-1)) #define PMD_MASK (~ (pmd_size-1)) #define Pud_ Maskpgdir_mask

2. Format of page table

The above definition already establishes the number of page table entries, but does not define their structure. The kernel provides 4 Data Structures (pagh.h) to represent the structure of a page table entry:

pgd_t for global page catalog entries

pud_t for upper page directory entries

pmd_t for intermediate page catalog entries

pte_t for direct page table entries

include/asm-generic/page.h:typedef struct {        unsigned long pte;} pte_t;typedef struct {        unsigned long pmd[16];} pmd_t;typedef struct {        unsigned long pgd;} pgd_t;typedef struct {        unsigned long Pgprot;} pgprot_t;typedef Struc T page *pgtable_t;

Functions for parsing page table entries:

Function

Describe

Include/asm-generic/page.h:

#define PTE_VAL (x) ((x). Pte)

#define PMD_VAL (x) ((&x)->pmd[0])

#define PGD_VAL (x) ((x). PGD)

#define PGPROT_VAL (x) ((x). Pgprot)

Converts a variable of type pte_t to a unsigned long integer

Include/asm-generic/page.h:

#define &NBSP;__PTE (x)           ((pte_t)  {  (x)  } )

#define &NBSP;__PMD (x)           ((pmd_t)  {  (x)  } )

#define &NBSP;__PGD (x)           ((pgd_t)  {  (x)  } )

#define  __pgprot (x)        ((pgprot_t)  {  (x)  } )

Pgd_val unsigned long pgd_t

Arch/x86/include/asm/pgtable.h:

#define &NBSP;PGD_INDEX (address)   ((address)  >> pgdir_shift)  &  (ptrs_per_pgd - 1)

static inline  Unsigned long pud_index (unsigned long address)

static inline unsigned  long pte_index (unsigned long address)

Static inline unsigned long  pmd_index (unsigned long address)

Get the address of the next Level page table from memory Pointers and page table entries

static inline int pgd_present (pgd_t PGD)

static inline int pte_present (pte_t a)

static inline int pmd_present (pmd_t PMD)

static inline int pud_present (pud_t pud)

Checks whether the _present bit of the corresponding item is set. If the item corresponds to a page table or page in memory, it is placed

static inline int Pgd_none (pgd_t PGD)

static inline int Pte_none (pte_t Pte)

static inline int Pmd_none (pmd_t PMD)

static inline int pud_none (pud_t pud)

The value of the _present function is logically flipped. If true, the page being checked is not in memory

#define  pgd_clear (PGD)                    native_pgd_clear (PGD)

#define &NBSP;PUD_CLEAR (PUD)                    Native_pud_clear (PUD)

#define &NBSP;PTE_CLEAR (Mm, addr, ptep)         native_pte_clear (mm, addr, ptep)

#define &NBSP;PMD_CLEAR (PMD)                    native_pmd_clear (PMD

Delete the passed page table entry, usually set it to zero

static inline int Pmd_bad (pmd_t PMD)

static inline int Pud_bad (pud_t pud)

static inline int Pgd_bad (pgd_t PGD)

static inline int Pmd_bad (pmd_t PMD)

Checks if the entry for the middle-tier page table, upper-level page table, global page table is invalid. If the function receives input parameters externally, it is not possible to assume that the parameters are valid, and to ensure security, these functions can be called to check

#define PUD_PAGE (PUD) pfn_to_page (Pud_val (PUD) >> page_shift)

#define Pgd_page (PGD) pfn_to_page (Pgd_val (PGD) >> page_shift)

#define PTE_PAGE (PTE) Pfn_to_page (PTE_PFN (PTE))

Returns the item of the page structure or the intermediate page catalog that holds the data

Static inline pmd_t *pmd_offset (pud_t *pud, unsigned long address)

Static inline pud_t *pud_offset (pgd_t *pgd, unsigned long address)

#define PGD_OFFSET (mm, address) ((mm)->PGD + pgd_index (address))

#define PGD_OFFSET_K (Address) Pgd_offset (&init_mm, (address))

Receives the memory description address, and the address of the linear address, which generates the address addr in the corresponding table entry of the linear address or directory entry


Not to be continued:

Pte Specific (page table information)


Linux Kernel Explorer memory management (III): Page table

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.