详解 Linux 可执行文件 ELF 文件的内部结构
2020-07-08 18:53:47 最后更新: 2020-07-08 18:53:47 访问数量:424
2020-07-08 18:53:47 最后更新: 2020-07-08 18:53:47 访问数量:424
上一篇文章中,我们介绍了如何让汇编语言与 C 语言相互调用:
还记得我们自制操作系统的脚步到哪里了呢?没错,已经完成了从启动扇区跳转到 loader,那么,下一步就是如何用 loader 拉起内核了
有了上面汇编语言调用 C 语言的基础,我们就可以做到让汇编语言编写的 loader 拉起用 C 语言编写的内核了,本文我们就来详细了解一下编译后的可执行文件 -- ELF 文件的结构,下一篇文章将会介绍如何通过汇编将 ELF 文件载入内存并执行
上一篇文章中,当我们编译汇编代码时,指定了 -f elf 参数:
nasm -f elf -o asm.o main.asm
这就意味着生成的 asm.o 是 ELF 文件(Executable and Linkable Format)
所谓的 ELF 文件,翻译过来就是“可执行与可链接文件”,是一种用于二进制文件之间相互调用的可执行文件格式,通过链接即可引入调用,拥有非常强大的可扩展性和灵活性
在 linux 中,可执行文件、Object文件、动态库文件都是ELF格式文件,他相当于 windows 操作系统中的 PE 文件
通过 readelf
命令可以读取 ELF 文件的内容
要想使用 ELF 文件,我们首先必须知道 ELF 文件是如何构成的
如上图所示,ELF 文件由四部分组成:
并非所有的 ELF 文件都包含全部上述四部分,除了 ELF 头外,其他各部分的位置、大小都不固定
这里提到了“节”的概念,上一篇文章中,我们在汇编中使用了 section 关键字,就是指定了对应代码块的 section 类型,linux 支持下面的三种 section:
既然除了 ELF 头外其他部分的位置、大小都不固定,那么他们又是如何决定的呢?很简单,他们的位置和大小都是由 ELF 头中的字段声明的
ELF 头的格式如下:
上面使用到的数据类型如下:
名称 | 大小 | 对齐 | 用途 |
Elf32_Addr | 4 | 4 | 无符号程序地址 |
Elf32_Half | 2 | 2 | 无符号中等大小整数 |
Elf32_Off | 4 | 4 | 无符号文件偏移 |
Elf32_Sword | 4 | 4 | 有符号大整数 |
Elf32_Word | 4 | 4 | 无符号大整数 |
unsigned char | 1 | 1 | 无符号小整数 |
下图展示了上篇文章中我们生成的两个文件通过 readelf 命令读取到的头信息:
Section Header Table 中的每个条目 Section Header 都描述了 ELF 文件中 Sections 区域中一个节的信息
他的结构如下:
下图展示了上篇文章中可执行文件 main 的 Section Header 结构:
Program Header Table 中的条目 Program Header 是与程序执行直接相关的,他描述了一个即将被载入内存的段在文件中的位置、大小以及它被载入内存后所在的位置和大小
一个段包含一个或多个节
Program Header 结构如下:
通过 readelf -l
命令我们就可以查看文件的 program headers 信息了:
从图中,我们可以看到这个 ELF 文件有五个 Program header 条目
本文,我们介绍了 ELF 文件的四个组成部分,以及其中三个的具体结构,而实际存储数据的 section 的结构我们并没有介绍
别忘了我们的目标,我们需要通过汇编语言编写的 loader 程序将在 linux 环境上编译的 C 语言内核程序载入到内存并执行,因此,实际上我们只需要知道 ELF 文件需要如何被载入内存,并从哪里开始执行
了解了上面的结构信息,你就会发现,事实上与我们的目标直接相关的是 ELF 文件中的 Program Header 部分,他描述了可执行文件中有那几个段,每个段需要被载入到内存的哪个位置,而每个段包含多少个节、以及每个节内部的具体信息我们其实并不需要关心
也就是说,我们通过 ELF header 中的字段,找到 Program Header Table,然后读取每个 Program Header,将对应的段载入到内存指定的位置,然后跳转,即可实现可执行文件的执行了
这样一来,是不是读取 ELF 文件并载入内存的工作已经呼之欲出了呢?
敬请期待博主下一篇文章,详细讲解 loader 加载内核的完整代码
https://blog.csdn.net/mergerly/article/details/94585901
http://www.choudan.net/2013/11/16/Linux%E8%BF%9B%E7%A8%8B%E5%9C%B0%E5%9D%80%E7%A9%BA%E9%97%B4%E5%86%8D%E5%AD%A6%E4%B9%A0.html
http://www.choudan.net/2013/10/25/Linux%E8%BF%9B%E7%A8%8B%E5%9C%B0%E5%9D%80%E7%A9%BA%E9%97%B4%E5%AD%A6%E4%B9%A0%28%E4%BA%8C%29.html