返回列表 发帖

Linux板级内存管理之-内核的页,页框,页帧

Linux板级内存管理之-内核的页,页框,页帧

Linux板级内存管理之-内核的页,页框,页帧


osboy - mcuos.com站长原创


mcuos.com@gmail.com




Linux的页描述符page管理的物理内存,他把物理内存划分为4kbyte大小的页框,用页描述符记录这些页框的状态,并统一放到structpage *mem_map数组中

下面我们来看一张图:


如果我们知道物理内存的基地址,可以通过上面的图看出,每个页的物理基地址是可知的,这张图也说明了页,页框,页帧之间的关系。
一个物理抽象的“页”有4kbytes的大小,一个4kbytes的页组成图中的框,我们称之为“页框”,而“页帧”则是从0开始数给每个页框用整数编号,以此每个页框的号码为“页帧”号。
从图中可以看出“页帧”左移12位,就是对用“页框”的物理基地址。反之亦然。

那么把这些个概念,用数据结构怎么表示呢?下面我们看看:

对“页”的数据结构表述:

  1. struct page {
  2.         unsigned long flags;                /* Atomic flags, some possibly
  3.                                          * updated asynchronously */
  4.         atomic_t _count;                /* Usage count, see below. */
  5.         union {
  6.                 atomic_t _mapcount;        /* Count of ptes mapped in mms,
  7.                                          * to show when page is mapped
  8.                                          * & limit reverse map searches.
  9.                                          */
  10.                 struct {                /* SLUB */
  11.                         u16 inuse;
  12.                         u16 objects;
  13.                 };
  14.         };
  15.         union {
  16.             struct {
  17.                 unsigned long private;                /* Mapping-private opaque data:
  18.                                                   * usually used for buffer_heads
  19.                                                  * if PagePrivate set; used for
  20.                                                  * swp_entry_t if PageSwapCache;
  21.                                                  * indicates order in the buddy
  22.                                                  * system if PG_buddy is set.
  23.                                                  */
  24.                 struct address_space *mapping;        /* If low bit clear, points to
  25.                                                  * inode address_space, or NULL.
  26.                                                  * If page mapped as anonymous
  27.                                                  * memory, low bit is set, and
  28.                                                  * it points to anon_vma object:
  29.                                                  * see PAGE_MAPPING_ANON below.
  30.                                                  */
  31.             };
  32. #if USE_SPLIT_PTLOCKS
  33.             spinlock_t ptl;
  34. #endif
  35.             struct kmem_cache *slab;        /* SLUB: Pointer to slab */
  36.             struct page *first_page;        /* Compound tail pages */
  37.         };
  38.         union {
  39.                 pgoff_t index;                /* Our offset within mapping. */
  40.                 void *freelist;                /* SLUB: freelist req. slab lock */
  41.         };
  42.         struct list_head lru;                /* Pageout list, eg. active_list
  43.                                          * protected by zone->lru_lock !
  44.                                          */
  45.         /*
  46.          * On machines where all RAM is mapped into kernel address space,
  47.          * we can simply calculate the virtual address. On machines with
  48.          * highmem some memory is mapped into kernel virtual memory
  49.          * dynamically, so we need a place to store that address.
  50.          * Note that this field could be 16 bits on x86 ... ;)
  51.          *
  52.          * Architectures with slow multiplication can define
  53.          * WANT_PAGE_VIRTUAL in asm/page.h
  54.          */
  55. #if defined(WANT_PAGE_VIRTUAL)
  56.         void *virtual;                        /* Kernel virtual address (NULL if
  57.                                            not kmapped, ie. highmem) */
  58. #endif /* WANT_PAGE_VIRTUAL */
  59. #ifdef CONFIG_WANT_PAGE_DEBUG_FLAGS
  60.         unsigned long debug_flags;        /* Use atomic bitops on this */
  61. #endif

  62. #ifdef CONFIG_KMEMCHECK
  63.         /*
  64.          * kmemcheck wants to track the status of each byte in a page; this
  65.          * is a pointer to such a status block. NULL if not tracked.
  66.          */
  67.         void *shadow;
  68. #endif
  69. };
复制代码

内核把内存分成不同的页,而每个页都有个page变量与其相对应,所有的page变量的物理地址组合起来通过一个数组:

  1. struct page *mem_map
复制代码



来表示。可以从上图中看出。

在linux内核中有定义这些变量的转化宏:

arch/arm/mach-xxx/include/mach/memory.h中有,

#define PHYS_OFFSET
UL(0x00000000)

arch/arm/include/asm/memory.h中有:

#define PHYS_PFN_OFFSET
(PHYS_OFFSET >> PAGE_SHIFT)

#define PAGE_SHIFT
12

#define ARCH_PFN_OFFSET
PHYS_PFN_OFFSET

Include/asm-generic/memory-model.h中有:

#if defined(CONFIG_FLATMEM)

#define __pfn_to_page(pfn)
(mem_map + ((pfn) - ARCH_PFN_OFFSET))

#define __page_to_pfn(page)
((unsignedlong)((page) - mem_map) + \



ARCH_PFN_OFFSET)

#define page_to_pfn __page_to_pfn

#define pfn_to_page __pfn_to_page


明白了上面我分析的,那么对这些转换宏定义就一目了然了吧。

附件: 您需要登录才可以下载或查看附件。没有帐号?本站只开放邀请码注册,QQ:82475491,索要邀请码
分享到: QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友

返回列表
网页右侧QQ悬浮滚动在线客服
网页右侧QQ悬浮滚动在线客服