使用Python分析ELF文件优化Flash和Sram空间的案例

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Python分析ELF文件优化Flash和Sram空间的案例相关的知识,希望对你有一定的参考价值。

1. 背景

Zephyr项目Flash和Ram空间比较紧张,有着非常强烈的优化需求。

优化的前提是量化标的,那么如何量化Flash和Ram的使用量呢?

在量化之后,首先要对量化结果进行分析,然后采取措施进行空间优化。

2. 基于ELF信息和linker.cmd分析Flash/Ram使用量

linker.cmd文件中规定了不同section在Flash还是在Ram中,还是兼而有之。

这是一个很有用的信息,基于此我们只需要去罗列每个section的symbol,然后统计大小;就可以知道section的信息;进而知道都有那些symbol在(Flash, Ram)中,都与多大。

 

分析ELF文件可以获得Sections和Symbols的详细信息。

Sections信息可以将,Sections的Index和Name对应起来。

Symbols信息可以将Symbol的Name、Size、Index和Sections的Index对应起来。

这样子就可以对ELF文件形成ELF-->Sections-->Symbols的树形结构关系。

分析脚本在:elf_analyze_pro.ipynb

输出结果是每个sections中symbol大小降序排列的csv文件,和显示最高top_counts个大小列表。

 

3. 分析Flash/Ram使用情况

从Flash/Ram总大小使用情况,可以看出Ram空间告急,Flash空间也不乐观。

由于每个Section按降序排列了所有符号表,所以从最大入手效果最明显。

 

同时不同Section都有自己的特性,是A.仅在Ram中,还是B.仅在Flash中,还是C.两者都占用。

优化的首要目标是C情况,如果能将其从Ram中移出,仅在Flash中使用,那最好不过了。不过肯定会降低速度。

其次优化A情况,静态变量改成动态分配。针对变量分配浪费情况:不需要的结构体成员、变量类型紧凑等等。

最后是B情况,去掉冗余Log信息,将inline类型函数改成普通函数等等。

 

4. 优化记录

4.1 通过const修饰变量,将变量从datas转移到rodata

由于Section datas既占用了Flash又占用了Sram,存在一些变量可以修改成const类型,即只读变量。

就可以将此Symbol转移到rodata区域,使用的时候从Flash读取。

4.2 通过k_malloc从mem pool中动态申请内存

申请静态大变量,简单省事不易错,但是浪费了有限的Ram空间。

如果可以通过k_malloc从Mem pool中申请,将有助于提高Sram的利用率。

4.3 删除冗余结构体成员

比如struct uart_driver_api中很多成员,没有实现,也不会使用到。将其中部分成员注释掉,有助于降低结构体实例大小。

4.4 变量超配情况

一个标志位这种情况就没有必要使用int32这样的类型了。

4.5 inline类型函数的废弃

在CPU速度较慢但是ROM空间较大的系统中,使用inline有助于利用空间换时间。

但是在空间非常紧张的系统中,这就变成了缺点。将inline修饰符去掉,该成普通函数,将节省空间,虽然会增加函数调用开销。

4.6 控制Log使用量

Log存在分级,所以不需要的Log就不需要编译。

在量产的时候,关闭Log,节省的空间非常可观。

 

5. 结语

当然优化的路没有尽头,边走边记录吧。

 

以上是关于使用Python分析ELF文件优化Flash和Sram空间的案例的主要内容,如果未能解决你的问题,请参考以下文章

Android 逆向使用 Python 解析 ELF 文件 ( Capstone 反汇编框架 | PyCharm 中导入 Capstone 反汇编框架 )

linux实践之ELF文件分析

ELF文件格式分析

Linux及安全实践四——ELF文件格式分析

Linux内核分析——ELF文件格式分析

ELF分析 实践