assembly - AVR - GNU 链接器脚本 - 如何获取 .data 部分的加载地址
问题描述
我对 GNU 链接器脚本很陌生。avr-libc
想要为 AVR MCU创建一个裸机(不带)应用程序。在项目的早期阶段,我不需要初始化该.data
部分。但现在我需要它。
我当前的链接器脚本:
OUTPUT_FORMAT(elf32-avr)
OUTPUT_ARCH(avr51)
ENTRY(_start)
MEMORY {
FLASH_APP (rx) : ORIGIN = 0x00000000, LENGTH = 120K
FLASH_BOOT (rx) : ORIGIN = 0x0001E000, LENGTH = 8K
SRAM (rw) : ORIGIN = 0x00800100, LENGTH = 16K
}
STACK_SIZE = 4K;
SECTIONS {
.text : {
_text_s = .;
KEEP(*(.isr_vector))
*(.text)
*(.text*)
_text_e = .;
} > FLASH_BOOT
.rodata : {
. = ALIGN(2);
_rodata_s = .;
*(.rodata)
*(.rodata*)
_rodata_e = .;
. = ALIGN(2);
} > FLASH_BOOT
.data : {
. = ALIGN(2);
_data_s = .;
*(.data)
*(.data*)
_data_e = .;
. = ALIGN(2);
} > SRAM AT > FLASH_BOOT
.bss (NOLOAD): {
. = ALIGN(2);
_bss_s = .;
*(.bss)
*(.bss*)
*(COMMON)
_bss_e = .;
} > SRAM
HEAP_SIZE = (ORIGIN(SRAM) + LENGTH(SRAM)) - _heap_s - STACK_SIZE;
.heap (NOLOAD): {
. = ALIGN(2);
_heap_s = .;
. = . + HEAP_SIZE;
_heap_e = .;
} > SRAM
.stack (NOLOAD): {
. = ALIGN(2);
_stack_s = .;
. = . + STACK_SIZE;
_stack_e = .;
} > SRAM
}
对于该.bss
部分,我在链接描述文件中使用符号,我在汇编中使用它来将该.bss
部分归零。我编写了这些函数来获取该.bss
部分的开始和结束:
/* Get .bss start */
FUNCTION(asm_self_get_bss_s)
ldi r24, lo8(_bss_s)
ldi r25, hi8(_bss_s)
ret
/* Get .bss end */
FUNCTION(asm_self_get_bss_e)
ldi r24, lo8(_bss_e)
ldi r25, hi8(_bss_e)
ret
如何获取.data
链接描述文件中该部分的加载地址 (FLASH) 以从 SRAM 中的 FLASH 复制(初始化)数据?符号_data_s
和_data_e
在我的链接器脚本中返回 SRAM 地址。但是我怎样才能从 FLASH 中得到地址呢?GNU-ld 是否有特殊功能?
解决方案
我找到了解决方案。
LOADADDR()
是从链接描述文件中的部分获取加载地址的正确函数.data
。
LOADADDR(section)
返回指定节的绝对加载地址。这通常与 ADDR 相同,但如果在节定义中使用 AT 关键字,则可能会有所不同(请参阅可选节属性一节)。
以下内容现在适用于我改进的链接器脚本:
.data : {
. = ALIGN(2);
_data_s_load = LOADADDR(.data);
_data_s = .;
*(.data)
*(.data*)
_data_e = .;
. = ALIGN(2);
} > SRAM AT > FLASH_BOOT
以及具体的组装功能:
/* Get .data start */
FUNCTION(asm_self_get_data_s)
ldi r24, lo8(_data_s)
ldi r25, hi8(_data_s)
ret
/* Get .data end */
FUNCTION(asm_self_get_data_e)
ldi r24, lo8(_data_e)
ldi r25, hi8(_data_e)
ret
/* Get .data start (load address) */
FUNCTION(asm_self_get_data_s_load)
ldi r22, lo8(_data_s_load)
ldi r23, hi8(_data_s_load)
ldi r24, hh8(_data_s_load)
eor r25, r25
ret
我现在可以使用指令将数据从 FLASH 复制(初始化)到 SRAM elpm
。
推荐阅读
- c++ - 缺少数组元素问题
- android - 在 HERE Lite 中等效于 HERE Starter PositioningManager
- java - 我正在尝试在 Java 中将与投注相关的组件添加到我的游戏中,但程序在要求投注金额后停止工作
- c# - 不允许访问预制对象上的 Renderer.material。改用 Renderer.sharedMaterial
- css - 使用 calc() 设置动态宽度不起作用
- python - 在 groupby pandas 函数之后导出 .csv
- visual-studio-code - NXunit 测试资源管理器未在 VS Code 上显示测试(测试资源管理器 UI)
- firebase - 有人可以帮我处理这段代码吗?Google 登录 Firebase (Flutter)
- excel - 如何清除范围内单元格 = + 的内容?
- python - 沿线旋转矩形