linux能编写stm52程序吗,在Windows10的Linux子系统下开发STM32----LD文件简述

ld是GUN binutils工具集中的一个,是众多Linkers(链接器)的一种。其主要作用是完成链接器的基本功能:把各种目标文件和库文件链接起来,并重定向它们的数据,完成符号解析。

Linking主要就是完成四个方面的工作:分配存储器、管理标识符、库和代码迁移。

ld可以识别一种Linker command Language表示的linker scriopt文件来显示的控制链接的过程。通过BFD(Binary Format Description)库,ld可以读取和操作COFF(common object file format)、ELF(executable and linking format)、a.out等各种格式的目标文件。

下面就对led_test实例工程中的stm32f103zet6_flash.ld进行简单的说明。

/\* Entry Point \*/

ENTRY(Reset\_Handler)

/\* Highest address of the user mode stack \*/

\_estack = 0x20010000; /\* end of 64K RAM \*/

/\* Generate a link error if heap and stack don't fit into RAM \*/

\_Min\_Heap\_Size = 0; /\* required amount of heap \*/

\_Min\_Stack\_Size = 0x200; /\* required amount of stack \*/

/\* Specify the memory areas \*/

MEMORY

{

FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K

RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K

MEMORY\_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K

}

/\* Define output sections \*/

SECTIONS

{

/\* The startup code goes first into FLASH \*/

.isr\_vector :

{

. = ALIGN(4);

KEEP(\*(.isr\_vector)) /\* Startup code \*/

. = ALIGN(4);

} >FLASH

/\* The program code and other data goes into FLASH \*/

.text :

{

. = ALIGN(4);

\*(.text) /\* .text sections (code) \*/

\*(.text\*) /\* .text\* sections (code) \*/

\*(.rodata) /\* .rodata sections (constants, strings, etc.) \*/

\*(.rodata\*) /\* .rodata\* sections (constants, strings, etc.) \*/

\*(.glue\_7) /\* glue arm to thumb code \*/

\*(.glue\_7t) /\* glue thumb to arm code \*/

KEEP (\*(.init))

KEEP (\*(.fini))

. = ALIGN(4);

\_etext = .; /\* define a global symbols at end of code \*/

} >FLASH

.ARM.extab : { \*(.ARM.extab\* .gnu.linkonce.armextab.\*) } >FLASH

.ARM : {

\_\_exidx\_start = .;

\*(.ARM.exidx\*)

\_\_exidx\_end = .;

} >FLASH

.ARM.attributes : { \*(.ARM.attributes) } > FLASH

.preinit\_array :

{

PROVIDE\_HIDDEN (\_\_preinit\_array\_start = .);

KEEP (\*(.preinit\_array\*))

PROVIDE\_HIDDEN (\_\_preinit\_array\_end = .);

} >FLASH

.init\_array :

{

PROVIDE\_HIDDEN (\_\_init\_array\_start = .);

KEEP (\*(SORT(.init\_array.\*)))

KEEP (\*(.init\_array\*))

PROVIDE\_HIDDEN (\_\_init\_array\_end = .);

} >FLASH

.fini\_array :

{

PROVIDE\_HIDDEN (\_\_fini\_array\_start = .);

KEEP (\*(.fini\_array\*))

KEEP (\*(SORT(.fini\_array.\*)))

PROVIDE\_HIDDEN (\_\_fini\_array\_end = .);

} >FLASH

/\* used by the startup to initialize data \*/

\_sidata = .;

/\* Initialized data sections goes into RAM, load LMA copy after code \*/

.data : AT ( \_sidata )

{

. = ALIGN(4);

\_sdata = .; /\* create a global symbol at data start \*/

\*(.data) /\* .data sections \*/

\*(.data\*) /\* .data\* sections \*/

. = ALIGN(4);

\_edata = .; /\* define a global symbol at data end \*/

} >RAM

/\* Uninitialized data section \*/

. = ALIGN(4);

.bss :

{

/\* This is used by the startup in order to initialize the .bss secion \*/

\_sbss = .; /\* define a global symbol at bss start \*/

\_\_bss\_start\_\_ = \_sbss;

\*(.bss)

\*(.bss\*)

\*(COMMON)

. = ALIGN(4);

\_ebss = .; /\* define a global symbol at bss end \*/

\_\_bss\_end\_\_ = \_ebss;

} >RAM

PROVIDE ( end = \_ebss );

PROVIDE ( \_end = \_ebss );

/\* User\_heap\_stack section, used to check that there is enough RAM left \*/

.\_user\_heap\_stack :

{

. = ALIGN(4);

. = . + \_Min\_Heap\_Size;

. = . + \_Min\_Stack\_Size;

. = ALIGN(4);

} >RAM

/\* MEMORY\_bank1 section, code must be located here explicitly \*/

/\* Example: extern int foo(void) \_\_attribute\_\_ ((section (".mb1text"))); \*/

.memory\_b1\_text :

{

\*(.mb1text) /\* .mb1text sections (code) \*/

\*(.mb1text\*) /\* .mb1text\* sections (code) \*/

\*(.mb1rodata) /\* read-only data (constants) \*/

\*(.mb1rodata\*)

} >MEMORY\_B1

/\* Remove information from the standard libraries \*/

/DISCARD/ :

{

libc.a ( \* )

libm.a ( \* )

libgcc.a ( \* )

}

}

首先我们看ld文件的第一部分:

/\* Entry Point \*/

ENTRY(Reset\_Handler)

/\* Highest address of the user mode stack \*/

\_estack = 0x20010000; /\* end of 64K RAM \*/

/\* Generate a link error if heap and stack don't fit into RAM \*/

\_Min\_Heap\_Size = 0; /\* required amount of heap \*/

\_Min\_Stack\_Size = 0x200; /\* required amount of stack \*/

该部分指定了入口地址,RAM的结束地址。并指定了堆和栈的大小。

其中,Reset_Handler为入口地址。

因为我们实例中使用的MCU为STM32F103ZET6,其中RAM的大小为64K,RAM的启始地址为0x20000000,所以RAM的结束地址为:RAM启始地址+RAM的大小,即0x20010000。

堆的大小为0,即_Min_Heap_size=0;栈的大小为512B,即_Min_Stack_Size=0x200。

第二部分:

MEMORY

{

FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K

RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K

MEMORY\_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K

}

该部分给出地址的划分区间。

其中,FLASH的启始地址为0x08000000,其长度为512K。

RAM的启始地址为0x20000000,其长度为64K

MEMORY_B1的启始地址为0x60000000,其长度为0。

第三部分:

SECTIONS

{

/\* The startup code goes first into FLASH \*/

.isr\_vector :

{

. = ALIGN(4);

KEEP(\*(.isr\_vector)) /\* Startup code \*/

. = ALIGN(4);

} >FLASH

/\* The program code and other data goes into FLASH \*/

.text :

{

. = ALIGN(4);

\*(.text) /\* .text sections (code) \*/

\*(.text\*) /\* .text\* sections (code) \*/

\*(.rodata) /\* .rodata sections (constants, strings, etc.) \*/

\*(.rodata\*) /\* .rodata\* sections (constants, strings, etc.) \*/

\*(.glue\_7) /\* glue arm to thumb code \*/

\*(.glue\_7t) /\* glue thumb to arm code \*/

KEEP (\*(.init))

KEEP (\*(.fini))

. = ALIGN(4);

\_etext = .; /\* define a global symbols at end of code \*/

} >FLASH

.ARM.extab : { \*(.ARM.extab\* .gnu.linkonce.armextab.\*) } >FLASH

.ARM : {

\_\_exidx\_start = .;

\*(.ARM.exidx\*)

\_\_exidx\_end = .;

} >FLASH

.ARM.attributes : { \*(.ARM.attributes) } > FLASH

.preinit\_array :

{

PROVIDE\_HIDDEN (\_\_preinit\_array\_start = .);

KEEP (\*(.preinit\_array\*))

PROVIDE\_HIDDEN (\_\_preinit\_array\_end = .);

} >FLASH

.init\_array :

{

PROVIDE\_HIDDEN (\_\_init\_array\_start = .);

KEEP (\*(SORT(.init\_array.\*)))

KEEP (\*(.init\_array\*))

PROVIDE\_HIDDEN (\_\_init\_array\_end = .);

} >FLASH

.fini\_array :

{

PROVIDE\_HIDDEN (\_\_fini\_array\_start = .);

KEEP (\*(.fini\_array\*))

KEEP (\*(SORT(.fini\_array.\*)))

PROVIDE\_HIDDEN (\_\_fini\_array\_end = .);

} >FLASH

/\* used by the startup to initialize data \*/

\_sidata = .;

/\* Initialized data sections goes into RAM, load LMA copy after code \*/

.data : AT ( \_sidata )

{

. = ALIGN(4);

\_sdata = .; /\* create a global symbol at data start \*/

\*(.data) /\* .data sections \*/

\*(.data\*) /\* .data\* sections \*/

. = ALIGN(4);

\_edata = .; /\* define a global symbol at data end \*/

} >RAM

/\* Uninitialized data section \*/

. = ALIGN(4);

.bss :

{

/\* This is used by the startup in order to initialize the .bss secion \*/

\_sbss = .; /\* define a global symbol at bss start \*/

\_\_bss\_start\_\_ = \_sbss;

\*(.bss)

\*(.bss\*)

\*(COMMON)

. = ALIGN(4);

\_ebss = .; /\* define a global symbol at bss end \*/

\_\_bss\_end\_\_ = \_ebss;

} >RAM

PROVIDE ( end = \_ebss );

PROVIDE ( \_end = \_ebss );

/\* User\_heap\_stack section, used to check that there is enough RAM left \*/

.\_user\_heap\_stack :

{

. = ALIGN(4);

. = . + \_Min\_Heap\_Size;

. = . + \_Min\_Stack\_Size;

. = ALIGN(4);

} >RAM

/\* MEMORY\_bank1 section, code must be located here explicitly \*/

/\* Example: extern int foo(void) \_\_attribute\_\_ ((section (".mb1text"))); \*/

.memory\_b1\_text :

{

\*(.mb1text) /\* .mb1text sections (code) \*/

\*(.mb1text\*) /\* .mb1text\* sections (code) \*/

\*(.mb1rodata) /\* read-only data (constants) \*/

\*(.mb1rodata\*)

} >MEMORY\_B1

/\* Remove information from the standard libraries \*/

/DISCARD/ :

{

libc.a ( \* )

libm.a ( \* )

libgcc.a ( \* )

}

}

该部分指定了程序的各个内容该如何放置在flash上或者ram上。

其中.=ALLGN(4)是指4字节对齐

.,小数点表示当前的地址位置

一般的程序中包含常见的几个段:text(存放程序),rodata(存放被初始化的数据),data(表示初始化不为0的变量),bass(表示初始化值为默认的全局变量)

Text,rodata放在FLASH中,而data中的初始化值作为rodata放在FLASH中,变量在RAM中占有空间,bss点RAM空间

段可以自定义,由于编译obj的过程中不会生成用户自定义的段,因此在源码中需要指定需要特殊处理的段

结尾的>MEMORY_B1指上面花括号内的内容都放在第二部分中定义的MEMORY_B1空间中。如果没有AT> FLASH,那么编译bin文件时,地址是连续的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值