可执行文件格式对应的load_binary 方法执行下列操作(我们假定这个可执行文件所在的文件系统允许文件进行内存映射并并需要一个或多个共享库):
![aa5a90bbf00b4b118293e56f55d2b028.png](https://i-blog.csdnimg.cn/blog_migrate/a5792c99d7e824497b3c59e19c32893b.jpeg)
1。 检查存放在文件前128字节中的一些魔数以确认可执行格式。如果魔数不匹配,则返回错误码-ENOEXEC。
2。读可执行文件的首部。这个首部描述程序的段和所需的共享库。
3。从可执行文一件获得动态链接程序的路径名,并用它来确定共享库的位置并把它们映射到内存。
4。获得动态链接程序的目录项对象(也就获得了索引节点对象和文件对象)。
5。检查动态链接程序的执行许可权。
6。把动态链接程序的前128字节拷贝到缓冲区。
7。对动态链接程序类执行一些一致性检查。
![ba104185e0cb3a5490cc1c5aa02be2d1.png](https://i-blog.csdnimg.cn/blog_migrate/cdf110933b9c05482017f8f6fb29f477.jpeg)
8。调用flush_old_exec()函数释放一个计算所占用的几乎所有资源。这个函数又依次执行下列操作:
- 如果信号处理程序的表为其他进程所共享,那就分配一个新表并把旧表引用计数器减1,而且它将进程从旧的线程组脱离。这是通过调用de_thread()函数完成的。
- 如果与其他进程共享,就调用unshare_files() 函数拷贝一份包含进程已打开文件的files_struct结构。
- 调用exec_mmap() 函数释放分配给进程的内存描述符、所有线性区及所有页表。
- 将可执行文件路径名赋给进程描述符的comm字段。
- 调用flush_thread()函数清除浮点寄存器的值和在TSS段保存的调试寄存器的值。
- 调用flush_signal_handlers()函数,用于将每个信息恢复为默认操作,从而更新信号处理程序的表。
- 调用flush_old_files()函数关闭所有打开的文件,这些打开的文件在进程描述符的files->close_on_exec字段设置了相应的标志。
现在,我们已经不能返回了:如果真出了差错,这个函数再不能恢复前一个计算。
![c66d5dcaebfe6ac7c603d51c05400d17.png](https://i-blog.csdnimg.cn/blog_migrate/ef1b256e4b0dbf8a42a94dbaae1a4172.jpeg)
9。清除进程描述符的PF_FORKNOEXEC标志。这个标志用于在进程创建时设置进程记账,在执行一个新程序时清除进程记账。
10。设立进程新的个性,即设置进程描述符的personality字段。
11。调用arch_pick_mmap_layout()。以选择进程线性区的布局。
12。调用setup_arg_pages() 函数为进程的用户态堆栈分配一个新的线性区描述符,并把那个线性区插入到进程的地址空间。setup_arg_pages()还把命令行参数和环境变量串所在的页框分配给新的线性区。
待续。。。。。。