Linux系统内核研究之可执行文件格式
2012-05-04 13:15
357 查看
Linux系统内核研究之可执行文件格式
时间:2007-01-30 11:48:44 来源:Linux联盟收集整理 作者:
我们知道Linux环境下不是所有的二进制文件都有相同的格式,Linux系统使用二进制文件的处理程序来实现对不同二进制格式文件的分别处理。二进制处理程序通过内嵌在文件开头的“特征序列”(一个特殊的字节序列)来识别文件,有时也会通过文件名的一些特征,例如ELF文件以’E’’L’’F’字符开头,Java文件以0xcafebabe开始前四个字节。
Linux用sys_execve装入可执行二进制文件。
1.当前Linux版本(2.2)提供以下几种二进制文件处理程序:
? a.out:主要时为了和以前兼容,因为a.out很难实现动态链接,以被ELF所取。
? ELF:现在主流的Linux二进制文件。尽管如此,她一样要和其他格式一样需要使用二进制处理程序。
? EM86:主要作用是在Alpha的主机上运行Intel的Linux二进制文件,仿佛他们就是Alpha的本地二进制文件。
? Java:通过以.class文件的文件名为参数,处理程序返回执行字节码的解释程序。
? Misc:最明智的二进制处理程序的方法。她通过内嵌的特征数字或文件名后缀识别二进制格式。另外她可以运行期配置,而不是只能在编译期配置,这样,你就可以在增加新二进制格式文件的支持而不用重新编译内核。有说将用她取代Java和EM86二进制处理程序。
? 脚本:主要支持shell脚本、Perl脚本,宽松一点说,所有前面两个字符是#!的可执行文件都由她来处理。
在继续向下介绍之前,我们必须先来认识一个数据结构linux_binfmt;
struct linux_binfmt{
struct linux_binfmt * next;
long *use_count;
int (*load_binary)(struct linux_binprm *,struct pt_regs *regs);
int (*load_shlib)(int fd);
int (*core_dump)(long signr,struct pt_regs *regs);
};
在linux_binfmt中包含两个重要指向函数的指针,load_binary装入可执行代码,load_shlib装入共享库。Core_dump是个转储函数指针。
很显然,由next构成一个链表,表头则由formats指向:
static struct linux_binfmt *formats=(struct linux_binfmt *)NULL;
系统为每个不同的文件格式定义了一个相应的对象:
static struct linux_binfmt elf_format;
static struct linux_binfmt java_format;
static struct linux_binfmt em86_format;
……
linux_binfmt的链表(由formats指向)则就是由这些不同的文件格式的linux_binfmt构成的一个链表。而对不同格式二进制文件的处理程序则通过注册在相应的linux_binfmt中的函数来实行,实际这里已经使用了面向对象的思想,而这种情况在Linux的内核源码中经常可以看到。
例如对于ELF文件格式:
当使用“装入函数的指针”使,指针指向装入函数分别为:
load_elf_binary(struct linux_binprm *bprm,struct pt_regs *regs);
static int load_elf_library(int fd);
以上函数在中定义实现。
而相应的elf_format 被定义成:
static struct linux_bmfmt elf_format={
#ifndef MODULE
NULL,NULL,load_elf_binary,load_elf_library,elf_core_dump
#else
NULL,&mod_use_count,load_elf_binary,load_elf_library,
elf_core_dump()
#endif
};
以此为参考我们自然也就可以想到其他文件格式的定义形式。
『注』Java的load函数为load_java,em86的load函数为load_em86,script 的load函数为load_script,他们没有提供library的load函数。
2.下面我们来看看关于这几个数据结构的主要操作:
register_binfmt:主要作用使将一中二进制文件加到formats链表中。
extern int register_binfmt(struct linux_binfmt *);
unregister_binfmt:执行与register_binfmt的反操作。
extern int unregister_binfmt(struct linux_binfmt *);
init:对于每个不同的二进制文件格式系统都提供了一组init操作,如下:
extern int init_elf_binfmt(void);
extern int init_aout_binfmt(void);
extern int init_script_binfmt(void);
extern int init_java_binfmt(void);
extern int init_em86_binfmt(void);
extern int init_misc_binfmt(void);
以上函数在中声明;
init函数的作用很简单,只是调用register_binfmt函数将自己的文件格式加入formats链表。
load函数:执行二进制文件调入工作,其实质工作一般都由一个相应do_load函数来完成。如:
do_load_elf_binary,do_load_elf_library,do_load_java……
extern int prepare_binprm(struct linux_binprm *);
extern int search_binary_handler
(struct linux_binprm*,struct pt_regs *);
这两个函数主要就涉及到另一个数据结构linux_binprm,她吗那就下次再说吧,到这里大家应该对Linux下几种二进制文件处理程序有个大体的印象了,具体细节去看看源代码吧。
时间:2007-01-30 11:48:44 来源:Linux联盟收集整理 作者:
我们知道Linux环境下不是所有的二进制文件都有相同的格式,Linux系统使用二进制文件的处理程序来实现对不同二进制格式文件的分别处理。二进制处理程序通过内嵌在文件开头的“特征序列”(一个特殊的字节序列)来识别文件,有时也会通过文件名的一些特征,例如ELF文件以’E’’L’’F’字符开头,Java文件以0xcafebabe开始前四个字节。
Linux用sys_execve装入可执行二进制文件。
1.当前Linux版本(2.2)提供以下几种二进制文件处理程序:
? a.out:主要时为了和以前兼容,因为a.out很难实现动态链接,以被ELF所取。
? ELF:现在主流的Linux二进制文件。尽管如此,她一样要和其他格式一样需要使用二进制处理程序。
? EM86:主要作用是在Alpha的主机上运行Intel的Linux二进制文件,仿佛他们就是Alpha的本地二进制文件。
? Java:通过以.class文件的文件名为参数,处理程序返回执行字节码的解释程序。
? Misc:最明智的二进制处理程序的方法。她通过内嵌的特征数字或文件名后缀识别二进制格式。另外她可以运行期配置,而不是只能在编译期配置,这样,你就可以在增加新二进制格式文件的支持而不用重新编译内核。有说将用她取代Java和EM86二进制处理程序。
? 脚本:主要支持shell脚本、Perl脚本,宽松一点说,所有前面两个字符是#!的可执行文件都由她来处理。
在继续向下介绍之前,我们必须先来认识一个数据结构linux_binfmt;
struct linux_binfmt{
struct linux_binfmt * next;
long *use_count;
int (*load_binary)(struct linux_binprm *,struct pt_regs *regs);
int (*load_shlib)(int fd);
int (*core_dump)(long signr,struct pt_regs *regs);
};
在linux_binfmt中包含两个重要指向函数的指针,load_binary装入可执行代码,load_shlib装入共享库。Core_dump是个转储函数指针。
很显然,由next构成一个链表,表头则由formats指向:
static struct linux_binfmt *formats=(struct linux_binfmt *)NULL;
系统为每个不同的文件格式定义了一个相应的对象:
static struct linux_binfmt elf_format;
static struct linux_binfmt java_format;
static struct linux_binfmt em86_format;
……
linux_binfmt的链表(由formats指向)则就是由这些不同的文件格式的linux_binfmt构成的一个链表。而对不同格式二进制文件的处理程序则通过注册在相应的linux_binfmt中的函数来实行,实际这里已经使用了面向对象的思想,而这种情况在Linux的内核源码中经常可以看到。
例如对于ELF文件格式:
当使用“装入函数的指针”使,指针指向装入函数分别为:
load_elf_binary(struct linux_binprm *bprm,struct pt_regs *regs);
static int load_elf_library(int fd);
以上函数在中定义实现。
而相应的elf_format 被定义成:
static struct linux_bmfmt elf_format={
#ifndef MODULE
NULL,NULL,load_elf_binary,load_elf_library,elf_core_dump
#else
NULL,&mod_use_count,load_elf_binary,load_elf_library,
elf_core_dump()
#endif
};
以此为参考我们自然也就可以想到其他文件格式的定义形式。
『注』Java的load函数为load_java,em86的load函数为load_em86,script 的load函数为load_script,他们没有提供library的load函数。
2.下面我们来看看关于这几个数据结构的主要操作:
register_binfmt:主要作用使将一中二进制文件加到formats链表中。
extern int register_binfmt(struct linux_binfmt *);
unregister_binfmt:执行与register_binfmt的反操作。
extern int unregister_binfmt(struct linux_binfmt *);
init:对于每个不同的二进制文件格式系统都提供了一组init操作,如下:
extern int init_elf_binfmt(void);
extern int init_aout_binfmt(void);
extern int init_script_binfmt(void);
extern int init_java_binfmt(void);
extern int init_em86_binfmt(void);
extern int init_misc_binfmt(void);
以上函数在中声明;
init函数的作用很简单,只是调用register_binfmt函数将自己的文件格式加入formats链表。
load函数:执行二进制文件调入工作,其实质工作一般都由一个相应do_load函数来完成。如:
do_load_elf_binary,do_load_elf_library,do_load_java……
extern int prepare_binprm(struct linux_binprm *);
extern int search_binary_handler
(struct linux_binprm*,struct pt_regs *);
这两个函数主要就涉及到另一个数据结构linux_binprm,她吗那就下次再说吧,到这里大家应该对Linux下几种二进制文件处理程序有个大体的印象了,具体细节去看看源代码吧。
相关文章推荐
- linux的几个内核镜像格式Image 和 u-boot启动内核和文件系统时的一些环境变量的设置
- 通过ramdisk内核模块研究Linux文件系统
- 基于S3C2440的Linux内核移植和yaffs2文件系统制作--Bootloader的执行过程
- linux2.6.30.4内核移植(5)——构建根文件系统(yaffs文件系统格式的镜像)
- Linux 2.6内核配置说明(8----Executable file formats可执行文件格式)
- Linux 2.6.11内核文件IO系统调用详解
- Linux下挂载NTFS格式文件系统
- 使用 /proc 文件系统来访问 Linux 内核的内容
- 20135337——Linux实践三:ELF文件格式(64位系统,简单分析)
- 在Ubuntu上为Android系统内置C可执行程序测试Linux内核驱动程序
- Linux 内核编程之文件系统 VFS中的目录项对象和文件对象 http://www.linuxidc.com/Linux/2011-02/32127p2.htm
- 使用 /sys 文件系统访问 Linux 内核
- 使用 /sys 文件系统访问 Linux 内核
- Linux虚拟文件系统(内核初始化<一>)
- 【linux】内核+文件系统下载到开发板
- 几个重要的Linux系统内核文件介绍
- linux-2.6.24.4内核移植到s3c2440----使用busybox-1.9.2制作根文件系统
- 基于S3C2440的Linux内核移植和yaffs2文件系统制作--修改Linux源码参数
- 使用 /proc 文件系统来访问 Linux 内核的内容
- real6410移植linux2.6.39.4内核(2)-添加nand flash驱动及启动cramfs文件系统