其他分享
首页 > 其他分享> > 【ARM】linker script file

【ARM】linker script file

作者:互联网

链接脚本文件,用于控制链接过程。以stm32在Linux环境下编译作为示例,项目链接git库地址:

tangquan/test.ld_file.proghttps://gitee.com/tq797/test.ld_file.prog

各种原因,视频参考教程的地址在文件startup_stm32f401xc.c里面。Makefile语法参考文章:

【Linux开发】一个小规模工程的Makefile模板_欢迎光临-CSDN博客本Makefile适用于小规模软件工程。修改SOURCE_PATH变量设置源码路径,修改BINARY_PATH变量设置输出文件的路径,OBJECT_PATH变量为中间.o文件的存放目录,INCLUDE_PATH变量为头文件包含路径,TARGET变量为输出文件名。Makefile会输出依赖关系文件“xxx.o.d”,以便根据依赖关系只进行必要的编译工作。# GNU的make工作时的执行步骤如下...https://blog.csdn.net/tq384998430/article/details/100087283?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163489021416780274187536%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=163489021416780274187536&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_v2~rank_v29-3-100087283.pc_v2_rank_blog_default&utm_term=makefile&spm=1018.2226.3001.4450ARM处理器的裸机代码编译可以使用armcc编译器(MDK,收费)或者gcc编译器(免费)。我使用的是arm-none-eabi-gcc,百度一下就能下载。交叉编译器的命名规则比较迷,这里arm表示处理器架构,none表示未指定制造商,eabi表示遵循嵌入式应用二进制接口标准,未指定操作系统。链接脚本的语法参考视频教程。

Makefile:

PROJECT				= bare_metal_arm
TARGET				= $(PROJECT)
TARGET_ELF			= $(PROJECT).elf
TARGET_BIN			= $(PROJECT).bin
TARGET_HEX			= $(PROJECT).hex
TARGET_MAP			= $(PROJECT).map

MACH				= cortex-m4

ROOT_DIR			= .
OBJ_DIR				= $(ROOT_DIR)/obj
OUT_DIR				= $(ROOT_DIR)/out

SOURCE_PATH			?= $(ROOT_DIR)
OBJECT_PATH			?= $(OBJ_DIR)
INCLUDE_PATH 		:= 

LINKER_SCRIPT		= $(ROOT_DIR)/link.ld
LINKER_SPECS		= nano.specs

SOURCES				:= $(foreach tmp,$(SOURCE_PATH),$(wildcard $(tmp)/*.c $(tmp)/*.cpp))
OBJECTS				:= $(addsuffix .o,$(addprefix $(OBJECT_PATH)/,$(basename $(notdir $(SOURCES)))))
DEPENDS				:= $(addsuffix .d,$(OBJECTS))

# $(info SOURCES: $(SOURCES))
# $(info OBJECTS: $(OBJECTS))
# $(info DEPENDS: $(DEPENDS))



CC := arm-none-eabi-gcc
# LD := arm-none-eabi-ld
LD := arm-none-eabi-gcc        # use gcc as the linker which can automatically find the dependent libraries
OBJCOPY := arm-none-eabi-objcopy

CFLAGS := -c -mcpu=$(MACH) -mthumb -std=gnu11 -Wall -O0
# CFLAGS += -ffunction-sections
LDFLAG := -mcpu=$(MACH) -mthumb -T link.ld -Wl,-Map=$(OUT_DIR)/$(TARGET_MAP) --specs=$(LINKER_SPECS) -mfloat-abi=soft
# LDFLAG += -Wl,--gc-sections
# LDFLAG += -L/c/gcc-arm-none-eabi-10.3/arm-none-eabi/lib
# LDFLAG += -L/c/gcc-arm-none-eabi-10.3/lib/gcc/arm-none-eabi/10.3.1




all : $(TARGET_ELF)
	$(info Build "$(PROJECT)" finished)

$(TARGET_ELF): $(OBJECTS)
#	$(info LD $@)
	$(LD) $(LDFLAG) -o $(OUT_DIR)/$@ $^
	$(OBJCOPY) -O binary -R .note -R .comment -S $(OUT_DIR)/$@ $(OUT_DIR)/$(TARGET_BIN)

-include $(DEPENDS)

$(foreach tmp,$(SOURCES),\
	$(eval $(addprefix $(OBJECT_PATH)/,$(addsuffix .o,$(basename $(notdir $(tmp))))):; \
				${CC} ${CFLAGS} $(INCLUDE_PATH) \
				-MMD -MF $(OBJECT_PATH)/$(basename $(notdir $(tmp))).o.d \
				-c -o $(OBJECT_PATH)/$(basename $(notdir $(tmp))).o $(tmp)))



.PHONY : clean setenv
clean:
	rm *.o ${TARGET}.* obj/* out/* -rf

linker script file:

/* Entry Point */
ENTRY(Reset_Handler)

/* Highest address of the user mode stack */
_estack = 0x20005000;    /* end of 20K 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 = 0x100; /* required amount of stack */

/* Specify the memory areas */
MEMORY
{
    FLASH(rx):ORIGIN =0x08000000,LENGTH =64K
    SRAM(rwx):ORIGIN =0x20000000,LENGTH =20K
}

/* Define output sections */
SECTIONS
{
    /* The startup code goes first into FLASH */
    .isr_vector :
    {
        . = ALIGN(4);
        KEEP(*(.isr_vector)) /* Startup code */
        . = ALIGN(4);
    } >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 = .;
        _exit = _etext;
    }> FLASH

    _la_data = LOADADDR(.data);
    
    .data :
    {
        . = ALIGN(4);

        _sdata = .;
        *(.data)           /* .data sections */
        *(.data*)          /* .data* sections */

        . = ALIGN(4);
        _edata = .;
    }> SRAM AT> FLASH

    .bss :
    {
        _sbss = .;
        __bss_start__ = _sbss;
        *(.bss)
        *(.bss*)
        *(COMMON)
        . = ALIGN(4);
        _ebss = .;
        __bss_end__ = _ebss;
    }> SRAM

    PROVIDE ( end = _ebss );    /* head starts after the .bss section */
    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);
    } >SRAM

    /* Remove information from the standard libraries */
    /DISCARD/ :
    {
        libc.a ( * )
        libm.a ( * )
        libgcc.a ( * )
    }

}

编译出来的文件:

 bin文件就可以下载到MCU中去,segger j-flash有linux版本:

SEGGER - The Embedded Experts - Downloads - J-Link / J-Traceicon-default.png?t=L9C2https://www.segger.com/downloads/jlink/使用JFlash命令可以打开UI界面,和windows上的j-flash是一样的:

 下载运行,使用的是STM32F401CCU,没有找到openocd的合适的脚本,没有进行调试验证。

标签:none,TARGET,linker,arm,eabi,file,PATH,ARM,DIR
来源: https://blog.csdn.net/tq384998430/article/details/120894350