S-Record 文件中的地址来自哪里?
Where do addresses in S-Record files come from?
我正在为 ARM Cortex-M 微控制器开发一个独立的应用程序,在研究 S-Record 文件的结构时,我发现我对地址在 S-Record 格式中的表示方式有一些误解.
我在源代码中定义了一个变量,如下所示:
uint32_t g_ip_address = IP_ADDRESS(10, 1, 0, 56); // in LE: 0x3800010A
当我 运行 objdump 时,我看到变量最终出现在地址 0x1ffe01c4 的 .data 部分中:
$ arm-none-eabi-objdump -t application.elf | grep g_ip_address
1ffe01c4 g O .data 00000004 g_ip_address
这是有道理的,因为我的链接描述文件的内存部分看起来像这样,并且 .data 将进入 RAM:
MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x0200000 /* 2M */
RAM (rwx) : ORIGIN = 0x1FFE0000, LENGTH = 0x00A0000 /* 640K */
}
但是,当我检查 srec 文件时,我发现记录的地址不是 0x1FFE0000。它是 0x0005F570,似乎将其放在 FLASH 部分(为清楚起见添加了空格)。
S315 0005F570 00000000 3800010A 000010180000000014
在不同的记录条目中是否存在编码的隐式偏移量? objcopy 是如何得到这个新地址的?如果这个值以某种方式被编码到一个函数中(也许是变量的一些预主要初始化)?
最终,我的目标是能够解析 srec 文件并修补 IP 地址值以创建新的 srec 文件。做这样的事情的惯用方法是否只是为了创建一个结构来硬编码一些可以在文件中检测到的前导幻数序列?
flash.s
.cpu cortex-m0
.thumb
.word 0x00002000
.word reset
.thumb_func
reset:
b reset
.data
.word 0x11223344
.bss
.word 0x00000000
.word 0x00000000
flash.ld
MEMORY
{
rom : ORIGIN = 0x08000000, LENGTH = 0x1000
ram : ORIGIN = 0x20000000, LENGTH = 0x1000
}
SECTIONS
{
.text : { *(.text*) } > rom
.bss : { *(.bss*) } > ram AT > rom
.data : { *(.data*) } > ram AT > rom
}
建造它
arm-none-eabi-as --warn --fatal-warnings -mcpu=cortex-m0 flash.s -o flash.o
arm-none-eabi-ld -nostdlib -nostartfiles -T flash.ld flash.o -o so.elf
arm-none-eabi-objdump -D so.elf > so.list
arm-none-eabi-objcopy --srec-forceS3 so.elf -O srec so.srec
arm-none-eabi-objcopy -O binary so.elf so.bin
猫so.list
08000000 <reset-0x8>:
8000000: 00002000 andeq r2, r0, r0
8000004: 08000009 stmdaeq r0, {r0, r3}
08000008 <reset>:
8000008: e7fe b.n 8000008 <reset>
Disassembly of section .bss:
20000000 <.bss>:
...
Disassembly of section .data:
20000008 <.data>:
20000008: 11223344 ; <UNDEFINED> instruction: 0x11223344
猫so.srec
S00A0000736F2E7372656338
S30F080000000020000009000008FEE7D2
S3090800000A443322113A
S70508000000F2
arm-none-eabi-readelf -l so.elf
Elf file type is EXEC (Executable file)
Entry point 0x8000000
There are 3 program headers, starting at offset 52
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000094 0x08000000 0x08000000 0x0000a 0x0000a R E 0x2
LOAD 0x000000 0x20000000 0x0800000a 0x00000 0x00008 RW 0x1
LOAD 0x00009e 0x20000008 0x0800000a 0x00004 0x00004 RW 0x1
Section to Segment mapping:
Segment Sections...
00 .text
01 .bss
02 .data
hexdump -C so.bin
00000000 00 20 00 00 09 00 00 08 fe e7 44 33 22 11 |. ........D3".|
0000000e
bss 通常不会按原样公开,您可以使链接描述文件复杂化以添加开始点和结束点,这样您就可以将 bootstrap 中的范围归零。对于 .data,您可以清楚地看到标准 binutils 工具发生了什么。
您没有提供足够的代码(和链接描述文件),也没有提供演示问题的最小示例,所以这已经差不多了。
我正在为 ARM Cortex-M 微控制器开发一个独立的应用程序,在研究 S-Record 文件的结构时,我发现我对地址在 S-Record 格式中的表示方式有一些误解.
我在源代码中定义了一个变量,如下所示:
uint32_t g_ip_address = IP_ADDRESS(10, 1, 0, 56); // in LE: 0x3800010A
当我 运行 objdump 时,我看到变量最终出现在地址 0x1ffe01c4 的 .data 部分中:
$ arm-none-eabi-objdump -t application.elf | grep g_ip_address
1ffe01c4 g O .data 00000004 g_ip_address
这是有道理的,因为我的链接描述文件的内存部分看起来像这样,并且 .data 将进入 RAM:
MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x0200000 /* 2M */
RAM (rwx) : ORIGIN = 0x1FFE0000, LENGTH = 0x00A0000 /* 640K */
}
但是,当我检查 srec 文件时,我发现记录的地址不是 0x1FFE0000。它是 0x0005F570,似乎将其放在 FLASH 部分(为清楚起见添加了空格)。
S315 0005F570 00000000 3800010A 000010180000000014
在不同的记录条目中是否存在编码的隐式偏移量? objcopy 是如何得到这个新地址的?如果这个值以某种方式被编码到一个函数中(也许是变量的一些预主要初始化)?
最终,我的目标是能够解析 srec 文件并修补 IP 地址值以创建新的 srec 文件。做这样的事情的惯用方法是否只是为了创建一个结构来硬编码一些可以在文件中检测到的前导幻数序列?
flash.s
.cpu cortex-m0
.thumb
.word 0x00002000
.word reset
.thumb_func
reset:
b reset
.data
.word 0x11223344
.bss
.word 0x00000000
.word 0x00000000
flash.ld
MEMORY
{
rom : ORIGIN = 0x08000000, LENGTH = 0x1000
ram : ORIGIN = 0x20000000, LENGTH = 0x1000
}
SECTIONS
{
.text : { *(.text*) } > rom
.bss : { *(.bss*) } > ram AT > rom
.data : { *(.data*) } > ram AT > rom
}
建造它
arm-none-eabi-as --warn --fatal-warnings -mcpu=cortex-m0 flash.s -o flash.o
arm-none-eabi-ld -nostdlib -nostartfiles -T flash.ld flash.o -o so.elf
arm-none-eabi-objdump -D so.elf > so.list
arm-none-eabi-objcopy --srec-forceS3 so.elf -O srec so.srec
arm-none-eabi-objcopy -O binary so.elf so.bin
猫so.list
08000000 <reset-0x8>:
8000000: 00002000 andeq r2, r0, r0
8000004: 08000009 stmdaeq r0, {r0, r3}
08000008 <reset>:
8000008: e7fe b.n 8000008 <reset>
Disassembly of section .bss:
20000000 <.bss>:
...
Disassembly of section .data:
20000008 <.data>:
20000008: 11223344 ; <UNDEFINED> instruction: 0x11223344
猫so.srec
S00A0000736F2E7372656338
S30F080000000020000009000008FEE7D2
S3090800000A443322113A
S70508000000F2
arm-none-eabi-readelf -l so.elf
Elf file type is EXEC (Executable file)
Entry point 0x8000000
There are 3 program headers, starting at offset 52
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000094 0x08000000 0x08000000 0x0000a 0x0000a R E 0x2
LOAD 0x000000 0x20000000 0x0800000a 0x00000 0x00008 RW 0x1
LOAD 0x00009e 0x20000008 0x0800000a 0x00004 0x00004 RW 0x1
Section to Segment mapping:
Segment Sections...
00 .text
01 .bss
02 .data
hexdump -C so.bin
00000000 00 20 00 00 09 00 00 08 fe e7 44 33 22 11 |. ........D3".|
0000000e
bss 通常不会按原样公开,您可以使链接描述文件复杂化以添加开始点和结束点,这样您就可以将 bootstrap 中的范围归零。对于 .data,您可以清楚地看到标准 binutils 工具发生了什么。
您没有提供足够的代码(和链接描述文件),也没有提供演示问题的最小示例,所以这已经差不多了。