运行一个可执行文件的过程

807 阅读2分钟

可执行文件在执行的过程中在操作系统看来就是一个进程。那么问题就可以看成怎么创建一个一个和这个可执行文件相关的进程。

在操作系统层面来看进程和线程最大的区别就是进程有着独立的地址空间。所以在加载一个可执行文件的过程中要为这个文件创建独立的地址空间。说到独立的地址空间那么就要说到大名鼎鼎的虚拟内存了。虚拟内存是为进程提供了假象的独立空间,这个虚拟空间需要用段页式内存管理机制映射到物理内存。然后使用虚拟内存做程序想做的事情。因此从这个分析过程中我们知道我们要做的事:创建虚拟内存空间,然后把建立文件中数据和虚拟内存的对应关系。最后改变PC指针指向文件入口就完事了。

创建一个进程

在运行前会调用fork函数创建一个进程。最终调用execve()这个系统调用创建进程。

创建虚拟内存空间,产生虚拟地址与物理地址的映射关系

这一步在Linux中十分简单,Linux仅仅会分配一个空的页目录,并没有设置映射关系。等出现缺页错误的时候再做缺页处理建立真正的映射关系。

建立可执行文件数据与虚拟内存的关系

这一步主要靠读文件的各种header确定各种数据在虚拟地址空间的地址。

更改PC指针指向起始地址

这一步也是在读各种header里的信息将系统调用的返回地址更改为入口地址。

参考资料:

markrepo.github.io/kernel/2018…