Cortex-M3启动深度解析
Cortex-Mx启动,备忘,以免将来忘记。
中断向量表不用说,从重置中断开始吧
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
这里一共就执行了两个函数,SystemInit和__main。
我们一般在SystemInit里面配置系统时钟,这里跳过。
__main是我们今天的重点。
__main:
0x080000C0 LDR r0,[pc,#] ; @0x080000D4
0x080000C2 MOV sp,r0 #设置栈顶
_main_scatterload:
0x080000C4 F000F956 BL.W __scatterload (0x08000374) #分散加载(拷贝初始值、清零变量)
__main_after_scatterload:
0x080000C8 F000F8D4 BL.W __cpp_initialize__aeabi_ (0x08000274) #C++初始化(全局对象构造函数执行)
_main_cpp_init:
0x080000CC LDR r0,[pc,#] ; @0x080000D0
0x080000CE BX r0 #进入C++的main函数
分散加载这里将会初始化我们的全局静态变量
.text: __scatterload_rt2
.text: LDR R4, =Region$Table$Base
.text: MOVS R5, #
.text: LDR R6, =Region$Table$Limit
.text: B loc_14
.text: ; ---------------------------------------------------------------------------
.text:
.text: loc_8 ; CODE XREF: __scatterload_rt2+16j
.text: LDR R3, [R4,#0xC]
.text:0000000A LDMIA R4!, {R0-R2}
.text:0000000C ORRS R3, R5
.text:0000000E SUBS R4, #0xC
.text: BLX R3
.text: ADDS R4, #0x10
.text:
.text: loc_14 ; CODE XREF: __scatterload_rt2+6j
.text: CMP R4, R6
.text: BCC loc_8
.text: BL __main_after_scatterload
可能汇编看起来不是很直观,我们配合看F5得到的反编译C代码
void _scatterload_rt2()
{
_DWORD *i; // r4@1 for ( i = &Region__Table__Base; (_UNKNOWN *)i < &Region__Table__Limit; i += )
((void (__fastcall *)(_DWORD, _DWORD, _DWORD))(i[] | ))(*i, i[], i[]);
_main_after_scatterload();
JUMPOUT(&Region__Table__Base);
}
从上面看出,有一张区域表,每4个int作为一段,每一段前三个为参数,第四个为函数指针。
经过调试得知:
第一个函数是__scatterload_copy,从某个Flash地址把数据拷贝给RAM里面的变量,也就是带有初始值的全局变量;
第二个函数是__scatterload_zeroinit,顾名思义,就是全局变量清零,只要没有初始值的全局变量,都清零,堆空间和栈空间一块清。
而在汇编文件里面我们有AREA HEAP, NOINIT, READWRITE, ALIGN=3。显然其中的NOINIT并没有生效
ER_IROM1:0800D704 Region$Table$Base DCD 0x800D72C ; #要拷贝的初始值来源,紧跟在固件源代码后面
DATA XREF: ER_IROM1:__scatterload_rt2o
ER_IROM1:0800D704 ; ER_IROM1:off_8000390o
ER_IROM1:0800D708 DCD 0x20000000 #要复制初始值的起始地址
ER_IROM1:0800D70C DCD 0xCC #带有初始值的区域大小
ER_IROM1:0800D710 DCD __scatterload_copy
ER_IROM1:0800D714 DCD 0x800D7F8
ER_IROM1:0800D718 DCD 0x200000CC #要清零的变量起始地址
ER_IROM1:0800D71C DCD 0x132C #要清零的变量大小
ER_IROM1:0800D720 DCD __scatterload_zeroinit
ER_IROM1:0800D724 EXPORT SHT$INIT_ARRAY$Base
因此,针对__scatterload_zeroinit而言,为了加快启动速度,建议堆空间设得尽量小,然后在SmartOS系统初始化的时候再重新设置堆空间
Cortex-M3启动深度解析的更多相关文章
- ARM Cortex M3(V7-M架构)硬件启动程序 二
解析 STM32 的启动过程 解析STM32的启动过程 当前的嵌入式应用程序开发过程里,并且C语言成为了绝大部分场合的最佳选择.如此一来main函数似乎成为了理所当然的起点——因为C程序往往从main ...
- ARM Cortex M3(V7-M架构)硬件启动程序 一
Cortex-m3启动代码分析笔记 启动代码文件名是STM32F10X.S,它的作用先总结下,然后再分析. 启动代码作用一般是: 1)堆和栈的初始化: 2)中断向量表定义: 3)地址重映射及中断向量表 ...
- Kafka深度解析
本文转发自Jason’s Blog,原文链接 http://www.jasongj.com/2015/01/02/Kafka深度解析 背景介绍 Kafka简介 Kafka是一种分布式的,基于发布/订阅 ...
- java内存分配和String类型的深度解析
[尊重原创文章出自:http://my.oschina.net/xiaohui249/blog/170013] 摘要 从整体上介绍java内存的概念.构成以及分配机制,在此基础上深度解析java中的S ...
- Unity加载模块深度解析(Shader)
作者:张鑫链接:https://zhuanlan.zhihu.com/p/21949663来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 接上一篇 加载模块深度解析(二 ...
- SpringMVC 源码深度解析<context:component-scan>(扫描和注冊的注解Bean)
我们在SpringMVC开发项目中,有的用注解和XML配置Bean,这两种都各有自己的优势,数据源配置比較经经常使用XML配置.控制层依赖的service比較经经常使用注解等(在部署时比較不会改变的) ...
- String深度解析
文章出处:http://my.oschina.net/xiaohui249/blog/170013 一.引题 String类型是比较特殊的一种类型,同时也是面试经常被问到的一个知识点,本文结合java ...
- mybatis 3.x源码深度解析与最佳实践(最完整原创)
mybatis 3.x源码深度解析与最佳实践 1 环境准备 1.1 mybatis介绍以及框架源码的学习目标 1.2 本系列源码解析的方式 1.3 环境搭建 1.4 从Hello World开始 2 ...
- 并发编程(十五)——定时器 ScheduledThreadPoolExecutor 实现原理与源码深度解析
在上一篇线程池的文章<并发编程(十一)—— Java 线程池 实现原理与源码深度解析(一)>中从ThreadPoolExecutor源码分析了其运行机制.限于篇幅,留下了Scheduled ...
随机推荐
- Android TCP/IP 扫盲教程
TCP/IP 是因特网的通信协议. 通信协议是对计算机必须遵守的规则的描写叙述.仅仅有遵守这些规则.计算机之间才干进行通信. 浏览器和server都在使用 TCP/IP 因特网浏览器和因特网serve ...
- leetcode第一刷_Populating Next Right Pointers in Each Node II
很自然的推广,假设去掉全然二叉树的条件呢?由于这个条件不是关键,因此不会影响整体的思路.做法依旧是每次找到一层的起点,然后一层一层的走. 假设是全然二叉树的话,每层的起点就是上一层起点的左孩子,兄弟之 ...
- Ubuntu 编译安装 OpenCV 3.1
目标系统:Ubuntu 16.04-64bit OpenCV 版本:opencv-3.1.0 安装步骤 安装 cmake.sudo apt-get isntall cmake cmake-qt-gui ...
- SignalR简单Demo
我们实现一个简单的消息通知的Demo 在NuGet中添加SignalR引用 install-package Microsoft.AspNet.SignalR 然后我们创建一个类来引用Hub类 name ...
- 【python】字符串、列表、元组间相互转化及函数len、max、min、sum、sorted、reversed、enumerate、zip用法示例
- HTML5 进阶系列:拖放 API 实现拖放排序(转载)
HTML5之拖放API实现拖放排序 前言 HTML5 中提供了直接拖放的 API,极大的方便我们实现拖放效果,不需要去写一大堆的 js,只需要通过监听元素的拖放事件就能实现各种拖放功能. 想要拖放某个 ...
- [HDU - 5170GTY's math problem 数的精度类
题目链接:HDU - 5170GTY's math problem 题目描述 Description GTY is a GodBull who will get an Au in NOI . To h ...
- web调用客户端程序
背景 最近做一个集成需求,我们是B/S架构的,对方是C/S架构的,对方直接扔过来一个EXE连OCX都没有,让我们调用,也就是说,我们需要通过js程序去调用他们的客户端程序并传入多个参数,当时内心是崩溃 ...
- geoserver发布地图服务WMS
wms服务发布: 1.打开geoserver管理首页(网址为http://localhost:8080/geoserver/web/),并使用安装时设置的帐户名和密码登录(这里是admin/geose ...
- 浅谈对ST表的一些理解
今天打了人生第一道ST表题(其实只是ST表跑得最快); ST表是一种用来解决RMQ问题的利器... 大体操作有两步: 第一部分nlogn预处理 第二部分O(1)询问 预处理就是运用倍增+区间动规 ST ...