1.程序如何被操作系统装载到内存中运行?
(1)覆盖装入这种方法基本被淘汰了,但书上说它体现的思想有借鉴意义。再嵌入式内存受限条件下,特别是诸如DSP等,或与有用武之地。(什么是DSP?????) 覆盖的大概原理就是加入程序有AB俩个模块。AB可以共享一块内存区域,当用到A时把A调用进来覆盖掉B,或B的某部分。当需要B时同理。(2)页映射 这个大家应该再熟悉不过了。就是把程序分成页之后,程序中的页和内存总的页存在对应关系。(谁对应谁无所谓)。用到谁的时候就把谁给调用进来。至于把谁替换出去,就要看操作系统的选择的算法了。比如FO(first in first out~~) 2.从操作系统看可执行文件的装载1.进程的建立:(1)创建虚拟地址空间:按书上说的是创建映射函数所需的相应的数据结构。(说实话没什么感性的认识,就认为是在磁盘上建立个数据结构)(2)读取可执行文件头,建立虚拟空间与可执行文件的映射关系由于发生页错误的时候,系统会将缺的页调入内存中。所以知道将要调入的页在可执行文件中的位置便十分重要了。所以要建立可执行文件到虚拟空间的映射。已经很白了~~~~如果再说的话,就是把各个段放到虚拟空间中去(这么说是不是不标准???)。(3)将CPU指令的寄存器设置成可执行文件的入口,启动运行。3.进程虚拟空间的分布
(1)ELF文件链接视图和执行视图如果每个段分别对应一个物理页,会造成页的浪费。而事实上操作系统并不关心可执行文件的各个段所包含的实际内容,只关心跟装载有关的内容。ELF文件中,段的权限基本只有一下几种:(1)可读可执行段(2)可读可写段(3)只读段所以,我们可以把相同权限的段合并到一起进行映射。
而数个相同属性的“section”合并到一起就形成了“segment”。相当于从装载的角度重新划分了ELF文件。系统是按照“segment”而不是“section”来映射可执行文件的。
这里书中又提出了两个概念:
(1)描述”section“属性的结构叫做段表。(2)描述“segment”的结构叫做程序头。 随后书中又介绍了程序头表,但特别说明了一种情况。即,程序头表结构中的p_memsz可能会大于p_filesz。原因是段会给BSS“section”额外的空间,这样就不用再建立BSS“segment”了(这里的section和segment的区别应该对吧??????)。4.堆和栈
书中的意思就是堆和栈在虚拟空间中的存在也是VMA形式的。代码VMA:r x 有映像文件
数据VMA:rw x(??不一定可执行,shellcode?)有映像文件堆VMA:rwx无映像文件 向上扩展栈VMA:rw无映像文件,向下扩展段地址对齐:
还是为了防止浪费,在进程虚拟内从空间中,逻辑上看做按“系统页面”的大小进行分配。但两个段中间的那个页要被映射两遍到物理内存中,用到谁就把谁映射到内存中。