将代码下载到闪存中的过程
我是嵌入式领域的新手。关于十六进制文件下载,我想到了一个疑问: 由于链接器和定位器的输出是一个二进制文件,具有 .text、.bss、.data 等各个部分,并且 .text 驻留在闪存中,.bss 进入 RAM,.data 进入 RAM ... 所以我的问题是,
- 当我使用 FLASH Loader 将程序刻录到闪存上时,如何将 .bss 和 .data 写入 RAM。
- 最终的二进制文件中是否有任何索引类型的东西可以区分 .text 和 .bss 段。
- 链接器/定位器中是否有任何实用程序可以将我们的简单二进制文件转换为十六进制格式。
- 如何从十六进制文件的内容中区分 .text 和 .bss?
提前致谢。请帮忙。
I am new to Embedded field. One doubt came up in my mind about hex file downloading:
As output of the linker and locator is a binary file having various sections as .text,.bss,.data etc. and .text resides in Flash, .bss goes to RAM, .data goes to RAM ...
so my question is that
- how .bss and .data are written to RAM as i am using FLASH Loader for burning my program onto flash.
- Is there any index kind of thing in the final binary which discriminates between .text and .bss segments.
- Is there any utility in the linker/locator which converts our simple binary into hex format.
- How can I discriminate between .text and .bss from the contents of hex file?
Thanks in advance. Please help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
代码、常量数据和初始化数据都写入FLASH。运行时,启动时初始化的数据被复制到bss。常量数据通常直接访问(使用“const”关键字声明它)。
我认为你所说的“二进制”是链接器输出的意思。这通常称为目标文件,与二进制图像不同。目标文件包括所有代码、数据、符号、调试信息和内存地址。对于 GCC 工具链,链接器输出通常是 .elf 文件。
您的链接器使用“链接脚本”或其他定义文件将各个段定位在适当的内存地址处。您的工具链应该有关于如何更改它的文档。
“objcopy”实用程序将读取链接器输出,并可以以各种格式写入输出文件,包括 Intel-hex。对于人类可读的输出,请参阅“objdump”。
通过内存地址。 GCC 使用“初始化数据”段来存储复制到 bss 的数据。它根据您的链接器脚本定位。
Intel 十六进制格式:http://en.wikipedia.org/wiki/Intel_HEX
GCC:http://gcc.gnu.org/onlinedocs/
Code, constant data and initialized data are all written to FLASH. At runtime, initialized data is copied to bss during startup. Constant data is usually accessed directly (you declare it with the "const" keyword).
I think you mean by "binary" the linker output. This is usually referred to as an object file and is different from a binary image. The object file includes all code, data, symbol, debug information and memory addresses. For the GCC tool chain, the linker output is usually an .elf file.
Your linker uses a "link script" or other definition file to locate the various segments at the appropriate memory addresses. Your tool chain should have docs on how to change that.
The "objcopy" utility will read linker output and can write output files in a variety of formats, including Intel-hex. For human readable output see "objdump".
By memory address. GCC uses the "initialized data" segment for data which is copied to the bss. It is located according to your linker script.
Intel-hex format: http://en.wikipedia.org/wiki/Intel_HEX
GCC: http://gcc.gnu.org/onlinedocs/
您的编程工具只需将程序映像(十六进制或二进制文件)写入闪存中的指定地址即可。
当编译器编译程序时,它会将包含
.bss
和.data
等信息的信息(查找表)添加到十六进制文件中,以及一些 C 开头向上代码。 C 启动代码在 Cmain()
函数开始之前运行,负责根据以下条件初始化.bss
和.data
闪存中查找表中的信息。通常,这意味着:.bss
初始化为零。.data
的初始化值从闪存复制到 RAM 中的适当位置。在某些平台上,出于各种原因,您可能希望在 RAM 中运行代码。 C 启动代码也可以以类似的方式将代码从 Flash 复制到 RAM。
C 启动代码还可以执行其他基本操作:
Your programming tools just write the program image (hex or binary file) into Flash, at the specified address.
When the compiler compiles the program, it adds information (look-up tables) containing information about the
.bss
and.data
etc into the hex file, along with some C start-up code. The C start-up code, which runs before the Cmain()
function begins, is responsible for initialising.bss
and.data
according to the information in the look-up tables in Flash memory. Typically, that means:.bss
to zeros..data
from the Flash memory into the appropriate locations in RAM.On some platforms, you might want to run code in RAM, for various reasons. The C start-up code can also copy code from Flash to RAM in a similar way.
The C start-up code can also do other essential things:
通常,这些问题可以通过用于管理目标设备的嵌入式工具来解决。
对于小型嵌入式设备(RAM 和 ROM/NVRAM 小于 16K 到 128K),代码直接从 NVRAM 执行。初始化代码将初始化的数据复制到 RAM,可能会对其进行解压缩,并通常通过清除未初始化的 RAM 来初始化它。定位器负责使所有数据引用访问正确的目标地址,而不是 ROM 数据的地址。
大型嵌入式设备的运行速度比 NVRAM 快得多,因此它们往往是将 NVRAM 内容(代码加数据)从 NVRAM 复制到 RAM 来执行。
回答您的其他观点:
2)最终的二进制文件经过精心构造,以区分程序部分。有许多不同的文件格式。有关详细信息,请参阅有关该格式的相应维基百科文章。
3)您可能不需要转换为十六进制格式,尽管这取决于您的目标加载程序。例如,基于 U-Boot 的系统支持二进制数据的
kermit
文件传输。4) 参见2)。
Typically these issues are solved by the embedded tools you use to manage the target device.
For small embedded devices (less than 16K to 128K of RAM and ROM/NVRAM), code executes directly from NVRAM. The initialization code copies initialized data to RAM, perhaps decompressing it, and initializes uninitialized RAM, usually by clearing it. The locator is responsible for making all data references access the proper target addresses and not the address of ROM data.
Large embedded devices run much faster than NVRAM, so they tend to be implemented where NVRAM content (code plus data) is copied from NVRAM to RAM for execution.
To answer your other points:
2) The final binary is carefully structured to distinguish between program sections. There are many different file formats. See the corresponding Wikipedia article about the format for details.
3) You many not need to convert to hex format, though that depends on your target loader. For example, U-Boot based systems support
kermit
file transfers of the binary data.4) See 2).