连接脚本

第一段程序:
helloword.c
#define UFCON0 ((volatile unsigned int *)(0x50000020))
void helloword(void){
    const char* p = "helloword\n";
    while(*p){
        *UFCON0 = *p++;
    };
    while(1);
}
UFCON0代表串口寄存器的地址,将数据写入这个寄存器,就会通过这个串口将数据发送出去
编译命令:
arm-elf-gcc -O2 -c helloword.c
-O是优化选项
-c编译成目标文件.o
此时是无法找到函数入口的,因为没有main函数同时也没有用连接脚本手动指向函数入口
因此手动指定函数入口以及链接生成可执行文件
arm-elf-ld -e helloword -Ttext 0x0 helloword.o -o helloword
-e helloworld是指定函数入口,这里边指定helloword函数是入口
-Ttext 0x0是指定函数运行的基地址,也就是说,链接工具将目标文件的helloworld函数链接到了内存的0地址上去执行
    内存0地址:ARM体系结构中代码都是从0地址开始运行
-o生成可执行文件,此时helloworld是ELF格式的可执行文件,还是不能够直接加载到硬件中去执行

生成.bin文件命令:
arm-elf-objcopy -O binary helloword helloword.bin
arm-elf-objcopy命令是将ELF格式的文件中的二进制机器码抽离出来的命令
    由于ELF格式的文件除了实际的代码之外,还包含ELF格式的文件头,段头或节头等附加信息
    抽离出来的.bin文件除了运行时的代码和数据之外不包含其他任何信息

应用程序中不用显示指定链接脚本,否则可能会与操作系统不匹配
但是操作系统代码与底层代码需要显示的指定连接脚本
一个典型的连接脚本
SECTIONS
{
    . = 0x1000;
    .text : {*(.text)}    //可执行文件中所有的代码段的集合的起始地址就是在0x1000处
    . = 0x8000000;
    .data : {*(.data)}
    .bss : {*(.bss)}
}
SECTIONS,这个命令是用来描述输出文件的内存分布的
代码段分配在0x1000处,data段分配在0x8000000处,bss段紧跟在data段后
.号是可赋值的,. = 0x1000;意义就是0x1000是起始地址后边跟着的是描述.text是代码段

例子:
helloword.lds
ENTRY(helloword)    //等价于-e选项,指定函数入口
SECTIONS
{
    . = 0x00000000;
    .text : {*(.text)}
    . = ALIGN(32); //ALIGN(n),就是按照n字节对齐
    .data : {*(.data)}
    . = ALIGN(32);
    .bss : {*(.bss)}    
}

使用链接脚本:
arm-elf-ld -T helloword.lds helloworld.o -o helloword
-T选项让链接器从链接脚本读取并解析命令,然后按照命令的要求链接生成可执行文件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值