FLASH算法
用来将程序镜像下载到嵌入式设备中的flash区间中的嵌入式程序。
Flash算法文件中的接口定义:
Flash算法文件实现的功能
以W801芯片为例,使用的算法文件为:W800_Flash_Tool.Elf。
什么是.elf文件?
.ELF是可执行文件的格式二进制文件。主要的文件类型有正常的可执行文件,可重定位目标文件、核心文件和共享目标文件。
ELF文件格式提供了两种不同的视角,在汇编器和链接器看来,ELF文件是由Section HeaderTable描述的一系列Section的集合,而执行一个ELF文件时,在加载器(Loader)看来它是 由Program Header Table描述的一系列Segment的集合。
ELF 文件headers说明
使用 ELF 文件格式的可执行文件包含一个 ELF标题,后跟程序标题表或节标题表,或两者。ELF 标头始终位于文件。程序头表和节头表的文件中的偏移量在 ELF 标头中定义。两张表 描述文件的其余特殊性。
基本类型
可以在elf.h文件中,看到基本的结构体定义:
以下类型用于 N 位架构(N=32,64,
ElfN代表Elf32或Elf64,uintN_t代表uint32_t或
uint64_t):
ElfN_Addr 无符号程序地址,uintN_t
ElfN_Off 无符号文件偏移量,uintN_t
ElfN_Section 无符号节索引,uint16_t
ElfN_Versym 无符号版本符号信息,uint16_t
Elf_Byte 无符号字符
ElfN_Half uint16_t
ElfN_Sword int32_t
ElfN_Word uint32_t
ElfN_Sxword int64_t
ElfN_Xword uint64_t
文件格式定义的所有数据结构都遵循相关类别的“自然”尺寸和对齐指南。如有必要,数据结构包含显式填充以确保4 字节对象的 4 字节对齐,强制结构大小为4 的倍数,依此类推。
ELF Header
在windows11系统下可使用内置的WSL,采用linux环境下的readlf工具读取其ELF Header和Section Header Table。
从ELF Header中可知:
操作系统是UNIX-System V,机器架构是C-SKY。
1、Section Headers
Section Header Table中有19个Section Header,从section headers起始地址46204(0XB47C)开始,每个Section Header占40字节,共760字节,到文件地址0x2F7结束。
下表为各字段的类型、偏移、虚拟地址等描述:
[Nr] | Name | Type | Addr | Off | Size | ES | Flg | Lk | Inf | Al |
---|---|---|---|---|---|---|---|---|---|---|
[ 0] | NULL | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ||
[ 1] | DevDscr | PROGBITS | 0 | 004f20 | 734 | 0 | 0 | 0 | 4 | |
[ 2] | .text | PROGBITS | 20000000 | 1000 | 002cb0 | 0 | AX | 0 | 0 | 1024 |
[ 3] | .rodata | PROGBITS | 20002cb0 | 003cb0 | 0.00E+00 | 0 | A | 0 | 0 | 4 |
[ 4] | .data | PROGBITS | 20003ab0 | 004ab0 | 470 | 0 | WA | 0 | 0 | 4 |
[ 5] | .bss | NOBITS | 20003f20 | 004f20 | 2430 | 0 | WA | 0 | 0 | 8 |
[ 6] | .comment | PROGBITS | 0 | 5654 | 42 | 1 | MS | 0 | 0 | 1 |
[ 7] | .csky.attributes | CSKY_ATTRIBUTES | 0 | 5696 | 27 | 0 | 0 | 0 | 1 | |
[ 8] | .csky_stack_size | PROGBITS | 0 | 0056c0 | 00028c | 0 | 0 | 0 | 16 | |
[ 9] | .debug_aranges | PROGBITS | 0 | 5950 | 0000b8 | 0 | 0 | 0 | 8 | |
[10] | .debug_info | PROGBITS | 0 | 005a08 | 00168f | 0 | 0 | 0 | 1 | |
[11] | .debug_abbrev | PROGBITS | 0 | 7097 | 737 | 0 | 0 | 0 | 1 | |
[12] | .debug_line | PROGBITS | 0 | 0077ce | 752 | 0 | 0 | 0 | 1 | |
[13] | .debug_frame | PROGBITS | 0 | 007f20 | 00044c | 0 | 0 | 0 | 4 | |
[14] | .debug_str | PROGBITS | 0 | 00836c | 000aa6 | 1 | MS | 0 | 0 | 1 |
[15] | .debug_loc | PROGBITS | 0 | 8.00E+12 | 0009de | 0 | 0 | 0 | 1 | |
[16] | .shstrtab | STRTAB | 0 | 00b3bc | 0000bf | 0 | 0 | 0 | 1 | |
[17] | .symtab | SYMTAB | 0 | 0097f0 | 0012c0 | 10 | 18 | 170 | 4 | |
[18] | .strtab | STRTAB | 0 | 00aab0 | 00090c | 0 | 0 | 0 | 1 |
主要字段描述
.text节
.text节是保存了程序代码指令的代码节。一段可执行程序,如果存在Phdr
,则.text节就会存在于text段中。由于.text节保存了程序代码,所以节类型为SHT_PROGBITS。
.rodata节
.rodata节保存了只读的数据,如一行C语言代码中的字符串。由于.rodata节是只读的,所以只能存在于一个可执行文件的只读段中。因此,只能在text段(不是data段)中找到.rodata节。由于.rodata节是只读的,所以节类型为SHT_PROGBITS。
.data节
.data节存在于data段中,其保存了初始化的全局变量等数据。由于.data节保存了程序的变量数据,所以节类型为SHT_PROGBITS。
.bss节
.bss节存在于data段中,占用空间不超过4字节.bss节保存了未进行初始化的全局数据。程序加载时数据被初始化为0,在程序执行期间可以进行赋值。由于.bss节未保存实际的数据,所以节类型为SHT_NOBITS。
把算法文件的所有编码打印出来:
执行:hexdump -C W800_Flash_Tool.elf
芯片相关信息:
显示入口地址和elf文件类型
头文件中的定义为:
2、Program Headers:
Program Header Table中有1个Program Header,从Program Headers起始地址52(0X34)开始,每个Program Header占52字节,到文件地址0x67结束。
在头文件中的定义部分如下:
在ELF_Header中,我们可以得到Program Header的索引地址(p_offset)、类型(p_type)、表项大小(p_filesz)等字段。
p_type 声明此段的作用类型
p_offset 段相对于文件的索引地址
p_vaddr 段在内存中的虚拟地址
p_paddr 段的物理地址
p_filesz 段在文件中所占的长度
p_memsz 段在内存中所占的长度
p_flage 段相关标志(read、write、exec)
p_align 字节对其,p_vaddr 和 p_offset 对 p_align 取模后应该相等。
头文件的其他定义请参考:
https://www.52pojie.cn/thread-591986-1-1.html