硬汉嵌入式论坛

 找回密码
 立即注册
查看: 348|回复: 14
收起左侧

[BOOT/IAP] 如何将bootloader代码从flash 搬到RAM运行

[复制链接]

0

主题

10

回帖

10

积分

新手上路

积分
10
发表于 2025-5-22 16:23:23 | 显示全部楼层 |阅读模式
本帖最后由 bourne.nee 于 2025-5-22 16:35 编辑

想要Bootloader能够自更新,我希望Bootloader启动之后,自身是在ram里面运行的,如果需要boot更新,把新boot下载到其他flash,校验通过后,再拷贝到起始位置的flash位置即可。

关于bootloader在ram里面运行,想到了两个办法:
1.  2级boot方案:StartBoot 负责将 UserBoot 拷贝Ram里面,然后跳转运行UserBoot 负责升级, 这个方案比较好实现
2.  单boot方案:程序存在flash里面,即加载域是flash,执行域是ram,  boot 自身将自己从flash拷贝到ram后然后运行
回复

使用道具 举报

0

主题

7

回帖

7

积分

新手上路

积分
7
发表于 2025-5-22 17:47:32 | 显示全部楼层
我们公司采用的方案2
回复

使用道具 举报

0

主题

10

回帖

10

积分

新手上路

积分
10
 楼主| 发表于 2025-5-22 17:52:23 | 显示全部楼层
有大佬能看看方案2如何实现么?
回复

使用道具 举报

0

主题

30

回帖

30

积分

新手上路

积分
30
发表于 2025-5-22 23:49:36 | 显示全部楼层
bourne.nee 发表于 2025-5-22 17:52
有大佬能看看方案2如何实现么?

gcc 的话应该是加 -PIC 这样的参数,固件就可以在任意地址运行了
然后拷贝自身的时候,把ram里面的固件开头的中断向量表的值都加上相应偏移就好了
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
116230
QQ
发表于 2025-5-23 08:01:34 | 显示全部楼层
如果你的是h7系列还有更简单的方案,用app更新boot,为了防止更新失败或者掉电,设置上电启动位置直接到app地址
回复

使用道具 举报

0

主题

21

回帖

21

积分

新手上路

积分
21
发表于 2025-5-23 08:39:14 | 显示全部楼层
eric2013 发表于 2025-5-23 08:01
如果你的是h7系列还有更简单的方案,用app更新boot,为了防止更新失败或者掉电,设置上电启动位置直接到app ...

也就是说,中断向量表位置更改了,在掉电以后,还可以保存?
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
116230
QQ
发表于 2025-5-24 08:02:54 | 显示全部楼层
了无 发表于 2025-5-23 08:39
也就是说,中断向量表位置更改了,在掉电以后,还可以保存?

h7 系列不像f1,f4系列,内部flash必须固定从0x08000000启动。
h7系列可以设置从其它地址启动
回复

使用道具 举报

0

主题

10

回帖

10

积分

新手上路

积分
10
 楼主| 发表于 2025-5-24 15:16:58 | 显示全部楼层
lorde 发表于 2025-5-22 17:47
我们公司采用的方案2

我参考了 21.com 里面的这个方案 https://bbs.21ic.com/icview-1249662-1-1.html,复现没有成功;大佬方便指导一下么?
回复

使用道具 举报

0

主题

10

回帖

10

积分

新手上路

积分
10
 楼主| 发表于 2025-5-24 15:27:32 | 显示全部楼层
eric2013 发表于 2025-5-23 08:01
如果你的是h7系列还有更简单的方案,用app更新boot,为了防止更新失败或者掉电,设置上电启动位置直接到app ...

我用的是M4内核,我的想法是代码存在flash里面,片子启动后进复位函数,复位函数依据分散加载文件,将需要运行到代码全部拷贝到ram里面运行,
[C] 纯文本查看 复制代码
LR_IROM1 0x08000000 0x00100000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00100000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
  }
现在的连接脚本是这样写的,看map文件代码全部到加载域是falsh,运行域是ram,但是Reset_Handler 一直是异常的, [mw_shl_code=c,true]   180:                 LDR     R0, =SystemInit 
0x20010188 DF8F      SVC           0x8F
   181:                 BLX     R0 
0x2001018A 3D75      SUBS          r5,r5,#0x75
   182:                 LDR     R0, =__main 
0x2001018C 9B2C      LDR           r3,[sp,#0xB0]
   183:                 BX      R0 
   184:                 ENDP 

  ER_IROM2 0x20010000 0x00010000  {  ; load address = execution address
   *.o (RESET_Ram, +First)
   .ANY (+RO)
  }
  RW_IRAM1 0x20000000 0x00010000  {  ; RW data

           .ANY (+RW, +ZI)
  }
}
[/mw_shl_code]
回复

使用道具 举报

0

主题

10

回帖

10

积分

新手上路

积分
10
 楼主| 发表于 2025-5-24 15:34:15 | 显示全部楼层
dukelec 发表于 2025-5-22 23:49
gcc 的话应该是加 -PIC 这样的参数,固件就可以在任意地址运行了
然后拷贝自身的时候,把ram里面的固件 ...

这个方案没研究过;-fPIC位置无关代码之前看NXP OTA 方案上面见过,他使得不带双BankFlash的mcu也支持双分区升级,同一个固件不用修改启动地址和连接地址,两个地址都可以运行。
回复

使用道具 举报

0

主题

10

回帖

10

积分

新手上路

积分
10
 楼主| 发表于 2025-5-24 20:27:20 | 显示全部楼层
更新一下进展:
回复

使用道具 举报

0

主题

10

回帖

10

积分

新手上路

积分
10
 楼主| 发表于 2025-5-24 21:28:42 | 显示全部楼层
更新一下进展: 基本实现如何将bootloader代码从flash 搬到RAM运行, 目前除了 Reset_Handler 以及  SystemInit 两个函数以外, 其他代码全部搬运到了ram里面运行

说一下思路:
1.Reset_Handler 负责将除Reset_Handler 以及  SystemInit 两个函数以外的所有代码搬运到ram;
2.之前遇到的问题是代码启动后直接去ram里面执行Reset_Handler 了,但是这会ram里面还是空的,__main 函数还没帮忙把代码拷贝到ram里面去;
3.现在就先将Reset_Handler 以及 SystemInit  的执行域仍定在flash,在flash里面运行,
[C] 纯文本查看 复制代码
                AREA    RESET, CODE, READONLY  ; 复用原始启动文件的段名
                THUMB

Reset_Handler   PROC
                EXPORT  Reset_Handler          ; 必须显式 EXPORT(无 [WEAK])
                IMPORT  SystemInit
                IMPORT  __main

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


4. Reset_Handler 单独在.s 文件里面实现, 重定向的ram 中断向量表也在新的.s 文件里面实现
[C] 纯文本查看 复制代码
                PRESERVE8
                THUMB

;               /* reset Vector Mapped to at Address 0 */
                AREA    RESET_Ram, DATA, READONLY
                EXPORT  __Vectors_Ram
                EXPORT  __Vectors_End_Ram
                EXPORT  __Vectors_Size_Ram

__Vectors_Ram   DCD     0                      ; Top of Stack
                DCD     0                     ; Reset Handler
                DCD     NMI_Handler                       ; NMI Handler
                DCD     HardFault_Handler                 ; Hard Fault Handler
                DCD     MemManage_Handler                 ; MPU Fault Handler
                DCD     BusFault_Handler                  ; Bus Fault Handler
                DCD     UsageFault_Handler                ; Usage Fault Handler
...中间省略 对比复制原始__Vectors...
                DCD     USBHS_EP1_In_IRQHandler           ; 91:USBHS Endpoint 1 in
                DCD     USBHS_WKUP_IRQHandler             ; 92:USBHS Wakeup through EXTI Line
                DCD     USBHS_IRQHandler                  ; 93:USBHS
                DCD     DCI_IRQHandler                    ; 94:DCI
                DCD     0                                 ; 95:Reserved
                DCD     TRNG_IRQHandler                   ; 96:TRNG
                DCD     FPU_IRQHandler                    ; 97:FPU

__Vectors_End_Ram

__Vectors_Size_Ram   EQU     __Vectors_End_Ram - __Vectors_Ram

                 AREA    |.text|, CODE, READONLY

                IMPORT  NMI_Handler                       
                IMPORT  HardFault_Handler                 
                IMPORT  MemManage_Handler                 
                IMPORT  BusFault_Handler                  
                IMPORT  UsageFault_Handler                
                IMPORT  SVC_Handler                       
                IMPORT  DebugMon_Handler                  
                IMPORT  PendSV_Handler                    
                IMPORT  SysTick_Handler                   

;               /* external interrupts handler */
                IMPORT  WWDGT_IRQHandler                  [WEAK]
                IMPORT  LVD_IRQHandler                    [WEAK]                  
                IMPORT  TAMPER_STAMP_IRQHandler           [WEAK]   
...中间省略 对比复制原始__Vectors...
                IMPORT  USBHS_EP1_In_IRQHandler           [WEAK]    
                IMPORT  USBHS_WKUP_IRQHandler             [WEAK]             
                IMPORT  USBHS_IRQHandler                  [WEAK]            
                IMPORT  DCI_IRQHandler                    [WEAK]                      
                IMPORT  TRNG_IRQHandler                   [WEAK]          
                IMPORT  FPU_IRQHandler                    [WEAK]          
END



现在遇到了另外一个问题, 没法打断点了, 有哪位大佬帮忙看看

回复

使用道具 举报

0

主题

10

回帖

10

积分

新手上路

积分
10
 楼主| 发表于 2025-5-24 21:29:51 | 显示全部楼层
连接脚本
[C] 纯文本查看 复制代码
LR_IROM1 0x08000000 0x00100000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00100000  {  ; load address = execution address
   startup_gd32f405.o (RESET, +First)
   *(InRoot$$Sections)
   startup_Reset_Handler.o (+RO, +RW, +ZI)
   system_gd32f4xx.o (+RO, +RW, +ZI)
   .ANY (+XO)
  }
  
  ER_IROM2 0x20000000 0x00010000  {  ; load address = execution address
   *.o (RESET_Ram, +First)
   .ANY (+RO)
  }
  
  RW_IRAM1 0x20010000 0x00010000  {  ; RW data
	.ANY (+RW, +ZI)
  }
}
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
116230
QQ
发表于 2025-5-25 09:20:34 | 显示全部楼层
bourne.nee 发表于 2025-5-24 21:29
连接脚本
[mw_shl_code=c,true]LR_IROM1 0x08000000 0x00100000  {    ; load region size_region
  ER_ ...

这个程序非常适合,我这里是复制app,你把这个app也做成boot功能即可

制作了一个通过BOOT复制APP程序到AXI SRAM运行的案例,适合H750,H7B0玩
https://www.armbbs.cn/forum.php? ... 2748&fromuid=58
(出处: 硬汉嵌入式论坛)
回复

使用道具 举报

0

主题

10

回帖

10

积分

新手上路

积分
10
 楼主| 发表于 2025-5-25 09:34:29 | 显示全部楼层
eric2013 发表于 2025-5-25 09:20
这个程序非常适合,我这里是复制app,你把这个app也做成boot功能即可

制作了一个通过BOOT复制APP程序 ...

是的,方案1 是打算用您这个方案,一级boot把二级boot加载到sram里面运行;方案2 我这边看着基本也没啥问题: 我看map文件里面基本除去那两个函数,执行域已经是sram里面了,指定执行域后,__main 帮忙把代码从flash搬运到sram太香了;那两个在flash运行的函数,也就是开始运行一下,后续不会运行,应该也不影响后续新旧boot的flash搬运操作了,
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-6-11 03:08 , Processed in 0.462270 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表