刚开始一直不明白一个源程序经过编译链接以后形成的可执行文件是怎么映射到系统为该进程分配的4GB虚拟地址空间中的。通过翻阅相关资料,仔细斟酌才恍然大悟。
一个源程序经过编译链接以后形成的是可执行文件,但是这个时候只是形成了可执行文件,并没有分配虚拟内存空间了。我们知道链接程序的方式有两种:
1、静态链接:就是在经过编译以后,由链接程序把所有该源程序用到的静态库函数,或者是原文件链接到一块,链接成一个整体的可执行文件。当该可执行文件被执行的时候,此时系统才为该进程分配了4GB的虚拟内存空间,这个时候就把可执行文件装入到虚拟内存空间了,所以接下来真正运行的时候再由虚拟内存地址到物理内存地址的转换进行。
2、动态链接在此种方式下,函数的代码被放到称作是动态链接库或共享对象的某个目标文件中。链接程序此时所作的只是在最终的可执行程序中记录下共享对象的名字以及其它少量的登记信息,也就是说此时并不把所有目标文件链接到一块。在此可执行文件被执行时,动态链接库的全部内容将被映射到运行时相应进程的虚地址空间。动态链接程序将根据可执行程序中记录的信息找到相应的函数代码。
虚拟地址空间是一个4GB大小的硬盘空间,其中0~3GB是进程的用户空间,3~4GB是内核空间,因为每个进程都可以通过系统调用进入内核,所以Linux内核空间供所有进程共享,但是用户空间不是共享的,它是隔离的,举个具体的例子,就好比我们这个长安区(硬盘空间),有两个大学,西安邮电大学(进程空间1),陕西师范大学(进程空间2),西安邮电大学有个实验楼A(进程空间中的某个数),陕西师范大学也有个实验楼A(进程空间2中的某个数),当我们分别访问西安邮电大学的实验楼A和陕西师范大学的实验楼A的时候会混淆吗,一点儿关系都没有对吧!其实内存也一样,所以这种虚拟的地址空间起到了很好的隔离机制,它很好的避免了一个恶意进程试图访问其他进程中的数据。
接下来就是映射的关系了。
内核的虚拟地址空间到物理地址空间是线性的映射关系,
而用户的虚拟地址空间到物理空间是利用分页机制来实现的,实现的过程很复杂,这里不再赘述。
阅读(1308) | 评论(0) | 转发(2) |