lds链接文件--Apple的学习笔记

原来windows下也可以编译出arm elf文件。我在网上无意间看到的,所以就下载来试用下。因为只想再学习下lds的语法,不想开2个PC再用vpn连接了。

https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm

下载成功后解压。我不想放入到环境变量中,以免影响到其它,所以制作了bat脚本来设置临时环境变量,本来也就是临时复习下,哈哈~

1. 工程搭建

armGunEnv.bat内容为

set path=%path%;D:/program/gcc_arm_win32/bin;D:/program/gcc_arm_win32/arm-none-eabi/bin

先做一个小的c语言工程。Hello.c代码如下

#include 

unsigned char a=1;

unsigned char b;

int main(void)

{

 a++;

 while(1)

 {

 if(a==10)

 {

 b++;

 }

 }

 return 0;

}

链接文件代码如下

SECTIONS

{

 . = 0x10000;

 .text : { *(.text) }

 . = 0x8000000;

 .data : { *(.data) }

 .bss : { *(.bss) }

}

Makefile文件代码如下

CC = arm-none-eabi-gcc

LD = arm-none-eabi-ld

CFLAGS = -Wall -g

TARGET = hello

MAPFLAGS = -Wl,-Map,hello.map

SOURCES = $(wildcard *.c)

OBJS = $(patsubst %.c, %.o, $(SOURCES))

$(TARGET):$(OBJS) 

 $(CC) --specs=nosys.specs -c $(SOURCES)

 $(LD) -Thello.lds $(OBJS) -o hello.elf

clean:

 rm -rf *.o hello

运行结果

image.png

全局变量a的初始化值若设置为0,就看不到.data段了。因为全局变量值为0也会放入.bss段中。

然后通过lds可以看出0x00010000为txt的首地址,size为0x54。0x08000000为.data的首地址,顺序为先.data然后是其它的。与实际elf看出的结果一致。

2 添加MEMORY命令

教程在gun官网https://sourceware.org/binutils/docs/ld/index.html,刚刚是sample lds,现在添加了RAM和ROM的重定向

Lds文件如下

MEMORY

 {

 ROM : ORIGIN = 0, LENGTH = 10

 RAM : ORIGIN = 0x10000000, LENGTH = 1M

 }

REGION_ALIAS("REGION_TEXT", ROM);

REGION_ALIAS("REGION_RODATA", ROM);

REGION_ALIAS("REGION_DATA", RAM);

REGION_ALIAS("REGION_BSS", RAM);

SECTIONS

 {

 .text :

 {

 *(.text)

 } > REGION_TEXT

 .rodata :

 {

 *(.rodata)

 rodata_end = .;

 } > REGION_RODATA

 .data : AT (rodata_end)

 {

 data_start = .;

 *(.data)

 } > REGION_DATA

 data_size = SIZEOF(.data);

 data_load_start = LOADADDR(.data);

 .bss :

 {

 *(.bss)

 } > REGION_BSS

 }

LENGTH = 10故意设置为10个字节,那么最后编译会报错,说`ROM' overflowed。

E:\mycode\gcc\hello>make

arm-none-eabi-gcc -Wall -g -c -o hello.o hello.c

arm-none-eabi-gcc --specs=nosys.specs -c hello.c

arm-none-eabi-ld -Thello.lds hello.o -o hello.elf

arm-none-eabi-ld: warning: dot moved backwards before `.bss'

arm-none-eabi-ld: warning: dot moved backwards before `.bss'

arm-none-eabi-ld: hello.elf section `.text' will not fit in region `ROM'

arm-none-eabi-ld: warning: dot moved backwards before `.bss'

arm-none-eabi-ld: warning: dot moved backwards before `.bss'

arm-none-eabi-ld: warning: dot moved backwards before `.bss'

arm-none-eabi-ld: region `ROM' overflowed by 114 bytes

make: *** [hello] Error 1

修改ROM LENGTH = 4M后编译结果。


image.png

3问题.data:后面的AT有什么作用?

好吧,我还是从头开始看,系统的了解下ld文件及section的概念。原来3.1章节就写了。地址分为VMA(运行地址)和LMA(下载地址),默认情况下VMA和LMA是一样的,但是AT(addr)或者>AT(addr)就定义了它的LMA地址与VMA地址不同,是一个特别的LMA地址。然后通过objdump –h hello.elf查看信息,就豁然开朗了,原来AT是有用的,它定义了下载地址,然后运行RAM的时候地址为0x10000000。如下图

Every loadable or allocatable output section has two addresses. The first is the VMA, or virtual memory address. This is the address the section will have when the output file is run. The second is the LMA, or load memory address. This is the address at which the section will be loaded. In most cases the two addresses will be the same. An example of when they might be different is when a data section is loaded into ROM, and then copied into RAM when the program starts up (this technique is often used to initialize global variables in a ROM based system). In this case the ROM address would be the LMA, and the RAM address would be the VMA.

You can see the sections in an object file by using the objdump program with the ‘-h’ option.

The load address is specified by the AT or AT> keywords.

image.png

你可能感兴趣的:(lds链接文件--Apple的学习笔记)