关于bootloader链接脚本中的ALIGN关键字的解析

来源:互联网 发布:木制玩具设计软件 编辑:程序博客网 时间:2024/06/07 10:40

问题描述:

前几天遇到一个问题:下图表示的链接脚本中的绿色框中ALIGN4):表示什么意思?是4个字节对齐呢?还是24次幂个字节对齐?还有就是对齐是如何对齐的呢?如果有结论该如何验证这些内容?


OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
 . = 0x33e00000;
 . = ALIGN(4);

 .text :
 {
   cpu/samsung/s5p6450/start.o (.text)
   cpu/samsung/s5p6450/start_irom.o (.text)
   cpu/samsung/s5p6450/cpu_init.o (.text)
   board/samsung/smdk6450/lowlevel_init.o (.text)
   cpu/samsung/s5p6450/nand_cp.o (.text)
   cpu/samsung/s5p6450/movi.o (.text)
   *(.text)
 }

.................

测试:

方法:以上图中的红色部分为纵轴,绿色部分为横轴,构成下表:

横轴:分别是12,4,8,16,32字节对齐

纵轴:分别是红色部分的基地址:0x33e0_0000~0x33e0_0010等。

验证:

                                   ALIGN(1)          ALIGN(2)          ALIGN(4)          ALIGN(8)          ALIGN(16)          ALIGN(32)          ALIGN(64)
. = 0x33e00000;       0x33e00000       0x33e00000     0x33e00000     0x33e00000     0x33e00000        0x33e00000       0x33e00000     
. = 0x33e00001;       0x33e00004       0x33e00004     0x33e00004     0x33e00008     0x33e00010        0x33e00020       0x33e00030     
. = 0x33e00002;       0x33e00004       0x33e00004     0x33e00004     0x33e00008     0x33e00010        0x33e00020       0x33e00030
. = 0x33e00003;       0x33e00004       0x33e00004     0x33e00004     0x33e00008     0x33e00010        0x33e00020       0x33e00030
. = 0x33e00004;       0x33e00004       0x33e00004     0x33e00004     0x33e00008     0x33e00010        0x33e00020       0x33e00030

. = 0x33e00005;       0x33e00008       0x33e00008     0x33e00008     0x33e00008     0x33e00010        0x33e00020       0x33e00030
. = 0x33e00006;       0x33e00008       0x33e00008     0x33e00008     0x33e00008     0x33e00010        0x33e00020       0x33e00030
. = 0x33e00007;       0x33e00008       0x33e00008     0x33e00008     0x33e00008     0x33e00010        0x33e00020       0x33e00030
. = 0x33e00008;       0x33e00008       0x33e00008     0x33e00008     0x33e00008     0x33e00010        0x33e00020       0x33e00030

. = 0x33e00009;       0x33e0000C      0x33e0000C     0x33e0000C     0x33e00010     0x33e00010        0x33e00020       0x33e00030
. = 0x33e0000A;       0x33e0000C      0x33e0000C     0x33e0000C     0x33e00010     0x33e00010        0x33e00020       0x33e00030
. = 0x33e0000B;       0x33e0000C      0x33e0000C     0x33e0000C     0x33e00010     0x33e00010        0x33e00020       0x33e00030
. = 0x33e0000C;       0x33e0000C      0x33e0000C     0x33e0000C     0x33e00010     0x33e00010        0x33e00020       0x33e00030
. = 0x33e0000D;       0x33e00010      0x33e00010     0x33e00010      0x33e00010     0x33e00010        0x33e00020       0x33e00030
. = 0x33e0000E;       0x33e00010      0x33e00010     0x33e00010      0x33e00010     0x33e00010        0x33e00020       0x33e00030
. = 0x33e0000F;       0x33e00010      0x33e00010     0x33e00010      0x33e00010     0x33e00010        0x33e00020       0x33e00030
. = 0x33e00010;       0x33e00010      0x33e00010     0x33e00010      0x33e00010     0x33e00010        0x33e00020       0x33e00030

最终结论:

1.ALIGN对齐在汇编文件中和链接脚本中都会涉及到:

     在汇编文件中,是伪操作 .align x 实现的:表示2x次幂个字节对齐;

     在链接脚本中,ALIGN关键字:ALIGN(X)中的X表示多少个字节对齐。

2.X的取值也是有讲究的,必须是2的整数次幂。例如:填写1,2,4,8,16,32,64....

3.在链接脚本当中,ALIGN主要是在程序链接时用来实现数据边界对齐功能:

     什么是边界对齐,怎样对齐呢?

     首先解释什么是边界对齐:

当有一块数据需要存放时,需要一个起始地址(存储空间的上边界),然后放数据,

放完后会有一个结束地址(存储空间的下边界);

     然后是该怎样对齐?一般情况,上边界都是给定的,但是下边如何确定呢?

先看ALIGN(X)是多少字节对齐,再看上边界,然后就可以确定下边界。

     下边界的确定有以下三种情况:

     (1.如果字节对齐数是ALIGN(X);并且上边界地址小于等于X

           则下边界为:基地址+X

     (2.如果字节对齐数是ALIGN(X);并且上边界地址大于X,则下边界为:

   基地址+X*n  n为多少呢?n=(上边界地址尾数%X的除数)+1

     什么是基地址?其实是指链接脚本中最开始指定的地址的尾数变为零,

          例如:0x33e0_0008  ->  基地址就是:0x33e0_0000

                0x33e0_00F5  ->  基地址就是:0x33e0_00F0

PS:

ALIGN(X)中的X最好是大于等于4,因为32位的处理器最小就是4字节对齐;

如果X赋值为1,2,则也是使用的默认4字节对齐。

0 0