正文

Linux 32位处理器下地址转换 (1)2007-10-07 20:16:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/ljqy/29943.html

分享到:

Linux 32位处理器下地址转换

 

 

1.   物理地址结构

物理内存(主存)结构如下:

 

内存管理按页帧管理,一页大小一般在正常情况(PSE=0)下为4KB

 

 

LINUX系统中定义宏:

#define page_size  4096

#define page _shift 12

  

 

由于线性地址只有4G32b),所以最多只能直接映射4G的物理地址,然而实际的物理内存可能远比4G大,因此有限的线性地址如何去映射产生了问题?!

 

 

 

 

 

2.   线性地址

实际在Linux中线性地址以0XC000 00003G)为分界线做了如下划分:

 

 

小于3G的线性地址用户模式和内核模式下都能访问或使用,但3G以上的地址空间只能在内核模式下直接使用。而且对于内存的管理是由内核来负责的,并只使用第3G来完成。同时前896MB线性地址直接映射物理内存的前896MB,后128MB的线性地址用来动态映射剩余的物理地址,最终实现使用1G的线性地址来映射大于1G的物理内存。对于前896MB由于是用直接映射来实现,所以系统定义了一些宏来简单的实现地址的转换:

 

#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.   页目录与页表 (待续)

 

 

阅读(3115) | 评论(2)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

loading...
您需要登录后才能评论,请 登录 或者 注册