目录
1.普通文件的加载
1.1程序要被运行,首先要被编译成可执行程序
使用绝对编址的方式,对每个指令,进行编址,然后将链接了哪些动态库,main函数的地址(虚拟地址),代码区,数据区,已初始化的数据.....各个区域的大小划分,存储到到表头中。
1.2程序要被运行必须先加载到内存
在加载内存之前,为其创建task_struct管理进程,打开文件,将文件的fd填入task_struct中。
然后讲表头的数据读到缓冲区刷新到内核,初始化进程地址空间mm_struct,分配每个空间的大小。
然后加载文件的内容,拷贝到物理内存。
在页表中建立,虚拟地址到物理地址的映射。
1.3程序运行必须要被cpu执行
当指令寄存器,执行指令的时候,需要访问物理地址,这是时候cpu会给MMU一个请求,MMU区页表中查询,将虚拟的地址转化为物理地址。
1.4结论
虚拟地址空间并不是有操作系统一个完成的,而是需要cpu,编译器,操作系统,三者共同联动,互相配合,编译器在编译的时候就已经生成虚拟地址了,CPU的MMU + 操作系统的页表才能讲虚拟的地址转化为物理地址。
2.动态库的加载
我们这里是说动态库的不同。
我们可执行程序的ELF表头里存着,该程序需要用到哪些动态库,会把这些动态库加载到内存。
动态库会被映射到mm_struct的共享区
动态库的起始地址会被记录_start,使用_start + 偏移量的方式就可找到,动态库的某个函数。