链接脚本的解析

文章目录

    • 1 链接脚本的语法
    • 2 elf文件和bin文件运行的不同
    • 3 清除bss段
      • 3.1 未清除bss段时
      • 3.2 清除bss段

1 链接脚本的语法

链接脚本的语法:

SECTIONS {
...
secname start BLOCK(align) (NOLOAD) : AT ( ldadr )
  { contents } >region :phdr =fill
...
}

解释:

  • secname:段名
  • start:起始地址,运行时的地址(runtime addr);重定位地址(relocate addr)
  • AT ( ldadr ) :可有可无(load addr:加载地址), 不写时LoadAddr = runtime addr
  • { contents } 的内容,有如下几种形式:
    • start.o //内容为start.o文件
    • *(.text)所有的代码段文件
    • start.o *(.text)文件

2 elf文件和bin文件运行的不同

elf文件格式:

  1. 链接得到elf文件,含有地址信息(load addr)。
  2. 使用加载器。
    2.1 对于裸板是JTAG调试工具。
    2.2 对于APP,加载器也是APP 把elf文件解析读入内存的加载地址。
  3. 运行程序
  4. 如果loadaddr != runtimeaddr程序本身要重定位,核心程序运行时应该位于 runtimeaddr(reloate addr)或者链接地址。

bin文件:

  1. elf生成bin文件。
  2. 硬件机制启动。
  3. 如果bin文件所在位置不等于runtimeaddr ,程序本身实现重定位。

3 清除bss段

bin文件/elf文件都不保存bss段,这些都是初始值为0或者没有初始化的全局变量。程序运行时把bss段对应的空间清零。

3.1 未清除bss段时

做个实验,把全局变量g_A以16进制打印出来。

/* 0xABCDEF12 */
void printHex(unsigned int val)
{
	int i;
	unsigned char arr[8];

	/* 先取出每一位的值 */
	for (i = 0; i < 8; i++)
	{
		arr[i] = val & 0xf;
		val >>= 4;   /* arr[0] = 2, arr[1] = 1, arr[2] = 0xF */
	}

	/* 打印 */
	puts("0x");
	for (i = 7; i >=0; i--)
	{
		if (arr[i] >= 0 && arr[i] <= 9)
			putchar(arr[i] + '0');
		else if(arr[i] >= 0xA && arr[i] <= 0xF)
			putchar(arr[i] - 0xA + 'A');
	}
}
//打印初始值为0的变量
int g_A = 0;
int g_B;

int main(void)
{
	uart0_init();

	puts("\n\rg_A = ");
	printHex(g_A);
	puts("\n\r");
}

上述代码,没有清理bss段 g_A等于莫名奇妙的值 并不等于0 所以需要清理bss段。

3.2 清除bss段

修改lds链接文件:

SECTIONS {
   .text   0  : { *(.text) }
   .rodata  : { *(.rodata) }
   .data 0x30000000 : AT(0x800) 
   { 
      data_load_addr = LOADADDR(.data);
      data_start = . ;
      *(.data) 
      data_end = . ;
   }
   
   bss_start = .; //bss开始地址是当前位置
   .bss  : { *(.bss) *(.COMMON) }
   bss_end = .; //bss结束地址也是当前位置
}

修改start.s,清除bss段:

/* 清除BSS段 */
	ldr r1, =bss_start
	ldr r2, =bss_end
	mov r3, #0
clean:
	strb r3, [r1]
	add r1, r1, #1
	cmp r1, r2
	bne clean

	bl main

halt:
	b halt

现在的代码全局变量就是为0,通过几行代码,就可以少几十个甚至上千个全局变量的存储空间。

你可能感兴趣的:(Linux)