内存映射和DMA——Linux 的内存管理
地址类型:
用户虚拟地址:这是用户空间程序能看到的常规地址。
物理地址:该地址在处理器和系统内存之间使用。
总线地址:该地址在外设总线和内存之间使用。
内核逻辑地址:组成了内核的常规地址空间。该地至映射了部分内存,并经常被视为物理地址,在大多数体系结构中,逻辑地址与相关的物理地址的不同,仅仅在于它们之间相差一个固定的偏移量。逻辑地址通常保存在UNSIGNED LONG ,和void*这样的内存变量中,用kmalloc返回的内存地址,就是内核逻辑地址。
内核虚拟地址:与逻辑地址相比,它与物理地址的映射不是线性和一一对应的。所有的逻辑地址都是虚拟地址,而虚拟地址不一定是逻辑地址。虚拟地址通常保存在指针变量中。
物理地址和页:
物理地址被分为很多离散单元称为页,ARM中一个页的大小为4096字节/* PAGE_SHIFT determines the page size */
#define PAGE_SHIFT 12 移动12位即得页帧数
#define PAGE_SIZE (1UL 低端内存:存在于内核空间上的逻辑地址内存。
高端内存:指那些不存在逻辑地址的内存,它们处于内核虚拟地址之上。
内存映射和页结构:
在高端内存中将无法使用逻辑地址,内存中处理内存的函数使用page结构的指针。
page结构中与驱动相关的成员:
atomic—t count;对该页的访问计数。
void *virtual: 如果该页被预设,则指向该页的虚拟地址,否则为NULL。
内核中维护一个或多个page数组,用来跟踪系统中的物理内存。
PAGE结构指针与虚拟地址之间的转换相关的宏:
struct page *virt_to_page(void *kaddr);
用来负责将逻辑地址转换为相应的page结构指针。
struct page *pfn_to_page(int pfn);
通过给定的页祯号,返回page结构指针。
void *page_address(struct page*page);
如果地址的话,返回该页的虚拟地址。