内核的存储管理是以page为单位的,每个page的大小为4K,且每个page都用一个page结构体来进行描述,这些page的描述做为一个数组放在内核代码之后。因而这里就涉及到3个量:一个是4K的实际页面的地址,即物理地址,在内核中表示为Virtual Address;另一个为描述此页面的page结构指针,用page表示;还有一个是这个page结构体在整个page数组中的序号,内核称之为pfn。这三个地址之间可以用6个宏来进行相互转换。page结构体的定义在include/linux/mm_types.h中:/** Each physical page in the system has a struct page associated with* it to keep track of whatever it is we are using the page for at the* moment. Note that we have no way to track which tasks are using* a page, though if it is a pagecache page, rmap structures can tell us* who is mapping it.*/struct page {unsignedlong flags;/* Atomic flags, some possibly* updated asynchronously */atomic_t _count;/* Usage count, see below. */union {atomic_t _mapcount;/* Count of ptes mapped in mms,* to show when page is mapped* & limit reverse map searches.*/struct {/* SLUB uses */shortunsignedint inuse;shortunsignedint offset;};};union {struct {unsignedlongprivate;/* Mapping-private opaque data:* usually used for buffer_heads* if PagePrivate set; used for* swp_entry_t if PageSwapCache;* indicates order in the buddy* system if PG_buddy is set.*/struct address_space *mapping;/* If low bit clear, points to* inode address_space, or NULL.* If page mapped as anonymous* memory, low bit is set, and* it points to anon_vma object:* see PAGE_MAPPING_ANON below.*/};spinlock_t ptl;struct {/* SLUB uses */void **lockless_freelist;struct kmem_cache *slab;/* Pointer to slab */};struct {struct page *first_page;/* Compound pages */};};union {pgoff_t index;/* Our offset within mapping. */void *freelist;/* SLUB: freelist req. slab lock */};struct list_head lru;/* Pageout list, eg. active_list* protected by zone->lru_lock !*/};llru这个结构体根据这个页面应用的不同有不同的含义,当此页面空闲时或者此页面用于高速缓存时,这个结构体用于将页面链接起来的双链表。而当此页面用于SLAB算法时,它的next指针将指向这个slab所在的cache,即一个kmem_cache的结构体。而其prev指针将指向这个slab。这两个指针都是通过slab_map_pages函数进行设置的。lflags这个结构体中的flags成员每个位的定义在include/linux/page_flags.h中:/** Various page->flags bits:** PG_reserved is set for special pages, which can never be swapped out. Some* of them might not even exist (eg empty_bad_page)...** The PG_private bitflag is set on pagecache pages if they contain filesystem* specific data (which is normally at page->private). It can be used by* private allocations for its own usage.** During initiation of disk I/O, PG_locked is set. This bit is set before I/O* and cleared when writeback _starts_ or when read _completes_. PG_writeback* is set before writeback starts and cleared when it finishes.** PG_locked also pins a page in pagecache, and blocks truncation of the file* while it is held.** page_waitqueue(page) is a wait queue of all tasks waiting for the page* to become unlocked.** PG_uptodate tells whether the page's contents is valid.When a read* completes, the page becomes uptodate, unless a disk I/O error happened.** PG_referenced, PG_reclaim are used for page reclaim for anonymous and* file-backed pagecache (see mm/vmscan.c).** PG_error is set to indicate that an I/O error occurred on this page.** PG_arch_1 is an architecture specific page state bit.The generic code* guarantees that this bit is cleared for a page when it first is entered into* the page cache.** PG_highmem pages are not permanently mapped into the kernel virtual address* space, they need to be kmapped separately for doing IO on the pages.The* struct page (these bits with information) are always mapped into kernel* address space...** PG_buddy is set to indicate that the page is free and in the buddy system* (see mm/page_alloc.c).**//** Don't use the *_dontuse flags.Use the macros.Otherwise you'll break* locked- and dirty-page accounting.** The page flags field is split into two parts, the main flags area* which extends from the low bits upwards, and the fields area which* extends from the high bits downwards.**| FIELD | ... | FLAGS |*N-1^0*(N-FLAGS_RESERVED)** The fields area is reserved for fields mapping zone, node and SPARSEMEM* section.The boundry between these two areas is defined by* FLAGS_RESERVED which defines the width of the fields section* (see linux/mmzone.h).New flags must _not_ overlap with this area.*/#define PG_locked0/* Page is locked. Don't touch. */#define PG_error1#define PG_referenced2#define PG_uptodate3#define PG_dirty4#define PG_lru5#define PG_active6#define PG_slab7/* slab debug (Suparna wants this) */#define PG_owner_priv_18/* Owner use. If pagecache, fs may use*/#define PG_arch_19#define PG_reserved10#define PG_private11/* If pagecache, has fs-private data */#define PG_writeback12/* Page is under writeback */#define PG_compound14/* Part of a compound page */#define PG_swapcache15/* Swap page: swp_entry_t in private */#define PG_mappedtodisk16/* Has blocks allocated on-disk */#define PG_reclaim17/* To be reclaimed asap */#define PG_buddy19/* Page is free, on buddy lists *//* PG_owner_priv_1 users should have descriptive aliases */#define PG_che