stm32 data,bss段加载理解

发布于:2025-07-06 ⋅ 阅读:(16) ⋅ 点赞:(0)

         EXPORT __scatterload_rt2
ER_IROM1:0800311C                               __scatterload_rt2                       ; CODE XREF: _main_scatterload↑p
ER_IROM1:0800311C 06 4C                         LDR             R4, =Region$$Table$$Base
ER_IROM1:0800311E 07 4D                         LDR             R5, =Region$$Table$$Limit
ER_IROM1:08003120 06 E0                         B               loc_8003130
ER_IROM1:08003120
ER_IROM1:08003122                               ; ---------------------------------------------------------------------------
ER_IROM1:08003122
ER_IROM1:08003122                               loc_8003122                             ; CODE XREF: ER_IROM1:08003132↓j
ER_IROM1:08003122 E0 68                         LDR             R0, [R4,#0xC]
ER_IROM1:08003124 40 F0 01 03                   ORR.W           R3, R0, #1
ER_IROM1:08003128 94 E8 07 00                   LDM.W           R4, {R0-R2}
ER_IROM1:0800312C 98 47                         BLX             R3
ER_IROM1:0800312C
ER_IROM1:0800312E 10 34                         ADDS            R4, #0x10
ER_IROM1:0800312E
ER_IROM1:08003130
ER_IROM1:08003130                               loc_8003130                             ; CODE XREF: ER_IROM1:08003120↑j
ER_IROM1:08003130 AC 42                         CMP             R4, R5
ER_IROM1:08003132 F6 D3                         BCC             loc_8003122
ER_IROM1:08003132
ER_IROM1:08003134 FC F7 DE FF                   BL              _main_init
ER_IROM1:08003134
ER_IROM1:08003134                               ; ---------------------------------------------------------------------------
ER_IROM1:08003138 F8 3E 00 08                   off_8003138 DCD Region$$Table$$Base     ; DATA XREF: ER_IROM1:__scatterload_rt2↑r
ER_IROM1:0800313C 18 3F 00 08                   off_800313C DCD Region$$Table$$Limit    ; DATA XREF: ER_IROM1:0800311E↑r
ER_IROM1:08003140

 EXPORT _main_init
ER_IROM1:080000F4                               _main_init                              ; CODE XREF: ER_IROM1:08003134↓p
ER_IROM1:080000F4 00 48                         LDR             R0, =(main+1)           ; argc
ER_IROM1:080000F6 00 47                         BX              R0


extern uint32_t Region$$Table$$Base;
extern uint32_t Region$$Table$$Limit;
//&Region$$Table$$Base  compress data, bss
//&Region$$Table$$Limit  the end of data bss
//data: 0x10  [Region$$Table$$Limit = compress data start] [ram base addr 0x20000000] [data size] [decompression function]
//bss : 0x10  [LOAD ends,the code end = compress data end] [ram addr start of bss segment] [bss size] [bss clear function] 
 

ER_IROM1:0800315C                               ; =============== S U B R O U T I N E =======================================
ER_IROM1:0800315C
ER_IROM1:0800315C
ER_IROM1:0800315C                               ; int __fastcall _decompress1(char *in_buff, _BYTE *out_buff, int len)
ER_IROM1:0800315C                               EXPORT __decompress1
ER_IROM1:0800315C                               __decompress1
ER_IROM1:0800315C 70 B5                         PUSH            {R4-R6,LR}
ER_IROM1:0800315E 01 EB 02 04                   ADD.W           R4, R1, R2
ER_IROM1:0800315E
ER_IROM1:08003162
ER_IROM1:08003162                               loc_8003162                             ; CODE XREF: __decompress1+56↓j
ER_IROM1:08003162 10 F8 01 5B                   LDRB.W          R5, [R0],#1
ER_IROM1:08003166 15 F0 07 03                   ANDS.W          R3, R5, #7
ER_IROM1:0800316A 01 D1                         BNE             loc_8003170
ER_IROM1:0800316A
ER_IROM1:0800316C 10 F8 01 3B                   LDRB.W          R3, [R0],#1
ER_IROM1:0800316C
ER_IROM1:08003170
ER_IROM1:08003170                               loc_8003170                             ; CODE XREF: __decompress1+E↑j
ER_IROM1:08003170 2A 11                         ASRS            R2, R5, #4
ER_IROM1:08003172 06 D1                         BNE             loc_8003182
ER_IROM1:08003172
ER_IROM1:08003174 10 F8 01 2B                   LDRB.W          R2, [R0],#1
ER_IROM1:08003178 03 E0                         B               loc_8003182
ER_IROM1:08003178
ER_IROM1:0800317A                               ; ---------------------------------------------------------------------------
ER_IROM1:0800317A
ER_IROM1:0800317A                               loc_800317A                             ; CODE XREF: __decompress1+28↓j
ER_IROM1:0800317A 10 F8 01 6B                   LDRB.W          R6, [R0],#1
ER_IROM1:0800317E 01 F8 01 6B                   STRB.W          R6, [R1],#1
ER_IROM1:0800317E
ER_IROM1:08003182
ER_IROM1:08003182                               loc_8003182                             ; CODE XREF: __decompress1+16↑j
ER_IROM1:08003182                                                                       ; __decompress1+1C↑j
ER_IROM1:08003182 5B 1E                         SUBS            R3, R3, #1
ER_IROM1:08003184 F9 D1                         BNE             loc_800317A
ER_IROM1:08003184
ER_IROM1:08003186 2B 07                         LSLS            R3, R5, #0x1C
ER_IROM1:08003188 05 D4                         BMI             loc_8003196
ER_IROM1:08003188
ER_IROM1:0800318A 00 23                         MOVS            R3, #0
ER_IROM1:0800318A
ER_IROM1:0800318C
ER_IROM1:0800318C                               loc_800318C                             ; CODE XREF: __decompress1+38↓j
ER_IROM1:0800318C 52 1E                         SUBS            R2, R2, #1
ER_IROM1:0800318E 0F D4                         BMI             loc_80031B0
ER_IROM1:0800318E
ER_IROM1:08003190 01 F8 01 3B                   STRB.W          R3, [R1],#1
ER_IROM1:08003194 FA E7                         B               loc_800318C
ER_IROM1:08003194
ER_IROM1:08003196                               ; ---------------------------------------------------------------------------
ER_IROM1:08003196
ER_IROM1:08003196                               loc_8003196                             ; CODE XREF: __decompress1+2C↑j
ER_IROM1:08003196 10 F8 01 3B                   LDRB.W          R3, [R0],#1
ER_IROM1:0800319A 02 F1 02 02                   ADD.W           R2, R2, #2
ER_IROM1:0800319E A1 EB 03 03                   SUB.W           R3, R1, R3
ER_IROM1:080031A2 03 E0                         B               loc_80031AC
ER_IROM1:080031A2
ER_IROM1:080031A4                               ; ---------------------------------------------------------------------------
ER_IROM1:080031A4
ER_IROM1:080031A4                               loc_80031A4                             ; CODE XREF: __decompress1+52↓j
ER_IROM1:080031A4 13 F8 01 5B                   LDRB.W          R5, [R3],#1
ER_IROM1:080031A8 01 F8 01 5B                   STRB.W          R5, [R1],#1
ER_IROM1:080031A8
ER_IROM1:080031AC
ER_IROM1:080031AC                               loc_80031AC                             ; CODE XREF: __decompress1+46↑j
ER_IROM1:080031AC 52 1E                         SUBS            R2, R2, #1
ER_IROM1:080031AE F9 D5                         BPL             loc_80031A4
ER_IROM1:080031AE
ER_IROM1:080031B0
ER_IROM1:080031B0                               loc_80031B0                             ; CODE XREF: __decompress1+32↑j
ER_IROM1:080031B0 A1 42                         CMP             R1, R4
ER_IROM1:080031B2 D6 D3                         BCC             loc_8003162
ER_IROM1:080031B2
ER_IROM1:080031B4 00 20                         MOVS            R0, #0
ER_IROM1:080031B6 70 BD                         POP             {R4-R6,PC}
ER_IROM1:080031B6
ER_IROM1:080031B6                               ; End of function __decompress1
ER_IROM1:080031B6
ER_IROM1:080031B8


int _decompress1( unsigned char *in_buff, unsigned char  *out_buff, int len )  
{
    unsigned char  *end;
    int temp; 
    int ctrl; 
    int copy_len; 
    int ref_len; 
    int offset; 
    int cnt; 
    unsigned char *i;
    
    end = &out_buff[len];
    do {
        ctrl = *in_buff++;
        temp = ctrl;
        copy_len = ctrl & 7;
        if ((ctrl & 7) == 0) {
            copy_len = *in_buff++;
        }
        ref_len = temp >> 4;
        if( ref_len == 0x00 ) {
            ref_len = *in_buff++;
        }
        while (--copy_len){
            *out_buff++ = *in_buff++;
        }
        if ((temp & 8) != 0){
            offset = *in_buff++;
            cnt = ref_len + 2;
            for (i = &out_buff[-offset]; --cnt >= 0; ++i) {
                *out_buff++ = i[0];
            }
        }else {
            while (--ref_len >= 0){
                *out_buff++ = 0;
            }
        }
    } while (out_buff < end);
    return 0;
}
 

  EXPORT Region$$Table$$Base
ER_IROM1:08003EF8 18 3F 00 08                   Region$$Table$$Base DCD Region$$Table$$Limit
ER_IROM1:08003EF8                                                                       ; DATA XREF: ER_IROM1:__scatterload_rt2↑o
ER_IROM1:08003EF8                                                                       ; ER_IROM1:off_8003138↑o
ER_IROM1:08003EFC 00 00 00 20                   DCD SystemCoreClock
ER_IROM1:08003F00 3C 03 00 00                   DCD 0x33C
ER_IROM1:08003F04 5C 31 00 08                   dword_8003F04 DCD 0x800315C             ; DATA XREF: ER_IROM1:loc_8003122↑r
ER_IROM1:08003F08 D8 3F 00 08                   DCD 0x8003FD8
ER_IROM1:08003F0C 3C 03 00 20                   DCD rxBuffer
ER_IROM1:08003F10 5C 0F 00 00 14 32 00 08       DCD 0xF5C, 0x8003214
ER_IROM1:08003F10                               ; ER_IROM1 ends

早期:data段是直接拷贝的,没有压缩

现在:armcc.exe v5.06 data段是压缩存储的,启动时需要解压缩。

bss段还是老套路,直接清零。

其实对于这种修改,启动代码只需修改一个函数指针就行,整个程序架构都不会变。由data段拷贝函数改成data段解压函数。

这种玩法,类似uboot的启动初始化代码,遍历一个初始化函数指针表,逐个执行其中的初始化函数。

具体stm32这个表中,有2个函数指针,第一个指向解压缩data的函数,r0-r3是函数的参数,总共占用16字节

第二个指向bss清零的函数,构造也类似。

  Reset_Handler                      
                LDR             R0, =(SystemInit+1)
                    BLX             R0                      ; SystemInit

                     LDR             R0, =(_main_stk+1)
                      BX              R0

  ; void NMI_Handler()
ER_IROM1:08000108                               WEAK NMI_Handler
ER_IROM1:08000108                               NMI_Handler                             ; CODE XREF: NMI_Handler↓j
ER_IROM1:08000108                                                                       ; DATA XREF: ER_IROM1:08000008↑o
ER_IROM1:08000108 FE E7                         B               NMI_Handler
ER_IROM1:08000108

_main_stk:

LDR.W           SP, =0x20001298

 EXPORT _main_scatterload
ER_IROM1:080000F0                               _main_scatterload
ER_IROM1:080000F0 03 F0 14 F8                   BL              __scatterload_rt2
ER_IROM1:080000F0
ER_IROM1:080000F0                               ; End of function _main_scatterload
ER_IROM1:080000F0
ER_IROM1:080000F4
ER_IROM1:080000F4                               ; =============== S U B R O U T I N E =======================================
ER_IROM1:080000F4
ER_IROM1:080000F4
ER_IROM1:080000F4                               ; int __cdecl main_init(int argc, const char **argv, const char **envp)
ER_IROM1:080000F4                               EXPORT _main_init
ER_IROM1:080000F4                               _main_init                              ; CODE XREF: ER_IROM1:08003134↓p
ER_IROM1:080000F4 00 48                         LDR             R0, =(main+1)           ; argc
ER_IROM1:080000F6 00 47                         BX              R0
ER_IROM1:080000F6
ER_IROM1:080000F6                               ; ---------------------------------------------------------------------------
ER_IROM1:080000F8                               ; const int argc
ER_IROM1:080000F8 D7 04 00 08                   argc DCD main+1                         ; DATA XREF: _main_init↑r
ER_IROM1:080000F8                               ; End of function _main_init
ER_IROM1:080000F8
ER_IROM1:080000FC                               EXPORT __rt_final_exit
ER_IROM1:080000FC 98 12 00 20                   __rt_final_exit DCD 0x20001298          ; DATA XREF: _main_stk↑r
ER_IROM1:08000100

可以看到 从

BL              __scatterload_rt2

返回后,就会进入c语言的main函数。

__scatterload_rt2这个函数就是前面描述的 data段解压缩和bss段清零程序。


网站公告

今日签到

点亮在社区的每一天
去签到