在我们写程序时,必须给编译器链接器指定地址。将来的程序被执行时必须放在当时编译链接时给定的地址才能运行。
但是也有一种特别的指令他可以跟指定的链接地址没有关系,这些代码不管放在哪里都可以正常运行。
分析:
之前的裸机程序中,makefile中用-Ttext 0x0来指定链接地址是0x0;这意味着我们认为将来这个程序会被放在0x0这个地址去运行。但是实际上我们在DNW中,把程序下载到0xd0020010. 在s5pv210中,由于在内部做了映射,所以0xd002_0010和0x0000_0010是一样的。那么为什么放在0x0而不是0x0000_0010依旧可以呢?原因就这个是位置无关编码。
在linux中的应用程序:gcc hello.c -o hello
三星推荐的启动方式:
bootloader必须大于16KB小于96KB,假定为80KB。启动过程如下:开机上电后BL0运行,BL0加载外部启动设备中的bootloader的前16KB(BL1)到SRAM中运行,BL1运行后会加载BL2到(80-16=64KB)到SRAM中运行,BL2运行时会初始化DDR并且将OS搬到DDR中执行,启动完成。
uboot实际使用方式:
uboot大小随意,假定为200KB,启动过程:先开机上电后BL0运行,BL0会加载外部启动设备中的uboot的前16KB到SRAM运行,BL1运行时会初始化DDR,然后将整个uboot搬运到DDR中,然后用一句长跳转指令从SRAM直接跳转到DDR中继续执行uboot直到uboot完全启动。uboot启动后在命令行中启动OS
strip:strip是把可执行程序中的符号给拿掉,以节省空间(debug版本和release版本)
objcopy:由可执行程序生成可烧录的镜像bin文件
段是程序的一部分,我们把整个程序的所有东西分成了一个个段,给每个段起一个名字,然后再链接时可以用和这个名字来指示这些段
段名分为2种:一种是编译器连接器内部定好的,一种是程序员自己指定的,自定义的段名
先天性段名:
后天性段名:
段名由程序员自己定义,段的属性和特征也由程序员自己定义。
分析一些问题,跟这里结合,然后试图明白一些本质
链接脚本就是一个规则文件,他是程序员用来指挥链接器用来工作的。链接器会参考链接脚本并且使用其中规定的规则来处理.o文件中的那些段,将其链接成可执行程序。
链接脚本的关键内容有两个部分:段名+地址(作为链接地址的内存地址)
SECTIONS{}这个是整体链接脚本
. 点号在链接脚本中代表当前位置
= 等号代表赋值
SECTIONS { . = 0xd0024000 .text : { start.o *(.text) } .data : { *(.data) } bss_start = .; .bss : { *(.bss) } bss_end = .; }
原文:http://www.cnblogs.com/jxjl/p/7003718.html