0x04 LiteOS内核详解--一个elf文件中有什么?
本章将带领大家从一个Huawei_LiteOS.ELF文件里面有什么开始分析,为后面的内核分析做铺垫,特别是“中断接管”以及“启动流程“和本章有这紧密的联系。
一、ELF文件和BIN文件有什么区别?
先来看看同一个程序生成的ELF文件和BIN文件的大小:
不看不知道,一看吓一跳,同一个程序的ELF文件居然比BIN文件大10倍!
如果你拥有一个ELF文件可以通过objcpy指令生成BIN文件,但是BIN文件不能生成ELF文件,它俩的关系是ELF文件包含BIN文件,也就是说BIN文件中有的东西ELF文件中也有,现在我们先讨论一下ELF文件中有的东西但是BIN文件中没有的东西。
“DEBUG”功能和“打断点”调式的功能相信大家都用过,可以一边看汇编代码、C代码,或者打上一个断电,让程序运行到断电处停止,这就是ELF文件的功能。
ELF文件中包含加载地址、运行地址、重定位表、符号表、汇编语句、注释等等信息。
BIN文件中只有机器码,STM32一次读取4字节执行。
上图是我通过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就是需要跳转到的地址。
第三帧数据是0x0800_8f01,这里的地址为0x0000_0008是NMI中断向量,CPU会将0x0800_8f01读入PC,跳转到0x0800_8f00的地方执行NMI中断处理函数。
我们就分析到这里吧,以上分析只想向大家说明一个问题,BIN文件中的每一条数据和FLASH中的数据一模一样,位置也是一一对应,最前面的就是中断向量表,LiteOS中通过设置一个数组,将这个数据链接到.isr_vector段中,也就是BIN文件最前面的那几条,到底有几条取决于LiteOS中配置了多少个中断。
二、反汇编Huawei_LiteOS.ELF文件
如果我们通过文本编辑器打开Huawei_LiteOS.ELF文件,将会看到全是数字,无法分析。
这时需要用到objdump命令,将ELF文件反汇编为汇编文件便于分析。
以下是我截取的部分具有代表性的段:
这些段构成一个STM32程序的基本单元
.isr_vector 存放中断向量表,LiteOS用一个数组来替代并通过链接脚本,将这个数组链接到中断向量段,发生中断时,就会跳到这个段中的某个地址处,将这个地址处的值读到PC中,去执行相应的中断处理函数,这里是重点,后面讲硬件接管中断的时候就要来说了。
.text 代码段,所有函数也就是代码都会被链接到.text段中存储,被链接到.text段中的数据在程序运行中一般是不会被修改的,也不可以被修改。
.bss 我们定义的初始值为0或者无初始值的全局变量和静态局部变量会被链接到这个段中保存,这样就不用为这个数据分配存储空间了,只要告诉单片机从xxx地址开始到xxx地址结束的数据为bss段,在复位中断中,通过汇编代码将这块数据清0即可,大大减小了BIN文件的大小。
.comment 注释段,这个段中存放一些注释信息,生成链接文件时,这个段中的信息不会被保存下来。显示编译器的一些信息,所以没必要放到BIN文件中。
.data 数据段,有初值并且初值不为0的全局变量和静态局部变量放到这个段中。
.rodata 只读数据段,被const修饰的数据会被放到这个段中。
本篇文章点到为止,不过多的深入讲解,因为只是为了后面做LiteOS中断接管机制的一个铺垫,如果大家有兴趣了解更多相关知识,可以留言或者私信我你想听的内容,感谢!
- 点赞
- 收藏
- 关注作者
评论(0)