硬汉嵌入式论坛

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

[MDK] keil的.sct链接文件理解问题

[复制链接]

13

主题

36

回帖

75

积分

初级会员

积分
75
发表于 2024-9-24 15:45:17 | 显示全部楼层 |阅读模式
以前用的外部sdram作为内存扩展,现在要使用外部flash作为rom拓展。
ps:以前是用的文件系统来驱动flash的,现在用的内存映射。
所以我需要重新更改sct文件了。感觉我都已经改sct文件这么多次了,这次好好捋一捋是怎么个事。
这次我的更改如下:


[C] 纯文本查看 复制代码
; *************************************************************

; *** Scatter-Loading Description File generated by uVision ***

; *************************************************************



LR_IROM1 0x08000000 0x00080000  {    ; load region size_region

  ER_IROM1 0x08000000 0x00080000  {  ; load address = execution address

   *.o (RESET, +First)

   *(InRoot$$Sections)

   .ANY (+RO)

   .ANY (+XO)

  }



  RW_IRAM1 0x20000000 0x00020000  {  ; RW data

   .ANY (+RW +ZI)

  }

}



EXT_FLASH 0x90000000 0x1000000{

  EXT_ROM 0x90000000 0x1000000{

   *(.ROM_EXT)

  }

}



看注释里写的有加载region和执行region,以前学过一些链接过程,还有输出section和输入section。我自己思考了半天,理论和实践没对上,特来请教大佬们。我的想法如下:
1.加载region是代码存放的内存地址,执行region是代码运行时的内存地址。如果二者的地址不同,一般是程序自身启动之后立刻将部分代码(通常是数据段)从加载region放置到执行region。主要的目的是程序的数据段变量段是要求读写    的,而在单片机系统加载区域往往是flash,是不可写的,所有需要把数据段转移到ram来实现程序的正常运行。我的sct中LR_IROM1 和EXT_FLASH 是加载region,ER_IROM1 ,RW_IRAM1 ,EXT_ROM 是执行区域。

2.在.c文件中为数据指定section的宏__attribute__((section(".ROM_EXT"))) 是指定了数据的输入section为.ROM_EXT,而在sct文件中,*(.ROM_EXT)很明显是输出section,这个对应关系似乎并没有显示的表现出来。

综上,那么我理解的对不对呢?输入section转为输出section是缺省配置吗?


回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117530
QQ
发表于 2024-9-24 18:19:04 | 显示全部楼层
本来输出段就是在link过程中由输入段组合而成的段

__attribute__((section(".ROM_EXT"))) 是程序指定的输入section,看map文件比较明显,然后最终由分散加载的执行域和加载域设置存储位置和加载位置,最终的输出section。
回复

使用道具 举报

1

主题

63

回帖

66

积分

初级会员

积分
66
发表于 2024-9-25 09:05:23 | 显示全部楼层
说一下我的理解:
1.
加载region是代码存放的内存地址,执行region是代码运行时的内存地址。

       这个是对的!
2.
如果二者的地址不同,一般是程序自身启动之后立刻将部分代码(通常是数据段)从加载region放置到执行region。

        这一点不完全对,对于 Keil(ARMCC 编译套件)来说,这个搬运的过程封装在了它的标准库中(在 __main 中);对于 IAR 来说也是封装在了它的标准库中(在 ?main 中);对于 GCC 来说,复制过程则位于 启动.s 文件中,这个完全是由用户自己来实现!

3.
主要的目的是程序的数据段变量段是要求读写    的,而在单片机系统加载区域往往是flash,是不可写的,所有需要把数据段转移到ram来实现程序的正常运行。我的sct中LR_IROM1 和EXT_FLASH 是加载region,ER_IROM1 ,RW_IRAM1 ,EXT_ROM 是执行区域

       正确
4.
在.c文件中为数据指定section的宏__attribute__((section(".ROM_EXT"))) 是指定了数据的输入section为.ROM_EXT,而在sct文件中,*(.ROM_EXT)很明显是输出section,这个对应关系似乎并没有显示的表现出来

      1. 输入节、输出节、代码段等只是为了人好理解在不同视图下的名称而已。例如 你这里的 .ROM_EXT 在链接视图中,它就是一个输入节,在执行视图中他就是一个代码段 或 数据段,只是链接器会把相同属性的输入节进行组合为代码段。连接文件处于连接视图的范畴,所以,你说 .ROM_EXT  是输入节 可以,输出节也可以,给你个图自己看把
fede7ca485845ea888531662acbac7c7.png

回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117530
QQ
发表于 2024-9-25 09:46:46 | 显示全部楼层
zcsexp 发表于 2024-9-25 09:05
说一下我的理解:
1.
       这个是对的!



非常给力的回复
回复

使用道具 举报

13

主题

36

回帖

75

积分

初级会员

积分
75
 楼主| 发表于 2024-9-25 10:22:42 | 显示全部楼层
大佬们和我理解的差不多,就是输出节还是有点迷惑。因为我以前搞adi的链接文件的时候发现它的很明显是有顺序的,编译之后每个文件会产生多个属于自己的输入节。链接的时候是先把输入节转为输出节,再给其指定内存地址。输入节转为输出节最大的最用感觉就是把所有.o文件的.text等组成一个输出节.text, .bss .data 同理。同类归并可以把程序的结构顺序排出来,可执行文件的机构更清晰。不知道理解的对不对,而且以此类推,应该所有的程序编译链接过程和这个是类似的吧?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-8-12 18:48 , Processed in 0.040619 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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