免费注册 查看新帖 |

Chinaunix

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

linux内核问题(存储管理/进程切换),求赐教 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2010-07-26 10:09 |只看该作者
本帖最后由 gqbfree 于 2010-07-26 10:23 编辑

回复 10# folklore

感谢楼上兄弟的耐心解答!!!


1)内核线性映射是896M,而且对应的物理地址已经确定,是0-896M。 那么用户进程空间分配地址的时候是不是优先考虑大于896M的物理地址页面?
     >>Windows 98将内核Map到所有进程中,但这不表示所有的OS都会这样做,内核并不从用户程序更加特别(从CPU的角度看),CPU甚至不会知道当前运行的是用户代码或是内核代码(当然,一般来说,内核可以执行特权指令,而用户代码不可以,不过,如果OS的设计者喜欢的话...)。
这个问题大家可以不用想的很深,我就是想知道Linux在用户空间使用内存时先用哪部分?(其实哪部分都可以,但想知道有没有啥思想在里面)


(2)有没有大侠帮忙把一个进程可能有的vm_area_struct结构对应的段列举一下,比如堆栈对应一个vm_area_struct(是不是只对应一个?)堆对应一个,代码段对应一个,还有mmap啥的 等等。还有malloc时,是否有新的vm_area_struct生成呢?还是扩展堆对应的vm结构?
     >>没看过内核,无法回答,从系统设计的角度看,这种结构应当只有一个。
     这个我又看了一遍情景分析,应该是堆,堆栈,代码段,数据段各有一个,如果堆有分配,且分配是在原来基础上连续,那么也归入原来区间;但如果不连续,则重新开启一个区间;文件映射mmap是需要重新开启一个虚拟区间的。不知道还有没有其它的遗漏?(比如说数据段分为几个区间?还是一个?)
(3)发生缺页异常时,如果需要从磁盘上把相应的内容读进内存,那么如何定位需要读入哪些内容?我知道 vm_area_struct结构里有对应文件的句柄和offsize,需要把整个都读进来吗?还是只读一个页面?如何确定读多少?
     >>一般的OS都会有预读功能,所以会一般也会读入相邻的页面,读交换页是通过文件系统进行的,如果把整个分页文件都读进入,内存足不足够不用说,分页的意义也没有了。
     这个好像是分一页出来,我还不太确认,再研究。
(4)能不能提供以下情形: 只有preem_disable能实现,而信号量无法实现的情形。(premm_disable主要用在哪里)
    >>PV信号量、Spin_lock、或是Preem_disable的任何一种互斥方式,都可单独实现所有功能(区别仅是代价和实现难度)。
(5)帮忙确认一下我自己理解的观点是否正确:

     1. 用户空间 切 内核空间,压当前的用户空间的ss,sp入内核栈,然后取值TSS中的ss0/sp0赋给SS,ESP,完成切换; 然后把返回值cs/eip和其它一些现场寄存器压入内核栈(即pt_regs)。(很多资料都写先赋值SS,SP,然后压用户空间的ss,sp入内核栈, 我疑问此时的ss/sp从哪里来啊,还有pt_regs是不是只是用来存储用户空间时寄存器内容的?有没有情况是对内核现场存储?)
     >>当前的SS,SP没有入内核栈的必要的,不过,非要这样做也可以
        应该需要吧,不然如何从内核返回到用户态?
     >>用户态的ss/sp本来就有的...据说Linux不使用X86CPU的TSS,如何还有TSS,不懂中,什么时候看代码去吧
        不是不用,X86设计是一个进程用一个TSS,但linux实现一个CPU使用一个TSS;进程切换时把TSS中的sp0,还有啥io bitmap切换即可。其实所有信息都包含在thread_info结构里,我也不清楚为什么需要TSS在中间插一脚。直接从thread_info里的信息放入寄存器不行吗?
     >>内核现场没有存储的价值,因为内核不会从“上次的执行点”开始执行,如果非要说有(可能被其它内核部件中断),那么无论被中断多少次,现场保存在当前的用户进程的内核线程中...(就像是80x86是单程序环境中一样),当然,前提是内核态代码不应当被Swtch中断(这样也未必不可,只是系统变得更复杂了)。
        
       请各位补充!

论坛徽章:
0
12 [报告]
发表于 2010-07-26 13:54 |只看该作者
本帖最后由 snail_314 于 2010-07-26 13:56 编辑

回复 11# gqbfree


    1. 这个思想就是buddy system。和map没一点儿关系。线性映射和page management没一点儿关系。
    2. 一个进程的/proc/xxx/maps文件就是vm_area的体现。
    3. 读交换文件和读“其他文件”为什么有区别?‘页缓冲’机制应该都是适用的

论坛徽章:
59
2015年亚洲杯之约旦
日期:2015-01-27 21:27:392015年亚洲杯之日本
日期:2015-02-06 22:09:41拜羊年徽章
日期:2015-03-03 16:15:432015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015元宵节徽章
日期:2015-03-06 15:50:392015年亚洲杯之阿联酋
日期:2015-03-19 17:39:302015年亚洲杯之中国
日期:2015-03-23 18:52:23巳蛇
日期:2014-12-14 22:44:03双子座
日期:2014-12-10 21:39:16处女座
日期:2014-12-02 08:03:17天蝎座
日期:2014-07-21 19:08:47
13 [报告]
发表于 2010-07-27 18:03 |只看该作者
回复  folklore

感谢楼上兄弟的耐心解答!!!


1)内核线性映射是896M,而且对应的物理地址已经确 ...
gqbfree 发表于 2010-07-26 10:09



    回答如下:

1)内核线性映射是896M,而且对应的物理地址已经确定,是0-896M。 那么用户进程空间分配地址的时候是不是优先考虑大于896M的物理地址页面?
     >>Windows 98将内核Map到所有进程中,但这不表示所有的OS都会这样做,内核并不从用户程序更加特别(从CPU的角度看),CPU甚至不会知道当前运行的是用户代码或是内核代码(当然,一般来说,内核可以执行特权指令,而用户代码不可以,不过,如果OS的设计者喜欢的话...)。
这个问题大家可以不用想的很深,我就是想知道Linux在用户空间使用内存时先用哪部分?(其实哪部分都可以,但想知道有没有啥思想在里面)
    >>没有什么思想,除了一般将0页该为不可访问外(地址0其实是可写可读的)

(2)有没有大侠帮忙把一个进程可能有的vm_area_struct结构对应的段列举一下,比如堆栈对应一个vm_area_struct(是不是只对应一个?)堆对应一个,代码段对应一个,还有mmap啥的 等等。还有malloc时,是否有新的vm_area_struct生成呢?还是扩展堆对应的vm结构?
     >>没看过内核,无法回答,从系统设计的角度看,这种结构应当只有一个。
     这个我又看了一遍情景分析,应该是堆,堆栈,代码段,数据段各有一个,如果堆有分配,且分配是在原来基础上连续,那么也归入原来区间;但如果不连续,则重新开启一个区间;文件映射mmap是需要重新开启一个虚拟区间的。不知道还有没有其它的遗漏?(比如说数据段分为几个区间?还是一个?)
   >>你说的是分页机器的地址Virtual空间的分配,所谓的“区间”实际上是指一个LDT
(3)发生缺页异常时,如果需要从磁盘上把相应的内容读进内存,那么如何定位需要读入哪些内容?我知道 vm_area_struct结构里有对应文件的句柄和offsize,需要把整个都读进来吗?还是只读一个页面?如何确定读多少?
     >>一般的OS都会有预读功能,所以会一般也会读入相邻的页面,读交换页是通过文件系统进行的,如果把整个分页文件都读进入,内存足不足够不用说,分页的意义也没有了。
     这个好像是分一页出来,我还不太确认,再研究。
(4)能不能提供以下情形: 只有preem_disable能实现,而信号量无法实现的情形。(premm_disable主要用在哪里)
    >>PV信号量、Spin_lock、或是Preem_disable的任何一种互斥方式,都可单独实现所有功能(区别仅是代价和实现难度)。
(5)帮忙确认一下我自己理解的观点是否正确:

     1. 用户空间 切 内核空间,压当前的用户空间的ss,sp入内核栈,然后取值TSS中的ss0/sp0赋给SS,ESP,完成切换; 然后把返回值cs/eip和其它一些现场寄存器压入内核栈(即pt_regs)。(很多资料都写先赋值SS,SP,然后压用户空间的ss,sp入内核栈, 我疑问此时的ss/sp从哪里来啊,还有pt_regs是不是只是用来存储用户空间时寄存器内容的?有没有情况是对内核现场存储?)
     >>当前的SS,SP没有入内核栈的必要的,不过,非要这样做也可以
        应该需要吧,不然如何从内核返回到用户态?
   >>CPU会将这些信息保存到当前的TTS中,没有OS的强制介入,CPU不会自动返回用户态,也就是说,CPU不可能从内核程序的Stack中得到信息再恢复执行,而必须Call TTS或Jump TTS(其它CPU也类似)
     >>用户态的ss/sp本来就有的...据说Linux不使用X86CPU的TSS,如何还有TSS,不懂中,什么时候看代码去吧
        不是不用,X86设计是一个进程用一个TSS,但linux实现一个CPU使用一个TSS;进程切换时把TSS中的sp0,还有啥io bitmap切换即可。其实所有信息都包含在thread_info结构里,我也不清楚为什么需要TSS在中间插一脚。直接从thread_info里的信息放入寄存器不行吗?
   >>没有TTS,根本就无法进行任务切换了,这里面有鸡和蛋的问题,因为你无法将自已举起来而离开地球。Linux不使用TTS,并非完全不用,最多它只能做到只用一个TTS,在Switch时从其它地方手工保存或恢复现场,而Intel的TTS的架构是每个任务一个。(在DOS时代,我曾想不使用CPU的任务Switch机制实现任务Switch,当然无论如何都会自相矛盾)
     >>内核现场没有存储的价值,因为内核不会从“上次的执行点”开始执行,如果非要说有(可能被其它内核部件中断),那么无论被中断多少次,现场保存在当前的用户进程的内核线程中...(就像是80x86是单程序环境中一样),当然,前提是内核态代码不应当被Swtch中断(这样也未必不可,只是系统变得更复杂了)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP