ARM Cortex-M3 SoC运行程序的详细流程
目录
RAM的读写速度比ROM快
在过去的20年里,嵌入式系统一直使用ROM(EPROM)作为它们的存储设备,然而近年来Flash全面代替了ROM(EPROM)在嵌入式系统中的地位,用作存储Bootloader以及操作系统或者程序代码或者直接当硬盘使用(U盘)。
参考链接:
https://www.huaweicloud.com/articles/9d767b49832fd1fd5c6d23163d87b83e.html
https://blog.csdn.net/u012351051/article/details/81034661
相信很多嵌入式的Developer肯定知道startup.s(汇编文件)
它是系统的启动文件,程序上电复位之后第一个执行的程序,一般用来堆栈的初始化,设置中断向量表,以及跳转到main函数
但是学过操作系统的肯定知道bootloader,是一个系统的引导程序,同样是上电复位之后第一个执行的程序
那么两者到底是啥关系呢?谁先开始执行,谁后执行?哪一个执行哪一个不执行?如何执行?(可能自己之前是计算机专业的,对startup.s有困惑)
实际上:两者是干同样的事情的:先进行系统初始化,然后跳转到main函数运行程序
堆栈初始化
建立向量表
跳转到main函数
如果硬是要说区别的话,那就是bootloader要更加的复杂,能干的事情更多,通常如果要启动操作系统的话,或者写很复杂的程序的话就会使用到bootloader,说到这计算机背景的肯定就知道自己只接触过bootload了,因为基本计算机都要运行操作系统的
如果是普通的嵌入式应用的话,使用startup.s就好,
那具体分析一下,到底复杂到哪里:
bootloader会有文件驱动或者网络驱动,因为通常操作系统是放在硬盘中的,boloader如果要加载操作系统到系统RAM的话,就必须能够读取文件内容,而有的操作系统是通过网络启动
还有一个就是重映射的问题remap:
一般来说,ROM存储器从0x0处开始编址,里面存放有异常中断向量,但是ROM的读写速度是没有RAM高的
为了提高系统的性能,bootloader会将ROM中的数据copy到RAM中,然后进行地址的重映射,即将RAM映射到0x0地址处,这样在发生异常中断的时候,访问的就是RAM,而不是ROM
参考链接:
https://www.cnblogs.com/no7dw/archive/2012/06/28/2567113.html
https://blog.csdn.net/weiLongElectrophile/article/details/75043746
从ROM启动/boot ROM启动
这里我所理解的是如果要使用bootloader的话,就从boot ROM启动,这是可选的模块,可以通过参数配置来设置启动的模式
?
一般简单的嵌入式是用不到boot ROM的,(M3默认是不启用boot ROM)
这部分的内容也看了相关的文章,感觉有一些地方不是很通顺,我还是把链接放过来
参考链接:
https://www.huaweicloud.com/articles/e7597769b186ee314625969ffa806654.html?
从上面的分析可以知道M3 SoC是从room启动,使用的是startup.s
C语言程序 + startup.s + libc库文件
ps:这里使用的编译工具是arm-none-eabi-gcc。arm的gcc工具链有好几种,都有不同的应用场景,不要弄混了
gcc工具在编译之后,会使用链接程序linker将它们链接到一起,至于为什么还有会用到libc库文件,这和startup.s有关
The?
_start
?FunctionFor most C and C++ programs, the true entry point is not?
main
, it’s the?_start
?function. This function initializes the program runtime and invokes the program’s?main
?function.The use of?
_start
?is merely a general convention. The entry function can vary depending on the system, compiler, and standard libraries. For example,?OS?X only has dynamically linked applications; the?loader?takes care of setup, and the entry point to the program is actually?main
.The linker controls the program’s entry point. The default entry point can be overridden by clang and GCC linkers using the?
-e
?flag, although this is rarely done for most programs.The implementation of the?
_start
?function is usually supplied by?libc
. The?_start
?function is often written in assembly. Many implementations store the?_start
?function in a file called?crt0.s
. Compilers typically ship with pre-compiled?crt0.o
?object files for each supported architecture.
大概的意思是:
最后在编译之后,将这三部分链接形成一个完整的程序(通常这并不是直接能够运行在裸机上的文件,还需要转换成hex文件)
ps:这里分析一波startup.s文件干了什么事情
通常linker会将startup.s的相关内容放在这个完整的程序的开头
那么它干了什么事呢?
看图
解释一波:
首先就是堆栈的初始化(记住:裸机上要执行程序,首先就是要初始化一个堆栈,建立一个程序执行的环境)
然后是设置中断向量表(中断向量表第一个字是MSP,第二个字是reset handler的入口地址,后面解释)
最后是跳转到start函数,然后再跳转到main函数
?
有了可执行的程序了,接下来就是通过烧写工具将其烧写到ROM中,(不需要关心,知道ROM的数据是如何来的就好)
由上面的分析可以知道:
0x0:存放的是MSP(主栈指针)
0x4:存放的是PC(reset handler的入口地址)
系统上电复位之后,PC指针指向0x0出
处理器自动读取0x0的MSP指针存放到处理器的内部状态寄存器,PC指向0x4地址处(一个字32位)
然后跳转到reset handler执行
那么reset handler干了什么事情呢?
从start跳到main函数,这样就执行用户程序了~~
OK,OK(OK怪上线,哈哈哈),明白了吧~~哈哈
ps:start通常会干啥事?
Program startup code behavior is not specified by the C and C++ standards. Instead, the standards describe the conditions that must be true when the?
main
?function is called. However, there are many steps that are commonly performed across the majority of?_start
?implementations.At a high level, the?
_start
?function handles:
- Early low-level initialization, such as:
- Configuring processor registers
- Initializing external memory
- Enabling caches
- Configuring the?MMU
- Stack initialization, making sure that the stack is properly aligned per the?ABI?requirements
- Frame pointer initialization
- C/C++ runtime setup
- Initializing other scaffolding required by the system
- Jumping to?
main
- Exiting the program with the return code from?
main
While the?
_start
?routine typically encompasses these activities, the specific order and implementation varies from system to system. For example,?early low-level initialization?code is commonly found with bare-metal embedded systems, but rarely on host machines with an OS. Your Linux or OS X program startup code will have multiple scaffolding functions which you will not find in embedded startup code.
(这里我就不说了,感兴趣的自己去了解~)
下面贴了链接~~~
?
最后最后,上面都是自己个人的总结和见解,希望能够帮到大家
另外这里的谁太深了,还有很多东西我没有分析,这里就不在多少了,够用就好~~~,感兴趣的自己去看吧~,就在下面最后的链接?investigating what it takes to get to main。
谢谢大家,能够看到这里,希望能够帮到你们~~~哈哈
?
参考链接:
https://www.jianshu.com/p/fd0103d59d8e
https://blog.csdn.net/kagaobin/article/details/84198141
investigating what it takes to get to main
?
?
DELETEFROMTablesWHEREIDNOTIN(SELECTMin(ID)FROMTablesGROUPBYName) Min的话保...
工具:Eclipse,Oracle,smartupload.jar;语言:jsp,Java;数据存储:Oracle。...
本文实例讲述了Laravel框架源码解析之反射的使用。分享给大家供大家参考,具体如...
上篇文章给大家介绍了 Java正则表达式匹配,替换,查找,切割的方法 ,接下来,...
项目中用到的一些特殊字符和图标 html代码 XML/HTML Code 复制内容到剪贴板 div ...
4月11日20:30~22:00通过腾讯会议进行了第二次在线学习讨论我把学习笔记整理一下...
Elasticsearch 是通过 Lucene 的倒排索引技术实现比关系型数据库更快的过滤。特...
错误描述: 在开发.net项目中,通过microsoft.ACE.oledb读取excel文件信息时,报...
复制代码 代码如下: % URL="http://news.163.com/special/00011K6L/rss_newstop....
正则忽略大小写 – RegexOptions.IgnoreCase 例如: 复制代码 代码如下: Str = R...