zoukankan      html  css  js  c++  java
  • 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系统初始化的时候再重新设置堆空间

  • 相关阅读:
    golang删除数组某个元素
    golang用通道实现信号量,控制并发个数
    什么是ScaleIO中的forwards rebuild和backwards rebuild?
    SQL Server中的database checkpoint
    如何将thick provision lazy zeroed的VMDK文件转换为thick provision eager zeroed?
    LoadTestAgentResultsLateException in VS2010
    SQL Server Instance无法启动了, 因为TempDB所在的分区没有了, 怎么办?
    VMware vCenter中, 如何辩认虚机上Raw Device Mapping过了的一块物理磁盘?
    SQL Server AlwaysOn Setup Step-By-Step Guide
    TPC-E在populate测试Database时需要注意的一些事项
  • 原文地址:https://www.cnblogs.com/nnhy/p/cortex_m3_boot.html
Copyright © 2011-2022 走看看