raw binary文件探秘

本文通过一个名为raw_binary.c的示例程序,详细介绍了如何生成和解析raw二进制文件。程序经过特定链接脚本处理,生成的可执行文件不依赖C库,直接调用my_test_func作为入口。转换后的raw_binary.rb文件包含.text、.eh_frame和.data节的内容,无额外描述信息。当将该文件内容加载到内存并执行,程序能够正常运行,展示了raw二进制文件的运行机制。
摘要由CSDN通过智能技术生成
Linux下的目标文件、动态库文件、可执行文件,其格式为elf格式。
elf文件是有结构的文件,其内部有丰富的信息,例如,可能包含了可执行文件的入口地址,各个节的起始地址,可重定位信息,还可能包含指令与代码行的对应关系(用于调试)。
内核则利用elf文件中的相关信息,加载运行可执行文件。
然而内核映像,u-boot映像这些特殊的文件,则是raw_binary文件。这当然有他的原因。
以u-boot为例,cpu通电后,就开始执行指令。而首先要执行的就是u-boot中的指令。然而cpu不具备解析elf文件的能力,他只知道执行指令。因此,只好给他一块纯粹的机器码让他跑。
因此,u-boot映像就做成了raw_binary文件。
raw_binary文件是没有任何结构的,其内容就是赤裸裸的代码与数据的组合体。
因此,不具备可解析性。


下面以一个简单的小例子,来看看raw_binary文件的面貌。

raw_binary.c是个简单的小程序,其内容如下:

char the_data[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
char bss_data1[3], bss_data2[4];

/* 为了初始化bss节,这里借助链接脚本中创建的两个符号,以得到bss节的地址区间 */
extern char __bss_start[], __bss_end[];
void init_bss_area();

void my_test_func()
{
    /* 为了能以raw binary形式运行,程序自己实现对bss节的清零 */
    init_bss_area(); 
    
    the_data[1]++;
    
    while (1)
    {
        asm volatile ("nop");
    }
}

void init_bss_area()
{
    int i, len = __bss_end - __bss_start;
    for (i=0; i<len; i++)
        __bss_start[i] = 0;
}

我们通过如下命令将上述代码编译成一个可执行文件。

[root@localhost raw_binary]# gcc -O2 -c raw_binary.c  -o  raw_binary.o
[root@localhost raw_binary]# ld -T raw_binary.lds raw_binary.o  -o raw_binary.exe

注意,上述编译过程中,我们用到了一个链接脚本raw_binary.lds。其内容如下:

ENTRY(my_test_func)
SECTIONS
{
    /* 这里设置代码段从2M开始 */
    . = 0x200000;
    .text :      
    {
        *(.text)
    }
    
    /* 我们让数据段的虚拟地址空间开始于8字节对齐的地方 */
    . 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值