注:本文档为《从0学x86操作系统》课程配套的学习文档,提供相应的辅助学习资料和答疑勘误。 有关该课程的信息,请点击这里访问:https://study.163.com/provider/1017884735/index.htm 在阅读本文档时,如有疑问和建议,欢迎在下方留言或者直接联系我。
本课时主要帮助同学了解可执行文件.elf的文件格式,以及如何对.elf文件格式进行解析,并加载到内存中。
下面的文字主要对elf文件格式和加载过程做简要的分析,详细的信息需要查看【参考资料】中的文档,以及本课时的视频。
ELF文件格式
windows的可执行文件格式通常为.exe结尾的PE 文件格式,而linux/unix用得更多的则为elf文件格式。我们的工具链编译生成的即为这种文件格式。此种文件格式结构简要图如下。对我们而言,只需要关注下图右半部分(即Execution View,左半部分是给链接器用的)。
(摘自ELF_Format.pdf,第7页)
该文件中包含了前一节课时中提到的.text/.rodata/.data/.bss各段的信息。通常解析该文件,找到program header table,从该表中,即可从中读取出相应的代码、数据段的相关信息,并可根据该信息将代码或数据加载到对应的内存中,完成整个加载过程。
其中elf header包含了有关该文件的全局性配置数据,以及描述了该文件的具体结构,其位于文件的最开头。
programe header table具体在文件中的位置,由e_phoff来指定,该位置存储了以下结构体数组。表项数量由e_phnum来决定。
该结构体描述了需要加载到内存中的相关配置信息,我们可以根据其中的配置,进行解析加载。根据以下分析,具体的加载过程如下:
- 初步检查elf header的合法性(课程中只做了非常简单的检查)
- 通过elf header->e_phoff定位到programe header table,遍历elf header->e_phnum次,加载各个段
- 从文件位置p_offset处读取filesz大小的数据,写入到内存中paddr的位置处
- 如果p_filesz < p_memsz,则将部分内存清零(bss区初始化)
- 取elf header->e_entry,跳转到该地址运行。
下图仅为某elf文件的内容存储示例,不同elf文件可能组织不同。课程视频中所展示的为text, rodata, data, bss被组织在一起,而非下图的分开存放。
(注:以上不考虑虚拟内存开启的情况,所以不关注vaddr,以后会再讲这部分)
参考资料
- ELF文件格式简介及加载过程:https://wiki.osdev.org/ELF
- ELF格式详细说明:ELF_Format.pdf(见课程附带的文档资料中)