14.2 a.out.h文件

14.2.1 功能描述

在Linux 内核中,a.out.h文件用于定义被加载的可执行文件结构。主要用于加载程序fs/exec.c中。该文件不属于标准C库,它是内核专用的头文件。但由于与标准库的头文件名没有冲突,因此在Linux系统中一般可以放/usr/include/目录下,以供涉及相关内容的程序使用。该头文件中定义了目标文件的一种a.out(Assembly out)格式。Linux 0.12系统中使用的.o文件和可执行文件就采用了这种目标文件格式。

a.out.h文件包括三个数据结构定义和一些相关的宏定义,因此文件可被相应地分成三个部分:

◆第1~108行给出并描述了目标文件执行头结构和相关的宏定义。

◆第109~185行对符号表项结构的定义和说明。

◆第186~217行对重定位表项结构进行定义和说明。

由于该文件内容比较多,因此对其中三个数据结构以及相关宏定义的详细说明放在程序列表后。

从0.96版内核开始,Linux系统直接采用了GNU的同名头文件a.out.h。因此造成在Linux 0.9x下编译的程序不能在Linux 0.1x系统上运行。下面对两个a.out头文件的不同之处进行分析,并说明如何让0.9x下编译的一些不是用动态链接库的执行文件也能在0.1x下运行。

Linux 0.12使用的a.out.h文件与GNU同名文件的主要区别在于exec结构的第一个字段a_magic。GNU的该文件字段名称是a_info,并且把该字段又分成3个子域:标志域(Flags)、机器类型域(Machine Type)和魔数域(Magic Number)。同时为机器类型域定义了相应的宏N_MACHTYPE和N_FLAGS,如图14-1所示。

Linux内核完全剖析---头文件

在Linux 0.9x系统中,对于采用静态库连接的执行文件,图中各域注释中括号内的值是该字段的默认值。这种二进制执行文件开始处的4个字节是:

0x0b, 0x01, 0x64, 0x00

而这里的头文件仅定义了魔数域。因此,在Linux 0.1x系统中一个a.out格式的二进制执行文件开始的4个字节是:

0x0b, 0x01, 0x00, 0x00

可以看出,采用GNU的a.out格式的执行文件与Linux 0.1x系统上编译出的执行文件的区别仅在机器类型域。因此我们可以把Linux 0.9x上的a.out格式执行文件的机器类型域(第3个字节)清零,让其运行在0.1x系统中。只要被移植的执行文件所调用的系统调用都已经在0.1x系统中实现即可。在开始重新组建Linux 0.1x根文件系统中的很多命令时,作者就采用了这种方法。

在其他方面,GNU的a.out.h头文件与这里的a.out.h没有什么区别。


相关内容