65、【OS】【Nuttx】【启动】链接脚本:地址布局(上)

【声明】本博客所有内容均为个人业余时间创作,所述技术案例均来自公开开源项目(如Github,Apache基金会),不涉及任何企业机密或未公开技术,如有侵权请联系删除

背景

接之前 blog
【OS】【Nuttx】【启动】向量表:指定内存段
分析了链接脚本里面关于 section 的一些内容,下面看下 section 的地址布局

地址布局

上篇 blog 提到 _stext = ABSOLUTE(.);,下面继续来分析这个修饰词 ABSOLUTE,ABSOLUTE 的含义是将当前地址(.)的值定义为一个绝对地址,实际上,在下面这种场景下,加不加 ABSOLUTE 修饰词,效果是一样的,原因就在于 62 行的语句 > flash
65、【OS】【Nuttx】【启动】链接脚本:地址布局(上)_第1张图片
flash 的定义如下
65、【OS】【Nuttx】【启动】链接脚本:地址布局(上)_第2张图片
首先是 MEMORY { … }

  • 链接脚本的语法,表示这里是系统内存的描述。
  • 链接器会根据 MEMORY 中定义的内存区域,将程序的不同部分(比如代码、数据等)分配到合适位置

其次是内存区域的定义,来看 flash 定义:flash (rx) : ORIGIN = 0x08000000, LENGTH = 2048K

  • flash:是内存区域的名字,可以随意命名,比如 flash_a,flash_b
  • (rx) 属性信息:r 表示 read(可读),x 表示 execute(可执行),说明定义的这段内存可以读取并执行指令
  • ORIGIN = 0x08000000 起始地址,也就是 stm32f429 芯片中 flash 的起始地址
  • LENGTH = 2048K 表示容量大小为 2048KB,也就是 2MB,当然可以不一定是 2MB,可以比 2MB 小,但不能比 2MB 大(超过 flash 大小的目标文件会导致烧录错误)

flash 区域可以存放程序代码(比如 .text 段),可以存放常量数据(比如 .rodata 段),但不能频繁写入,而且 flash 写之前要擦除,寿命有限

再看下 sram 定义:sram (rwx) : ORIGIN = 0x20000000, LENGTH = 112K

  • sram:另一块内存区域名称,根据 stm32f429 用户手册的描述,其实这块区域命名叫做 sram1 更合适
  • (rwx) 属性信息:r 可读,w 可写,x 可执行
  • ORIGIN = 0x20000000 起始地址,是 stm32f429 芯片中 sram1 的开始位置
  • LENGTH = 112K :容量大小为 112KB,同样可以比 112KB 小,但不能比 112KB 大,不然就内存越界了(越界到 sram2)

stm32f429 的内存区域分布如下,可以看到链接脚本只定义了 flash 和 sram1 区域

65、【OS】【Nuttx】【启动】链接脚本:地址布局(上)_第3张图片

下面回到 ABSOLUTE 这个修饰词,在 .text : { … } > flash 这种上下文中,即使不加 ABSOLUTE(),(.) 的值也已经是相对于 flash 地址空间的偏移量,也就是最终内存布局中的绝对地址,所以 _stext = .; 和 _stext = ABSOLUTE(.); 在这种场景的结果是一样的

在 bash 中输入如下命令

arm-none-eabi-nm ../build/nuttx | grep _stext

可以观察到,不管是 _stext = ABSOLUTE(.);,还是 _stext = .;,最终的 elf 文件中,_stext 的值都是固定的,为 0x8000000

在这里插入图片描述

先分析到这里,下篇继续

你可能感兴趣的:(【OS】【Nuttx】,OS,Nuttx,启动)