0x04 LiteOS内核详解--一个elf文件中有什么?

举报
樊心昊 发表于 2020/06/22 15:36:29 2020/06/22
【摘要】 本章将带领大家从一个Huawei_LiteOS.ELF文件里面有什么开始分析,为后面的内核分析做铺垫,特别是“中断接管”以及“启动流程“和本章有这紧密的联系。一、ELF文件和BIN文件有什么区别?先来看看同一个程序生成的ELF文件和BIN文件的大小:不看不知道,一看吓一跳,同一个程序的ELF文件居然比BIN文件大10倍!如果你拥有一个ELF文件可以通过objcpy指令生成BIN文件,但是BI...

本章将带领大家从一个Huawei_LiteOS.ELF文件里面有什么开始分析,为后面的内核分析做铺垫,特别是“中断接管”以及“启动流程“和本章有这紧密的联系。


一、ELF文件和BIN文件有什么区别?

先来看看同一个程序生成的ELF文件和BIN文件的大小:

不看不知道,一看吓一跳,同一个程序的ELF文件居然比BIN文件大10倍!image.png

如果你拥有一个ELF文件可以通过objcpy指令生成BIN文件,但是BIN文件不能生成ELF文件,它俩的关系是ELF文件包含BIN文件,也就是说BIN文件中有的东西ELF文件中也有,现在我们先讨论一下ELF文件中有的东西但是BIN文件中没有的东西。

“DEBUG”功能和“打断点”调式的功能相信大家都用过,可以一边看汇编代码、C代码,或者打上一个断电,让程序运行到断电处停止,这就是ELF文件的功能。

image.png

ELF文件中包含加载地址、运行地址、重定位表、符号表、汇编语句、注释等等信息。

BIN文件中只有机器码,STM32一次读取4字节执行。

image.png上图是我通过Hex Editor软件打开的BIN文件,第一帧数据0x0000_0000(16进制表示),代表栈顶地址设置为 0x0000_0000(16进制表示),对应我在stm32启动流程文章中说的“STM32上电后硬件会从0x0000_0000(0地址处会被映射到0x8000_0000,也就是Flash中)”地址处取处四字节数据,将这四字节数据设置为栈顶,大家可能想我问是不是搞错了?为什么是0x0000_0000,没错的,后面会重新设置的,不用担心。第二帧数据是0x0800_0441,这里的地址为0x0000_0004是复位中断向量,CPU会将这个数据读入PC寄存器,跳转到0x0800_0440地方执行复位中断处理函数,相信细心的同学注意到这里的最低位是1,但是我说的是跳转到0x0800_0440地方,这里涉及到ARM指令切换Thumb指令,所以PC的最低位需要写入1,大家只要记住这个数据减1就是需要跳转到的地址。

image.png

第三帧数据是0x0800_8f01,这里的地址为0x0000_0008是NMI中断向量,CPU会将0x0800_8f01读入PC,跳转到0x0800_8f00的地方执行NMI中断处理函数。

image.png

 

我们就分析到这里吧,以上分析只想向大家说明一个问题,BIN文件中的每一条数据和FLASH中的数据一模一样,位置也是一一对应,最前面的就是中断向量表,LiteOS中通过设置一个数组,将这个数据链接到.isr_vector段中,也就是BIN文件最前面的那几条,到底有几条取决于LiteOS中配置了多少个中断。

二、反汇编Huawei_LiteOS.ELF文件

如果我们通过文本编辑器打开Huawei_LiteOS.ELF文件,将会看到全是数字,无法分析。

image.png

这时需要用到objdump命令,将ELF文件反汇编为汇编文件便于分析。

以下是我截取的部分具有代表性的段:

 

image.png

image.png

image.png

image.png

image.png

image.png

 

这些段构成一个STM32程序的基本单元

.isr_vector      存放中断向量表,LiteOS用一个数组来替代并通过链接脚本,将这个数组链接到中断向量段,发生中断时,就会跳到这个段中的某个地址处,将这个地址处的值读到PC中,去执行相应的中断处理函数,这里是重点,后面讲硬件接管中断的时候就要来说了。

.text        代码段,所有函数也就是代码都会被链接到.text段中存储,被链接到.text段中的数据在程序运行中一般是不会被修改的,也不可以被修改。 

.bss        我们定义的初始值为0或者无初始值的全局变量和静态局部变量会被链接到这个段中保存,这样就不用为这个数据分配存储空间了,只要告诉单片机从xxx地址开始到xxx地址结束的数据为bss段,在复位中断中,通过汇编代码将这块数据清0即可,大大减小了BIN文件的大小。

 

.comment 注释段,这个段中存放一些注释信息,生成链接文件时,这个段中的信息不会被保存下来。显示编译器的一些信息,所以没必要放到BIN文件中。

image.png

.data 数据段,有初值并且初值不为0的全局变量和静态局部变量放到这个段中。

.rodata 只读数据段,被const修饰的数据会被放到这个段中。

 

本篇文章点到为止,不过多的深入讲解,因为只是为了后面做LiteOS中断接管机制的一个铺垫,如果大家有兴趣了解更多相关知识,可以留言或者私信我你想听的内容,感谢!


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。