当内核模块号或过程访问内存时,号中的内存地址都是思维逻辑地址,但地址是和真实的物理内存地址匹配的,所以地址必须一一映射。比如思维逻辑地址0xc0000003的物理地址是0×3,0xc0000004的物理地址是0×4,……,思维逻辑地址。
物理地址=思维逻辑地址–0xc000000:是内核地址之间的地址转换关系空。注意,内核的虚拟地址在“高端”,但ta映射的物理内存地址在中低端。
假设按照上面简单的地址映射关系,内核思维的逻辑地址空之间的访问是0xc000000~0xffff,那么对应的物理内存范围是0×0~0×4000000,也就是只能访问2GB的物理内存。如果机器安装了8G物理内存,那么内核只能访问前2GB的物理内存,后面的7G物理内存可能打不开,因为内核的所有地址空都已经映射到0×0~0×4000000的物理内存地址范围。即使安装了8G物理内存,内核如何访问物理地址为0×4000001的内存?尝试在数字中有一个逻辑内存地址。0xC0000000到0xffffffff之间的地址空早就用光了,物理地址0×4000000之后的内存就打不开了。
显然,内核地址空之间的所有0xc0000000~0xfffffff都不能用于简单的地址映射。所以在x86架构中,内核地址空分为三个部分:ZONE_DMA、ZONE_NORMAL和ZONE_HIGHMEM。ZONE_HIGHMEM是高端内存,这是高端内存定义的由来。
在x86架构中,三种类型的区域(从3G开始计算)如下:
ZONE_DMA内存开头16MB
ZONE_NORMAL16MB~896MB
zone_highmeme896MB~end(2GB)
2.掌握前面大家都描述了高端内存的起源。Linux内核地址空分为三个部分:ZONE_DMA、ZONE_NORMAL和ZONE_HIGHMEM,高端内存地址空范围从0xf800000到0xffffffff(896MB到1024MB)。那么如果内核是,那么128MB的高端内存地址空,如何访问所有的物理内存?
当内核要访问物理地址高于896MB的内存时,从0xF8000000~0xFFFFFFFF地址范围内,找一段相对规范空的空闲心智逻辑地址空,应用一段时间。用这段思维逻辑地址空构建一个物理内存映射到你要访问的那段(即填充内核PTE网页的页表),暂时使用,用完后再偿还。那样的话,别人也可以使用这个地址空访问其他物理内存,完成使用一个相对有限的地址空访问所有物理内存。如下图。
举个例子,如果内核要在2G开头访问一个1MB的物理内存,物理地址范围是0×80000000~0x800FFFFF。访问前先找一个1MB的备用地址空空,假设要找的备用地址空是0xF8700000~0xF87FFFFF,把1MB的逻辑地址空映射到物理上。映射关系如下:
当内核访问0×80000000~0x800FFFFF物理内存时,释放内核线型空0xf8700000~0xf87fffff。其他全进程或数也可以使用0xF8700000~0xF87FFFFF访问其他物理内存。
从上面的描述中,我们可以抓住高端内存最基本的意识:借用一段地址空,建立一个临时地址映射,用完后释放,这样才能保证这段地址空可以回收,访问所有物理内存。
看到这里,有人不禁要问:如果有一整个内核进程或者一个模块一直占用着一个thinking空的逻辑地址,没有释放出来怎么办?如果出现这种情况,内核的高端内存地址空会越来越不安。如果全部被占用,没有释放,不映射到物理内存就打不开。
3.划分内核高端内存分为三部分:VMALLOC_START~VMALLOC_END、KMAP_BASE~FIXADDR_START和FIXADDR_START~4g。
对于高端内存,可以根据alloc_page()或者其他函数获取页面,但是如果要访问实际的物理内存,就要把页面改成线性地址(为什么?想想MMU是怎么访问物理内存的),也就是说,我们必须给高端内存的page找一个线性空的空间。这整个过程被称为高端内存映射。
高端内存的映射方式有三种:
映射到“非连续内存分配”
,这个比较简单,因为根据vmalloc(),在“内核动态映射空”竞价内存的情况下,很有可能从高端内存(查询vmalloc)获取网页,所以高端内存可能映射到“内核动态映射空”。
永久内核映射
如果根据alloc_page()获取高端内存的页面,如何为其找一个linetype空?
所以内核技术专业空创建了一条从PKMAP_BASE到FIXADDR_START的线空,用来映射高端内存。在2.6内核上,这个地址范围是4g-8M到4g-4M的中间。这个空叫做“内核永久映射空或者“永久内核映射空”。这个空房间使用与其他空房间相同的页面目录表。对于内核,它是swapper_pg_dir。对于一般全流程来说,按照CR3存储是有偏的。一般这个空房间是4M,所以只需要一个页表,内核会根据pkmap_page_table寻找这个页表。根据kmap(),你可以映射一个页面到这个空房间。由于这个空空间为4M,最多可以映射1024页。所以对于没有使用的页面,要从这个空空间释放(也就是清除映射关系),根据kunmap(),可以从这个空空间释放一个页面的线性地址。
临时内核映射
内核为了不同的规定,在FIXADDR_START到FIXADDR_TOP中间存储了一些线型空。这个空房间叫做“固定映射空房间”。这个空房间的一部分是用来临时映射高端内存的。
这些空房间具有以下特征:
(1)每个CPU占用一个空房间
(2)每个CPU占用的这个空房间被分成许多小的空房间,并且
如果要进行临时映射,必须有特殊的映射目的。根据映射目的,可以找到匹配的小空房间,然后将这个空房间的地址作为映射地址。这意味着临时映射将导致之前的映射变得模糊。可以根据kmap_atomic()进行临时映射。
三.其他1。客户空房间(全程)是否有高端内存的定义?
客户全流程没有高端内存的定义。只有内核空有高端内存。最好的客户可以全程访问3G物理内存,而内核可以全程访问所有物理内存。
2、64位内核有高端内存吗?
目前64位Linux内核不容易有高端内存,因为64位内核可以使用512GB以上的内存。如果机器安装的物理内存超过内核地址空的范围,就会出现高端内存。
3。客户在整个过程中可以访问多少物理内存?内核号可以访问多少物理内存?
32位系统客户可以全程访问3GB,内核号可以访问所有物理内存。
64位系统客户全程可访问512GB以上,内核号可访问所有物理内存。
4。高端内存与物理地址、思维逻辑地址、线性地址的关系?
高端内存只和思维的逻辑地址有关,和思维的逻辑地址和物理地址没有直接关系。
以上是Linux的客户空和内核空之间细节的详细描述。请关注龙族互联网科技的相关文章!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)