Cortex-M3启动深度解析

Cortex-Mx启动,备忘,以免将来忘记。 中断向量表不用说,从重置中断开始吧

LDR     R0, =SystemInit
BLX     R0
LDR     R0, =__main
BX      R0

这里一共就执行了两个函数,SystemInit和__main。

我们一般在SystemInit里面配置系统时钟,这里跳过。 __main是我们今天的重点。

                 __main:
0x080000C0 4804      LDR      r0,[pc,#16]  ; @0x080000D4
0x080000C2 4685      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 4800      LDR      r0,[pc,#0]  ; @0x080000D0
0x080000CE 4700      BX       r0        #进入C++的main函数

分散加载这里将会初始化我们的全局静态变量

.text:00000000 __scatterload_rt2
.text:00000000                 LDR     R4, =Region$Table$Base
.text:00000002                 MOVS    R5, #1
.text:00000004                 LDR     R6, =Region$Table$Limit
.text:00000006                 B       loc_14
.text:00000008 ; ---------------------------------------------------------------------------
.text:00000008
.text:00000008 loc_8                                   ; CODE XREF: __scatterload_rt2+16j
.text:00000008                 LDR     R3, [R4,#0xC]
.text:0000000A                 LDMIA   R4!, {R0-R2}
.text:0000000C                 ORRS    R3, R5
.text:0000000E                 SUBS    R4, #0xC
.text:00000010                 BLX     R3
.text:00000012                 ADDS    R4, #0x10
.text:00000014
.text:00000014 loc_14                                  ; CODE XREF: __scatterload_rt2+6j
.text:00000014                 CMP     R4, R6
.text:00000016                 BCC     loc_8
.text:00000018                 BL      __main_after_scatterload

可能汇编看起来不是很直观,我们配合看F5得到的反编译C代码

void _scatterload_rt2()
{
  _DWORD *i; // r4@1

  for ( i = &Region__Table__Base; (_UNKNOWN *)i < &Region__Table__Limit; i += 4 )
    ((void (__fastcall *)(_DWORD, _DWORD, _DWORD))(i[3] | 1))(*i, i[1], i[2]);
  _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系统初始化的时候再重新设置堆空间

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏爱撒谎的男孩

地址管理之省市区三级联动菜单

1.1K30
来自专栏跟着阿笨一起玩NET

以读取博客园随笔备份为例 将xml 序列化成json,再序列化成对象

资源下载:http://files.cnblogs.com/codealone/ConsoleApplication2.zip

11410
来自专栏芋道源码1024

【Netty 专栏】深入浅出 Netty write

上一章节中,分析了Netty如何处理read事件,本节分析Netty如何把数据写会客户端。

14100
来自专栏编码小白

tomcat请求处理分析(六)servlet的处理过程

1.1.1.1  servlet的解析过程 servlet的解析分为两步实现,第一个是匹配到对应的Wrapper,第二个是加载对应的servlet并进行数据,这...

75470
来自专栏Spark学习技巧

hadoop系列之MR经典案例分享二

4、MapReduce的join(hive已经实现) http://database.51cto.com/art/201410/454277.htm ? 这三种...

371100
来自专栏Ryan Miao

使用dropwizard(6)-国际化-easy-i18n

前言 Dropwizard官方文档并没有提供国际化的模块,所以只能自己加。Spring的MessageResource用的很顺手,所以copy过来。 Easy...

399120
来自专栏Java Web

JavaFX-TableView详解

前言 最近在着手一个学生管理系统的编写,涉及到TableView的使用,这前前后后的也有了些经验和想法想要记录和分享一下(事实上我正在想要用html网页代替界面...

41060
来自专栏分布式系统进阶

Librdkafka的操作处理队列

32220
来自专栏Pythonista

Django之ORM数据库

            django默认使用sqlite的数据库,默认自带sqlite的数据库驱动 , 引擎名称:django.db.backends.sqli...

15710
来自专栏码农分享

4.1、苏宁百万级商品爬取 代码讲解 索引建立

Lucene是一款高性能的、可扩展的信息检索(IR)工具库。信息检索是指文档搜索、文档内信息搜索或者文档相关的元数据搜索等操作。

16230

扫码关注云+社区

领取腾讯云代金券