0.sys_execve:系统调用,让进程执行某个程序

(1)在系统空间建立一个路径名的副本(见1)

(2)do_execve()(见2)

(3)释放路径名副本(即作为缓冲区的管理页面)


1.getname()

(1)在系统空间定义一个缓冲指针

(2)分配一个物理页面作为缓冲区

(3)将路径名从用户空间复制到缓冲区

(4)缓冲区指针指向这个物理页面


2.do_execve()

(1)打开可执行文件(结合文件系统来阅读)

(2)初始化bprm数据结构(见3)

bprm是用于保存可执行文件上下文的数据结构

(3)用formats队列中相应的“代理人”来可执行文件装入(4)

formats队列中的成员代表着各种可执行文件的代理人,每个成员只认识且处理一种特定格式的可执行文件的运行


3.初始化bprm数据结构(bprm是用于保存可执行文件上下文的数据结构)

(1)初始化各个成员变量

(2)统计参数个数和环境变量个数

(3)从可执行文件中读入开头128个字节到bprm缓冲区

不管是什么格式的可执行文件,开头的128个字节包含了关于可执行文件属性的必要成充分的信息

(4)把filename从系统空间复制到bprm

(5)把参数从用户空间复制到bprm

(6)把环境变量从用户空间复制到bprm


4.search_binary_handler()

(1)依次让formats队列中的每个成员尝试它们的load_binary()函数

load_binary()用于装入可执行程序。假设是a.out格式的可执行文件,以load_aout_binary()为例说明load_binary()的过程(见5)

(2)若尝试成功(那么一定已经装入成功),则让可执行文件投入运行

(3)若全部失败,则装入相应的模块,再从step1开始再尝试一次(一共只尝试两次)


5.load_aout_binary():将a.out格式的可执行文件

(1)各种检查(见6)

(2)与父进程“决裂”(见7)

拥有独立的信号处理表、用户空间、文件打开信息等,不再与父进程共享

(3)当前进程的一些初始化(见10)

(4)根据a.out具体的不同格式,以不同的方式装入代码段和数据段(见11)

(5)将入bss段

调用do_brk()函数,为bss段分配空间,并建立映射

(6)将入堆栈段(见12)

(7)设置regs指针

regs指向保留在当前进程的系统空间堆栈中的各个寄存器副本。当进程从系统调用返回时,这些值就会被“恢复”到CPU的各个寄存器中


6.各种检查

(1)检查目标文件的格式,是不是a.out格式的可执行文件

(2)data段和bss段总和不能超过某个限制


7.flush_old_exec

(1)建立独立的信号处理表,不再与父进程共享(见8)

(2)释放从父进程继承来的用户空间(见9)

运行后子进程有了独立的用户空间,但是大小为0

即放弃从父进程继承来的全部空间,不管是通过复制不断是通过共享

(3)修改程序名

(4)如果当前进程曾是父进程的一个线程,共享父进程的用户空间,则从线程组中脱离,因为有了独立的空间

(5)关闭文件

打开文件的信息也是从父进程继承过来的。扫描文件位图指示,把打开的文件关掉


8.建立独立的信号处理表

(1)为独立的信号处理表开辟空间并复制或赋值

(2)递减父进程信号处理表的引用计数

(3)若父进程信号处理表的引用计数减为0,则释放

(4)若信号处理表的表项指向用户空间的子程序,则改为SIG_DFL

中断向量表的表项一定指向一个中断服务程序

信号处理表的表项有三种:忽略SIG_IGN,默认SIG_DFL,指向用户空间的子程序

因为用户空间已经被释放了,所以要改


9.exec_mmap:释放从父进程释放的用户空间

(1)若子进程的用户空间是通过复制得到的,则

A.唤醒父进程

B.释放mm_struct中所有的vm_area_struct结构

C.页面表的表项清0

D.使高速缓存与内存一致

(2)若子进程的用户空间是通过共享得到的,则

A.为进程分配一个mm_struct结构

B.把新的mm_struct结构加入到全局的mm_struct队列中

C.设置mm_struct为进程的当前用户空间

D.切换到当前用户空间

E.唤醒父进程

F.若父进程用户空间的引用计数减为0,则释放(移出全局的mm_struct队列,并释放空间)

G.释放一个临时的mm_struct(只是减少引用计数)


10.一些初始化

(1)设置代码段、数据段、bss段要存放的位置

数据段存放的是已经初始化的全局变量和静态变量

bss段存放的是未初始化的全局变量和静态变量

(2)计算权限


11.根据a.out具体的不同格式,以不同的方式装入代码段和数据段

(1)若是OMAGIC类型,则:

  A.为代码段和数据段合在一起分配空间

B.把代码段和数据段从文件是读来

(2)若不是OMAGIC类型,则:

  A.分别将文件中的代码和数据段映射到进程的用户空间,映射地址与装入的地址一致


12.装入堆栈段

(1)在用户空间的堆栈区顶部建立一个卡虚存空间,将参数与环境变量所占的物理页面与些虚存区间建立映射

由此可见,堆栈的起始位置不是严格地从3G位置开始的

(2)在堆栈的栈顶构筑envp[],argv[]和argc

Logo

更多推荐