MMU(Memory Management Unit)
用来管理内存的最小单位是一个物理页面(physical page
,在32-bit
系统上通常每个页面为4k
,64-bit
系统上为8k
)。Linux kernel
使用struct page
结构体(定义在<linux/mm_types.h>
)来代表每个物理页面:
struct page {
/* First double word block */
unsigned long flags; /* Atomic flags, some possibly
* updated asynchronously */
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.
*/
......
}
受制于一些硬件限制,有些物理页面不能用来进行某种操作。所以kernel
把页面分成不同的zone
:
ZONE_DMA
:用来进行DMA
操作的页面;
ZONE_DMA32
:也是用来进行DMA
操作的页面,不过仅针对32-bit
设备;
ZONE_NORMAL
:包含常规的,用来映射的页面;
ZONE_HIGHMEM
:包含不能永久地映射到kernel
的地址空间(address space
)的页面。
还有其它的zone
定义(例如:ZONE_MOVABLE
)。zone_type
定义在 <linux/mmzone.h>
文件里:
enum zone_type {
#ifdef CONFIG_ZONE_DMA
/*
* ZONE_DMA is used when there are devices that are not able
* to do DMA to all of addressable memory (ZONE_NORMAL). Then we
* carve out the portion of memory that is needed for these devices.
* The range is arch specific.
*
* Some examples
*
* Architecture Limit
* ---------------------------
* parisc, ia64, sparc <4G
* s390 <2G
* arm Various
* alpha Unlimited or 0-16MB.
*
* i386, x86_64 and multiple other arches
* <16M.
*/
ZONE_DMA,
#endif
#ifdef CONFIG_ZONE_DMA32
/*
* x86_64 needs two ZONE_DMAs because it supports devices that are
* only able to do DMA to the lower 16M but also 32 bit devices that
* can only do DMA areas below 4G.
*/
ZONE_DMA32,
#endif
/*
* Normal addressable memory is in ZONE_NORMAL. DMA operations can be
* performed on pages in ZONE_NORMAL if the DMA devices support
* transfers to all addressable memory.
*/
ZONE_NORMAL,
#ifdef CONFIG_HIGHMEM
/*
* A memory area that is only addressable by the kernel through
* mapping portions into its own address space. This is for example
* used by i386 to allow the kernel to address the memory beyond
* 900MB. The kernel will set up special mappings (page
* table entries on i386) for each page that the kernel needs to
* access.
*/
ZONE_HIGHMEM,
#endif
ZONE_MOVABLE,
__MAX_NR_ZONES
};
如果CPU
体系结构允许DMA
操作访问任何地址空间,那就没有ZONE_DMA
。同理,Intel X86_64
处理器可以访问所有的内存空间,也就不存在ZONE_HIGHMEM
。 关于“High memory
”,可以参考这篇文章。