我的任务是为嵌入式系统开发一个简单的引导加载程序。我们没有运行任何操作系统或RTOS,所以我希望它非常简单。
此代码将存储在ROM中,处理器将在开机时开始执行。
我的目标是用ASM编写第一部分来处理以下操作:
Main显然是用C语言编写的,并执行更高级别的操作,如自测等......
现在,我真正不知道如何将这两个程序合并为一个程序。我找到了一个糟糕的工具,基本上使用objcopy从可执行文件中收集.text和.data部分并在前面附加一些asm,但这似乎是一种非常丑陋的方式来做到这一点我想知道是否有人能指出我在右边方向?
答案 0 :(得分:2)
您可以(原则上)链接从汇编程序代码生成的目标文件,就像链接程序中的任何对象一样。
问题是您需要布置生成的可执行文件,以便您的启动代码在开头。如果您使用GNU ld,那么执行此操作的方法是linker script。
原始设置(未检查语法错误):
MEMORY
{
FLASH (RX) : ORIGIN = 0, LENGTH = 256K
RAM (RWX) : ORIGIN = 0x40000000, LENGTH = 4M
}
SECTIONS
{
.bootloader 0 : AT(0) { bootloader.o(.text) } >FLASH AT>FLASH
.text : { _stext = .; *(.text .text.* .rodata .rodata.*); _etext = . } >FLASH AT>FLASH
.data : { _sdata = .; *(.data .data.*); _edata = .; _sdata_load = LOADADDR(.data) } >RAM AT>FLASH
.bss (NOLOAD) { _sbss = .; *(.bss .bss.*); _ebss = . } >RAM
}
基本思想是让链接器大致了解内存映射,然后将输入文件中的部分分配给最终程序中的部分。
链接器为每个输出节保留“虚拟”和“加载”地址之间的区别,因此您可以告诉它生成二进制文件,其中代码重新定位到最终地址,但可执行文件中的布局是不同(在这里,我告诉它将 .data 部分放在RAM中,但将其附加到flash中的 .text 部分)。
然后,您的引导加载程序可以使用提供的符号(_sdata
,_edata
,_sdata_load
)来查找RAM和闪存中的数据部分,然后复制它。
最后警告:如果你的程序使用静态构造函数,你还需要一个构造函数表,引导程序器需要调用静态构造函数。
答案 1 :(得分:1)