免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: augustusqing
打印 上一主题 下一主题

linux虚拟地址空间疑惑 [复制链接]

论坛徽章:
0
41 [报告]
发表于 2007-09-17 22:16 |只看该作者
原帖由 augustusqing 于 2007-9-17 21:57 发表
我曾经阅读过中关于页缓存的章节,了解过相关的,这里主要是疑惑这块buffer和进程的关系,是否要修改进程的页表表项,来指向这块buffer了?这块buffer的首地址,是处于进程虚拟地址空间中吧
曾经实现过设备驱动 ...


在物理上来说,CPU 就有这个 page cache,叫做 TLBS,存放各级页表结构。任何物理页面结构的改变操作都会更新T LBS 的内容

论坛徽章:
0
42 [报告]
发表于 2007-09-17 22:36 |只看该作者
原帖由 augustusqing 于 2007-9-17 21:57 发表
我曾经阅读过中关于页缓存的章节,了解过相关的,这里主要是疑惑这块buffer和进程的关系,是否要修改进程的页表表项,来指向这块buffer了?这块buffer的首地址,是处于进程虚拟地址空间中吧
曾经实现过设备驱动 ...

呵呵,lz已经彻底混淆了mmap用于地址映射、mmap用于文件映射之间的关系了。文件映射前面已经说过了,建议lz阅读过相关章节。
mmap用于地址映射嘛就比较简单,就是修改页表。
例如在驱动中,该设备的某个寄存器组映射到物理地址空间中的3.8G这个地址(这是物理地址)。通过mmap(ioremap)修改页表,使某个虚拟地址映射它,那么通过这个虚拟地址就可以访问设备对应的寄存器了。

论坛徽章:
0
43 [报告]
发表于 2007-09-17 22:42 |只看该作者
原帖由 augustusqing 于 2007-9-17 22:03 发表

我感觉加载器加载程序的方式应该跟驱动实现mmap映射的过程是同本质的,就是疑惑的,进程怎么跟这个磁盘文件联系起来的,怎么指向这个磁盘文件内容的,指向的是这个文件的page cache吗?

page cache是属于文件节点的,和进程地址空间中的数据段是两回事。
vm_area是用于描述程序地址空间的,例如数据段、代码段有对应的vm_area结构。但在mmap的时候,也有vm_area结构也和被map的文件对应 ………… 噢噢噢,越说概念越多,lz会越来越混淆。
还是看书吧,先把相关内容读一次,不明白再说。《Understanding linux kernel》的8、9、15、16章回答了你所有的问题。《linux kernel development》虽然经典,但写的比较简单,只适合入门。

论坛徽章:
0
44 [报告]
发表于 2007-09-17 22:48 |只看该作者
原帖由 mik 于 2007-9-17 21:52 发表


zx_wing 说得很不错。

但:
>> page fault是转换是地址转换的一个中间过程
不认同这一点, 偶认为 page fault 不能算是地址转换的一个中间过程,虚拟地址会按照既有的规则进行转换得出物理页面。在实际 ...

嗯,这样理解也不错。在一次正常的地址转换中,不会发生page fault,这样看page fault只能算地址转换中的一个异常。呵呵,反正这些东西没有个明确的定义,我们了解它的实质就可以了

呵呵,这个帖子太长了,引出的概念太多,越说越觉得不是一两句话说的清楚的。

论坛徽章:
0
45 [报告]
发表于 2007-09-18 11:44 |只看该作者
原帖由 mik 于 2007-9-17 22:16 发表


在物理上来说,CPU 就有这个 page cache,叫做 TLBS,存放各级页表结构。任何物理页面结构的改变操作都会更新T LBS 的内容

我所说的page cache是指一个inode的address_space对象,页缓存,把相应inode对应的文件的内容按page为单位缓存起来,是内核维护的,而您说的TLB,确实是在CPU内部把虚拟地址直接转换成某个物理页帧号的一块高速缓存,跟我所没搞清楚的不在同样位置,不过也是容易搞混的,我也不知道自己有没有搞混,多谢提醒。

论坛徽章:
0
46 [报告]
发表于 2007-09-18 12:23 |只看该作者
原帖由 zx_wing 于 2007-9-17 22:42 发表

page cache是属于文件节点的,和进程地址空间中的数据段是两回事。
vm_area是用于描述程序地址空间的,例如数据段、代码段有对应的vm_area结构。但在mmap的时候,也有vm_area结构也和被map的文件对应 ……… ...


page cache确实是属于文件节点的,和进程地址空间中的数据段是两回事,我疑惑的是它们之间的联系

呵呵,lz已经彻底混淆了mmap用于地址映射、mmap用于文件映射之间的关系了。文件映射前面已经说过了,建议lz阅读过相关章节。
mmap用于地址映射嘛就比较简单,就是修改页表。


总结一下我现在的理解:

我觉得mmap用于地址映射和mmap用于文件映射本质上是一样的,地址映射是修改页表项指向物理内存页,文件映射是修改页表指向这个文件的page cache中的某个内存页,加载器加载程序就是修改进程空间的代码段、数据段所在虚拟地址对应的页表项,指向进程对应的可执行文件中代码节、数据节的偏移地址处在这个可执行文件的page cache中的内存页,这些过程本质上是一样的,由文件的页缓存机制(以前主要是块缓冲),把不同层次的对象,不同子系统协同起来了,交换机制也是利用一样的机制,只是交换文件存储的就是某个进程的物理内存页面的内容,并且很快会把物理内存页面写进磁盘,不占用物理内存页,但本质上仍然是一样的,而缺页故障处理程序做的就是把磁盘文件中的内容或着交换文件的内容从磁盘上读入到这个文件的页缓存中。


嗯,这样理解也不错。在一次正常的地址转换中,不会发生page fault,这样看page fault只能算地址转换中的一个异常。呵呵,反正这些东西没有个明确的定义,我们了解它的实质就可以了

呵呵,这个帖子太长了,引出的概念太多,越说越觉得不是一两句话说的清楚的。

我认为对一种机制的学习,完全的理解它固然很重要,但我认为更重要的是把自己理解的能准确清晰的表述出来,象理解了TCP/IP的人很多,但象Richard Steven,Comer Douglas这样能准确清晰的表述出来的,就不多了,大家认为了?^_^

还是看书吧,先把相关内容读一次,不明白再说。《Understanding linux kernel》的8、9、15、16章回答了你所有的问题。《linux kernel development》虽然经典,但写的比较简单,只适合入门。

好的,一直落下ULK没买,一直心存侥幸这本应该可以不用买,我错了,受教了!(抱拳)

论坛徽章:
0
47 [报告]
发表于 2007-09-18 12:49 |只看该作者
原帖由 augustusqing 于 2007-9-18 12:23 发表


page cache确实是属于文件节点的,和进程地址空间中的数据段是两回事,我疑惑的是它们之间的联系



总结一下我现在的理解:

我觉得mmap用于地址映射和mmap用于文件映射本质上是一样的,地址映射是修 ...

lz总结的不错。但我不认为加载程序的时候,代码位于文件的的page cache中。这是不合常理的。操作系统应该专门为程序分配内存,再把二进制代码拷贝过去。否则,当程序运行时,它本身的目标文件被读写修改了,会反应到page cache中去,这样会影响当前正在运行的程序。

论坛徽章:
4
戌狗
日期:2013-08-15 18:22:43技术图书徽章
日期:2013-08-21 13:48:45巨蟹座
日期:2013-09-26 17:06:39处女座
日期:2013-12-25 11:26:10
48 [报告]
发表于 2007-09-18 13:28 |只看该作者
其他不清楚,至少load_elf_binary/interpreter/libiary时,

1) 只是为mm 建立了vma_area的链,而没有填写pte项的内容 (最高的vma_area除外,表示最初的栈,这段区间写了pte项)。进程前3G的pte项内到底是什么东西,完全由以后的page_fault根据vma_area来填写。这样,加载完程序,未page_fault前,进程访问不到pagecache。

2)所有vma_area,全部都是deny_write_access,并且map_private,即使发生page_fault,进程也只能读pagecache,而不能写pagecache。

论坛徽章:
0
49 [报告]
发表于 2007-09-18 13:37 |只看该作者
原帖由 zx_wing 于 2007-9-18 12:49 发表

lz总结的不错。但我不认为加载程序的时候,代码位于文件的的page cache中。这是不合常理的。操作系统应该专门为程序分配内存,再把二进制代码拷贝过去。否则,当程序运行时,它本身的目标文件被读写修改了,会反应到page cache中去,这样会影响当前正在运行的程序。


^_^,终于看到你说"不错"了,多谢多谢,^_^

加载程序的时候,文件的代码节、数据节在文件中都有偏移offset,加载程序只是修改页表中固定虚拟地址对应的页表项,指向这个文件的页缓存的相应的偏移offset,此时代码还没有拷贝进来,当要执行这段代码时,虚拟地址的引用,引起缺页异常时,才由缺页异常处理程序,"专门为程序分配内存,再把二进制代码拷贝进来“,这里分配的内存就会添加到这个文件的页缓存中,而这个进程对这个文件的页缓存中代码段所在的物理页面的映射,是只读的,其它进程,如果也要映射这个文件的这个页,也有映射成只读的,要写的话,就映射成私有的写时拷贝,真正写这个页面时,再另外分配一个物理页,这样也不会影响当前正在运行的程序,这就是mmap中,prot、flags参数的解释

我上面说的本质,就是指修改进程页表,因为页表表项不是只有两种可能吗?指向某个物理页帧,或者磁盘上某个文件,加载器,mmap函数,交换,都是指向某个文件,但无论哪种情况,页表项的终极目标是指向某个物理内存页,这就是页缓存了,页缓存万岁!

我后来迷惑的就是这些机制是如何协同起来的,现在觉得页缓存应该记头功,好像内核中就页缓存用了radix tree,确实,页缓存的检索效率太重要了。

看我现在的理解,对吗?^_^

论坛徽章:
0
50 [报告]
发表于 2007-09-18 14:03 |只看该作者
原帖由 塑料袋 于 2007-9-18 13:28 发表
其他不清楚,至少load_elf_binary/interpreter/libiary时,

1) 只是为mm 建立了vma_area的链,而没有填写pte项的内容(最高的vma_area除外,表示最初的栈,这段区间写了pte项)。进程前3G的pte项内到底是什么东西,完全由以后的page_fault根据 vma_area来填写。这样,加载完程序,未page_fault前,进程访问不到pagecache。

2)所有vma_area,全部都是deny_write_access,并且map_private,即使发生page_fault,进程也只能读pagecache,而不能写pagecache。


说一些用户空间的机制时塑料袋兄好像有时保持沉默,说到内核里面的机制时就"舍我其谁"了,^_^,上回我说你对/proc/xxx/maps中vm_area_struct结构参数你最清楚就是这个意思啊,^_^

我最迷惑的就是load_elf_binary/interpreter/libiary这段源码了

1,load_elf_binary时,确实为进程建立起区域链表,代码区,数据区,bss区,堆区,栈区各自有自己的vm_area_struct,这些区域链表就代表了这个进程的虚拟地址空间了,代码区的vm_area_struct中vm_start的值是固定的0x8048000了,这个区域对应着二进制文件的代码节,那关键是在这里了,这个对应关系是在哪里记录的?vm_area中还是pte中
按照塑料袋兄的说法,这个对应关系是记录在vm_area_struct中,pte中0x8048000处仍然为空,直到访问时缺页了,才分配物理页面,根据vm_area_struct中记录的对应关系从磁盘读入,存入物理页面,这个物理页面属于二进制文件的页缓存吧

2,你的意思是所有vm_area对应的空间都不能写?只能读?
写驱动时,比如LCD,frame buffer结构,为显存分配一个vm_area,再mmap到用户空间,用户当然有写权限啊
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP