uboot的编译及连接过程

前言

  想读懂uboot的链接脚本,以及了解链接脚本的使用方法,需要掌握以下基本知识。

1、gcc程序段介绍

  一个可执行程序主要包含text段(代码),data段(初始化的全局变量),以及bss段(未初始化的全局变量)。局部变量是在运行过程中分配的,不占用可执行程序的大小。下面举一个例子说明

#include <stdio.h>
#include <string.h>


int a = 0;            //全局未初始化变量,系统默认赋值成0,bss段,4个字节
int b = 5, c = 6; //全局已初始化变量, data段,8个字节

int main()
{
    int i = 0; //局部变量

    i++;
    a++;
    printf("i = %d, a = %d\n", i, a);

    return 0;
}

  将上面代码保存成main.c,并将其编译成.o文件:arm-fsl-linux-gnueabi-gcc -c main.c,-c参数说明只进行编译不进行链接。然后使用以下命令查看各种段的大小

root@silent:/home/lianxi/test# arm-fsl-linux-gnueabi-size main.o
   text    data     bss     dec     hex filename
    120       8       4     132      84 main.o
root@silent:/home/lianxi/test# 

  可以看到代码段大小120个字节,data段大小8个字节(变量b和c的大小),bss段的大小4个字节(变量a的大小),可执行程序的总大小为120+8+4=132。局部变量i,是在代码运行的时候分配的,不影响bin文件的大小!

2、链接脚本的使用

  为了说明uboot的编译及链接过程,这里写两个简单的汇编源文件,然后使用自己写的链接脚本将它们链接起来。两个源文件分别是mystart.s,mylowlevel_init.s,链接脚本是myboot.lds,其内容及注释如下。
  mystart.s汇编文件内容如下:

b reset
b reset
b reset
b reset
b reset
b reset
b reset
b reset

reset:
    mov r0, r1
    bl mytest  /*在另一个文件中定义*/
    mov r1, r2
    mov r2, r3
    mov r3, r4
loop:
    b loop

  mylowlevel_init.s汇编文件内容如下:

.global mytest
mytest:
    mov r0, r1
    mov r1, r2
    mov pc, lr

  myboot.lds链接脚本内容如下:

SECTIONS
{
    /********************************************
    *编译地址从0地址开始,
    *这个地址可以使用连接器的-Ttext参数重新修改,
    *在uboot里面是重新定位到了TEXT_BASE这个内存地址。
    ********************************************/
    . = 0x00000000; 

    /******************************************
    *代码段,把mystart.o放在最前面,其他.o的顺序
    *不管,使用* (.text)通配!
    ******************************************/
    .text : {
        mystart.o
        * (.text)
    }

    /*****************************************
    *已经初始化的全局变量
    ******************************************
    .data : {
        * (.data)
    }

    /****************************************
    *未初始化全局变量,这里放两个标号bss_start
    *和bss_end,在程序中可以引用,比如可以用来
    *计算整个二进制文件的大小。
    ****************************************/
    .bss_start = .;
    .bss : {
        * (.bss)
    }
    .bss_end = .;
}

  然后使用如下命令就可以对以上两个源文件进行编译和链接:

root@silent:/home/lianxi/uboot_lds# arm-fsl-linux-gnueabi-gcc -c mystart.s
root@silent:/home/lianxi/uboot_lds# arm-fsl-linux-gnueabi-gcc -c mylowlevel_init.s
root@silent:/home/lianxi/uboot_lds# arm-fsl-linux-gnueabi-ld -Tmyboot.lds -o myboot mylowlevel_init.o mystart.o  //使用链接脚本进行链接
root@silent:/home/lianxi/uboot_lds# ls
myboot  myboot.bin  myboot.lds  mylowlevel_init.o  mylowlevel_init.s  mystart.o  mystart.s
root@silent:/home/lianxi/uboot_lds# 

  链接完成后生成myboot文件,该文件格式为ELF,需要使用如下命令将其转换成bin文件

arm-fsl-linux-gnueabi-objcopy -O binary myboot myboot.bin

  可以使用hexdump命令查看myboot.bin和其他.o文件的内容,如:hexdump -C myboot.bin,对比链接前后的差异。如果想在开发板上跑起来,还需要根据具体的cpu,将myboot.bin制作成相应的格式(一般在前面加个一个头),cpu的类型千千万万种,这里不说了,具体格式应该查看该cpu的datasheet。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值