Linux 32位处理器下地址转换
1. 物理地址结构
物理内存(主存)结构如下:
内存管理按页帧管理,一页大小一般在正常情况(PSE=0)下为4KB,
在LINUX系统中定义宏:
#define page_size 4096
#define page _shift 12
由于线性地址只有
2. 线性地址
实际在Linux中线性地址以0XC000 0000(
小于
#define PAGE_OFFSET 0xC000 0000
Linear Address = __va(physical address ) = physical address + PAGE_OFFSET
Physical Address = __pa(Linear address ) = Linear address - PAGE_OFFSET
对于后128MB线性地址到底映射到物理内存的那个位置,则需要建立一些映像关系,具体可分为:永久映射,临时映射和非连续性物理内存映射。
3. 物理页帧
实际对于物理内存的管理是按照页帧来管理的,由于页的大小是相同的,所以可以对页按照顺序来编号,只要记住页帧号,也就可以定位到相应得页。
实际在Linux中的实现是定义一个数组,数组的大小和页的总数量一致,这样数组的元素可以和页实现一一对应,只需记住数组的首地址,则可实现对物理页帧的访问。
4. 地址转换
由于物理内存是按照页来管理的,所以对于内存按照字节或其他的方式来管理的意义并不实际,因此Linux内存也是以页为单位来管理的,在类似Mem_map数组(可能是其他变量指向的数组)内存放的实际是每个物理页的描述符(描述每页的属性信息)页描述符“1”实际对应物理页“1”,这要内核在管理内存时只需管理和传递这些内存描述符线性地址即可。
页描述符index = 页描述符线性地址 – 数组基址
物理页帧号pfn = 页描述符index + 数组第一项对应页帧号
物理页地址 = 物理页帧号pfn << PAGE_SIZE
因此通过上面一些转换关系,再加上前面的__va() 和__pa()宏定义就可以实现页描述符与物理地址和线性地址之间的转换
pfn_to_page(pfn) :输入页帧号输出页描述符
pfn_to_kadd(pfn) :输入页帧号输出线性地址
pfn_to_phy(pfn) :输入页帧号输出物理地址
5. 页目录与页表 (待续)
评论