Linux内核源代码分析——可执行文件header处理(二进制文件读写范例,写DUL工具入门指引)...

在把Linux内核源代码生成Image之前,需要把执行文件头结构信息剔除出来。这个过程对理解Linux内核具有很大的帮助。同时,由于是对可执行文件进行直接读写操作,想写DUL工具的童鞋可以在这里学习到基本的二进制文件读写方法。

首先,我们看一下minix可执行文件的格式(Linux和minix很基情)。

struct exec {
 unsigned char a_magic[2];
 unsigned char a_flags;
 unsigned char a_cpu;
 unsigned char a_hdrlen;
 unsigned char a_unused;
 unsigned short a_version;
 long a_text;
 long a_data;
 long a_bss;
 long a_entry;
 long a_total;
 long a_syms;
 long a_trsize;
 long a_drsize;
 long a_tbase;
 long a_dbase;
};
下面来具体看下读写代码:linux/tools/build.c line 60-117
        char buf[1024];
	...
        ...
       for (i=0;i<sizeof buf; i++) buf[i]=0;                      //buf初始化
	if ((id=open(argv[1],O_RDONLY,0))<0)                       //处理boot二进制文件
        die("Unable to open 'boot'");
	if (read(id,buf,MINIX_HEADER) != MINIX_HEADER)             //读入MINIX_HEADER长度的内容
		die("Unable to read header of 'boot'");
	if (((long *) buf)[0]!=0x04100301)                         //其中的0x0301表示minix头部的a_magic魔数;0x10表示a_flag可执行;0x04 - a_cpu
		die("Non-Minix header of 'boot'");
	if (((long *) buf)[1]!=MINIX_HEADER)                       //a_hdrlen是否正确
		die("Non-Minix header of 'boot'");
	if (((long *) buf)[3]!=0)                                  //数据段长是否为0
		die("Illegal data segment in 'boot'");
	if (((long *) buf)[4]!=0)                                  //a_bss是否为0
		die("Illegal bss in 'boot'");
	if (((long *) buf)[5] != 0)                                //a_entry是否为0?哈哈,汇编的入口哦《Linux内核源代码分析——Linux内核入口》中的答案
		die("Non-Minix header of 'boot'");
	if (((long *) buf)[7] != 0)                                
		die("Illegal symbol table in 'boot'");
	i=read(id,buf,sizeof buf);
	fprintf(stderr,"Boot sector %d bytes.\n",i);
	if (i != 512)
		die("Boot block must be exactly 512 bytes");
	if ((*(unsigned short *)(buf+510)) != 0xAA55)
		die("Boot block hasn't got boot flag (0xAA55)");
	buf[508] = (char) minor_root;
	buf[509] = (char) major_root;	
	i=write(1,buf,512);                                         //剔除文件头之后,把执行代码写入标准输出
	if (i!=512)
		die("Write call failed");
	close (id);                                                 //处理boot二进制文件结束
	...
        ...       

所以,读写二进制文件的关键在于对Unix基本的api的熟悉。可以通过《Unix环境高级编程》得到这些基础知识。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值