链接脚本
链接脚本是指导链接器(ld)的编译过程,控制程序中各段:.text/.data/.bss等 在内存中的位置排布。
伪操作:汇编程序中以点.开头的名称并不是指令的助记符,不会被翻译成机器指令,而是给汇编器一些特殊指示,称为汇编指示(Assembler Directive)或伪操作(Pseudo-operation),由于它不是真正的指令所以加个“伪”字。
- .section指示把代码划分成若干个段(Section),程序被操作系统加载执行时,每个段被加载到不同的地址,操作系统对不同的页面设置不同的读、写、执行权限。
- .data段保存程序的数据,是可读可写的,相当于C程序的全局变量。本程序中没有定义数据,所以.data段是空的。
.section .text
链接脚本代码
map.lds:链接脚本文件
OUTPUT_ARCH(arm) ARM架构
ENTRY(_start) 指定代码启动位置_start
SECTIONS SECTIONS{}:代表是整个链接脚本代码的范围
{
. = 0x43C00000; .:表示当前位置;=:赋值地址,即程序加载时的启动首地址(也是loadb下载的地址)。
. = ALIGN(4);
.text : 文本段text:先存放启动代码start.S和后存放一些函数代码段
{
start/start.o(.text) 先存放:start目录下的start.o文件
*(.text) *:是通配符,指其他的.o文件根据链接器存放
}
. = ALIGN(4);
.rodata : 常量数据区
{
*(.rodata)
}
. = ALIGN(4);
.data : 初始化的全局变量
{
*(.data)
}
. = ALIGN(4);
__bss_start = .;
.bss : bss:未初始化的全局变量/static 局部变量,默认值为0
{
*(.bss)
}
__bss_end__ = .;
}
Makefile
CROSS_COMPILE = arm-none-linux-gnueabi- #指定交叉编译工具
NAME = interface #文件名
#=============================================================================#
CFLAGS += -g -Wall -O0 -mabi=apcs-gnu -mfpu=neon -mfloat-abi=softfp -fno-builtin \
-nostdinc -I./common/include
#CFLAGS:添加调试信息-g和-I./common/include:指定链接头文件的目录
LD = $(CROSS_COMPILE)ld
CC = $(CROSS_COMPILE)gcc
NM = $(CROSS_COMPILE)nm
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
#============================================================================#
# 展开start/、commom/src/、src/、以及.目录下所有的.c/.S文件
OBJSss := $(wildcard start/*.S) $(wildcard common/src/*.S) $(wildcard *.S)\
$(wildcard start/*.c) $(wildcard common/src/*.c) \
$(wildcard src/*.c) $(wildcard *.c)
# 将所有的.S文件替换成.o目标文件
OBJSs := $(patsubst %.S,%.o,$(OBJSss))
# 将所有的.c文件替换成.o目标文件
OBJS := $(patsubst %.c,%.o,$(OBJSs))
%.o: %.S
@echo " AS $@"
$(CC) $(CFLAGS) -c -o $@ $<
%.o: %.c
@echo " CC $@"
$(CC) $(CFLAGS) -c -o $@ $<
all:clean $(OBJS)
@echo " LD Linking $(NAME).elf"
$(LD) $(OBJS) -T map.lds -o $(NAME).elf
@echo " OBJCOPY Objcopying $(NAME).bin"
$(OBJCOPY) -O binary $(NAME).elf $(NAME).bin
@echo " MAP Generating $(NAME).map"
$(NM) $(NAME).elf > $(NAME).map
@echo " OBJDUMP Objdumping $(NAME).dis"
$(OBJDUMP) -DS $(NAME).elf > $(NAME).dis
distclean clean:
rm -rf $(OBJS) *.elf *.bin *.dis *.map
@echo " CLEAN complete."