为何要把物理内存地址映射到内核空间?

389 篇文章 30 订阅 ¥19.90 ¥99.00
15 篇文章 0 订阅
32位x86系统限制访问超过896M物理内存,Linux通过映射解决。内核初始化时将物理内存映射到内核空间,仅映射896M,预留128M可能用于内核自身或动态映射。内核地址从物理内存0地址开始,简化虚拟与物理地址转换,如__pa()和__va()。动态映射用于内存大于1G时,且内核空间需预留区域供I/O内存映射。
摘要由CSDN通过智能技术生成

提出这个问题是因为32位的x86如果没有特殊的支持和机制,是无法访问896M以上的物理内存的,这让我很奇怪。虽然内核所分配到的空间是[3G,4G-1),但是这并不代表内核本身的寻址能力是1G呀。

后来看到一篇文章说,linux会在初始化的时候把物理内存映射到内核空间。这也让我很奇怪。linux本身维护了一个page的数组来作为物理内存的“仓库”,这个数组的下标实际上就是物理内存的页面号,linux会在初始化的时候初始化这个数组。我的理解是,后期的虚存到物理内存的映射实际上都落实到了对这个page数组的操作,这就够了。为什么还要把物理内存地址映射到内核空间?

并且,为什么仅仅是896M,剩下的128M内核地址空间去哪儿了?难道剩下的这128M就是内核本身么?如果是的话,那么内核中的各种系统调用、内核数据结构等就都要挤在这个空间里,这样要对这相对所剩无几的空间进行良好的规划,而不是像普通程序那样,一开始就是8开头的虚存空间地址;如果不是的话,那这128M方的又是什么东西,内核自己又躲到哪儿去了?




linux这样做,只是为了简化内核中虚拟地址和物理地址之间相互转化的工作,__va()、__pa()轻松的就变换过来了,并不是说物理内存映射到内核空间就全部被内核占了对于内核中非动态数据使用的物理内存是不可以变了,但是动态的部分,是可以释放掉的,而释放掉后这一部分对应的物理内存又可以影射到用户空间。

至于为什么不完全映射1g的空间,我想是因为还要留一片内核的虚拟地址给ioram用,比如说pci的ioram,通过ioremap映射总得留下点虚拟地址把,而ioram的虚拟地址又必需在内核空间中,也就是3-4g。 

不完全映射1G,是因为要保留出一段空间来供动态映射所使用,比如当内存大于1G是,除了前面的890M可以直接映射,后面的空间都需要临时映射一下,用完解除映射(某些平台下实际解除是个空操作)。

对于刚好1G内存的时候,动态映射其实是没有必要的。www.kerneltrap.org上曾经有文章讨论过一个patch,可以去掉动态映射,但只能用于少于1G的情况,好像现在kernel的配置已经有这个选项了。

内核的地址是从物理内存的0地址开始的,而0xc0000000就是这个偏移量

"linux这样做,只是为了简化内核中虚拟地址和物理地址之间相互转化的工作,__va(), __pa()轻松的就变换过来了。 "


物理地址 <--> 虚拟地址
#define __pa(x) ((unsigned long)(x) & 0x3fffffff)
#define __va(x) ((void *)((unsigned long)(x) | 0xc0000000))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值