虚拟地址的高端内存
1.由来原因
虚拟地址分为用户空间和内核空间,用户空间为3G,高1G为内核空间。
用户空间的虚拟地址到实际物理地址的映射我们之前有谈及此处不赘述。
高1G(3G-4G)为虚拟内核空间这一空间的映射比较暴力,直接在物理内存
的0开始映射,一一对应。那么这样会有一个问题,1G的虚拟内存只能映射
1G的物理内存,对于大于1G的物理内存就无能为力了,我们想用1G的线性
空间访问整个(大于1G)物理内存.可是想想,我们的线性地址空间是有限的
对于内核来说就是1G,那我们访问整个物理空间有什么意义呢?这个问题我
至今没有找到答案,但是我自己想的是,内核申请物理框的时候,或是连续
或是不连续,我们知道伙伴算法保存了很多这种内存块的链表,这种链表不
一定就在0-1G的空间很可能是大于1G的物理地址上,通过高端内存我们就可
以取到这部分物理内存了。
2.内核态用户态申请内的差异
用户态我们采用的是缺页机制,就是不管你这个虚拟内存当时有木有,我
直接先用,然后跑到页表去查一看木有,没事,爷现场给你分一个就行了,
内核可以不是这样,首先内核如果发生了缺页会报一个oops异常,(据说会
导致崩溃,这个有待考证,copy_from_user就是为了防止内存访问用户空间
缺页的),所以内核必须保证这个虚拟地址对应到了物理地址,实际我们可以
这么理解如果给用户用虚拟地址,那么我们应该先拿到物理页框,然后把这
个页框对应到虚拟地址,再给我们用虚拟地址。
用户态现有虚拟地址得到物理地址,内核态现有了物理地址得到一个虚拟地址。
(当然这个理解不是很到位,但大致可以这么认为了)
3.解决方法
内核的虚拟地址和物理地址映射的时候不要把1G全部映射完毕,虚拟内存留
出高128MB,也就是说高端内存实际是针对物理内存而已的。
想想1中提及的,因为内核的线性空间只有1G,所以他能映射的物理空间其实
也只能是1G,内核放弃了自己的这128Mb不用却用七拼八凑的其他空间,这里
的原因是什么。内核使用内存的时候首先使用一些函数申请物理地址,物理
地址或是连续或是不连续申请成功后返回给内核,内核再把这些物理地址映射
给高端地址空间,用完之后释放掉。