Chinaunix

标题: 物理内存为什么在使用时要映射到内核空间? [打印本页]

作者: mushroom2008    时间: 2014-02-10 13:46
标题: 物理内存为什么在使用时要映射到内核空间?
请教一上问题:linux中有mem_map数组管理物理页面,内核为什么还要将每个物理页面映射到内核线性空间?如果用户程序发生了缺页中断,只要查找mem_map中有没有空闲页面,比如:有就映射到用户空间,为什么还要通过高端内存的复杂映射方法,将一个页面映射到内核空间,进行分配后再用呢?我不明白用户空间用的每个物理页面要先映射到内核空间,再映射到用户空间?


作者: mushroom2008    时间: 2014-02-10 13:52
但为什么要将访问高端内存(如物理内存的1G-4G部分)也搞的那么复杂,直接用mem_map数组中管理不就行了吗?有必要先映射到内核空间再映射到用空间吗?
作者: arm-linux-gcc    时间: 2014-02-10 15:33
不映射是没法访问的,这个你得去看懂CPU MMU的原理才能理解


分配给app的内存是优先从高端内存中拿,如果是高端内存中拿到的,直接就映射给用户空间了,并没有映射到内核空间;
如果分配给app的内存是低端内存中取得的,这个页早在内核启动的时候就已经先映射到低端内存了,并不是你分配的时候才去映射的



作者: humjb_1983    时间: 2014-02-10 16:34
mushroom2008 发表于 2014-02-10 13:46
请教一上问题:linux中有mem_map数组管理物理页面,内核为什么还要将每个物理页面映射到内核线性空间?如果 ...

在保护模式下,CPU使用的虚拟地址,也就是说必须映射后才能访问。
另外,不会将所有的物理内存都映射到内核地址空间的,这种说法肯定是有问题的。
作者: mushroom2008    时间: 2014-02-11 09:43
谢谢楼上二位大侠,但我发现当linux用户程序要使用内存时,他都是由内核分配的,内核无论是分配高端还是内存,都首先要将其映射到内核空间,再进行分配,我知道1G以内的内存是一一映射,但1G以上的高端内存分配为什么也要映射到内核空间,直接用mem_map数组管理不就行了吗?
作者: humjb_1983    时间: 2014-02-11 10:18
你把概念弄混了,用户态程序分配内存时(比如malloc、mmap),实际是分配的虚拟地址空间,“分配”操作的具体执行者肯定是内核,但此时并没有分配物理内存,也并不是你说的将内存映射到内核空间。
用户态真正的物理内存分配,发生在“写”相应内存时,会触发缺页异常,在缺页异常中进行物理内存的分配,并创建相应的页表,将其映射到进程的虚拟地址空间中。
作者: hulidong971    时间: 2014-02-11 12:48
理解Linux的内存管理,首先理解的几个概念:用户虚拟地址空间、内核虚拟地址空间、物理内存页。
用户程序通过malloc等分配虚拟地址空间不会立即分配为物理内存页,是在访问该空间时通过缺页异常进行物理页的分配,如楼上所述。
内核程序既可以分配(通过kmalloc或vmalloc)内核虚拟地址空间,也可以直接分配物理页
作者: mushroom2008    时间: 2014-02-12 14:32
谢谢二位,我理解用户程序在使用内存时是通过在发生”缺页中断“时才内核闭为其分配物理内存,但我不理解的是,内核为什么分配(物理地址1G以上的)物理内存时要将一物理页面映射到内核空间才能分配,内核可不可以通过mem_map数组查找1G以上的空闲物理页面直接分配呢?
作者: mushroom2008    时间: 2014-02-12 14:41
问题的简化就是:无论是内核还是用户使用物理内存,是不是都要将其映射到内核线性地址空间?我看到一些书上讲的,物理内存都由内核分配,内核分配时无论是用kmalloc 还是vmalloc函数都要将此块物理内存映射到内核线性空间?谢谢
作者: humjb_1983    时间: 2014-02-12 15:02
本帖最后由 humjb_1983 于 2014-02-12 15:04 编辑
mushroom2008 发表于 2014-02-12 14:41
问题的简化就是:无论是内核还是用户使用物理内存,是不是都要将其映射到内核线性地址空间?我看到一些书上 ...

这个理解肯定是不对的,不是要“映射到内核线性地址空间”,分配物理内存由伙伴系统负责,会用到mem_map,但分配物理内存后,需要将其映射到“进程地址空间”中,也就是为该段内存映射虚拟地址后,进程才能使用和访问,所以这里应该是映射到“进程的线性地址空间”,不是“内核线性地址空间”。
作者: mushroom2008    时间: 2014-02-13 11:47
谢谢楼上,现在明白了一点,是不是可以这么理解:在linuxt系统中,内核必须能够管理所有物理内存,比如通过kmalloc动态映射,这是因为内核有可能使用到任何一块物理内存页面,但当一个物理内存页面映射到用户空间不一定要先映射到内核空间?再次谢谢!
作者: humjb_1983    时间: 2014-02-13 12:39
关键是理解:物理内存分配和进程虚拟机地址空间分配是分开的,用户态分配内存的整体思路是:先分配地址空间,在真正使用时,再实际分配物理内存,并将相应的物理内存映射到相应的地址空间中(修改页表)
作者: tc1989tc    时间: 2014-02-13 12:58
因为内核在它自己的1g以下的线性地址是和实际的物理地址存在一个固定偏移的,这是所谓的低端地址,,也就是重内核线性地址可以直接推断出物理地址,,,但是内核为了能访问大于1g的高端地址就在1g下面留出来个空洞,,供内核在使用高端物理地址的时候,将其映射到1g的空洞地址内
作者: mushroom2008    时间: 2014-02-13 13:26
因为,很多书让讲,内核必须能够管理到所有的物理内存,无论是低端的还是高端的,所以为了使有限的内核线性空间能够管理所有的物理内存,采用了动态分配VMALLOC,这也是为什么内核有固定映射、永久映射、临时映射等多种映射方式,我就是不明白,内核真的必须管理到所有物理内存吗?
作者: humjb_1983    时间: 2014-02-13 13:53
mushroom2008 发表于 2014-02-13 13:26
因为,很多书让讲,内核必须能够管理到所有的物理内存,无论是低端的还是高端的,所以为了使有限的内核线性 ...

是的,32位系统中,低端内存(<896M)内核直接映射(偏移),高端内存通过896-1014M之间的128M空间进行映射,其中包括了vmalloc
作者: mushroom2008    时间: 2014-02-14 14:32
谢谢啦!!:wink:




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2