gcc链接脚本和启动文件详解

C代码生成可执行程序分为:预编译、编译、汇编、链接四个阶段。

  1. 预处理器把源程序聚合在一起,并把宏定义转换为源语言;
  2. 编译器根据预处理的源程序生成汇编程序;
  3. 汇编器处理汇编程序,生成可重定位的机器代码;
  4. 连接器将可重定位的目标代码和库文件连接到一起,生成可执行程序。

在这里插入图片描述
介绍几个常用命令,具体解释出自《The GNU linker》:

  1. SECTIONS命令
    在这里插入图片描述
  2. MEMORY命令
    在这里插入图片描述
  3. ENTRY命令
    在这里插入图片描述
    output sections:
    在这里插入图片描述
    下面是rtthread bsp下的一个连接脚本,逐字分析:
/*
 * linker script for GD32F4xx with GNU ld
 * bernard.xiong 2009-10-14
 */

/* Program Entry, set to mark it as "used" and avoid gc */
/* MEMORY命令,定义flash、ram的起始地址和长度,name也可改写成ROM和RAM,rx和rw表示属性,可读可执行和可读可写,ORIGIN可以写成org或o,LENGTH可以写成len或l */
MEMORY
{
   
    CODE (rx) : ORIGIN = 0x08000000, LENGTH = 64k /* 64/512KB flash */
    DATA (rw) : ORIGIN = 0x20000000, LENGTH = 256k /* 256KB sram */
}
/* entry point,也有其他写法 */
ENTRY(Reset_Handler)
/* 定义栈大小 */
_system_stack_size = 0x1000;

/* SECTIONS命令,定义了具体的flash和ram分布 */
SECTIONS
{
   
	/* gcc在flash中主要包含text、data和bss三个section,text存放code,data存放initialized data,bss存放uninitialized data */
    .text :
    {
   
    	/* .表示the location counter,At the start of the ‘SECTIONS’ command, the location counter
has the value ‘0’,ALIGN(4)表示4字节对齐 */
        . = ALIGN(4);
        /* _stext表示text section的起始地址,在cmbacktrace中用到了_stext */
        _stext = .;
        /* 当垃圾回收开启时‘--gc-sections’,使用KEEP防止被清除,isr_vector在startup文件中被定义,从这里开始存放中断向量表 */
        KEEP(*(.isr_vector))            /* Startup code */
        . = ALIGN(4);
        /* The ‘*’ is a wildcard which matches any file name. The expression ‘*(.text)’ means all ‘.text’ input sections in all input files. */
        *(.text)                        /* remaining code */
        /* 这里应该是text的结尾,怎么理解会比较好一点? */
        *(.text.*)                      /* remaining code */
        *(.rodata)                      /* read-only data (constants) */
        *(.rodata*)
        /* 没找到glue_7的解释 */
        *(.glue_7)
        *(.glue_7t)
        *(.gnu.linkonce.t*)

        /* section information for finsh shell */
        . = ALIGN(4);
        __fsymtab_start = .;
        KEEP(*(FSymTab))
        __fsymtab_end = .;
        . = ALIGN(4);
        __vsymtab_start = .;
        KEEP(*(VSymTab))
        __vsymtab_end = .;
        . = ALIGN(4);

        /* section information for initial. */
        . = ALIGN(4);
        /*  */
        __rt_init_start = .;
        /* typedef int (*init_fn_t)(void)
        #define SECTION(x) __attribute__((section(x)))
        #define INIT_EXPORT(fn, level) RT_USED const init_fn_t __rt_init_##fn SECTION(".rti_fn." level) = fn
        init_fn_t是函数指针;
        SECTION(".rti_fn." level)则表示把对象放在由括号中的名称所指代的section中;
        INIT_EXPORT(rti_start, "0") => init_fn_t __rt_init_rti_start = rti_start SECTION(.rti_fn.0)
        SORT is an alias for SORT_BY_NAME
        实质就是将函数rti_start的首地址放到这个section中,并排序(启动顺序很重要) */
        KEEP(*(SORT(.rti_fn*)))
        __rt_init_end = .;
        . = ALIGN(4);

        . = ALIGN(4);
        /* cmbacktrace中用到了这个地址 */
        _etext = .;
    } > CODE = 0/* CODE section中 */

    /* .ARM.exidx is sorted, so ha
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值