免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 786 | 回复: 0
打印 上一主题 下一主题

arm-linux bootloader预备之GNU ld机理 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-07-20 02:25 |只看该作者 |倒序浏览

       
       
       
       
       
       
       
       
       
       
1.
目标文件格式与类型
        GNU
C
compiler根据源文件的后缀名来对文件进行预处理、汇编或编译操作。在编译链接时,生成的目标文件都是ELF格式的(可执行链接格式,Executable
and Linking Format)。Object文件格式有三种类型:
        (1)可重定位(relocatable)文件:用来和其他的object文件一起链接为一个可执行文件(executable)或一个共享文件(.so文件,shared
object)。
        (2)可执行(executable)文件;
        (3)共享目标文件(shared
object file):用于被下面的两个链接器链接。一是链接编辑器(ld),可以和其他的relocatable或shared
object
file来创建其他的目标文件,例如.so共享库(可用file命令查看其属性);二是动态链接器,联合一个可执行文件和其他的shared
object file来创建一个进程映像。
2.
链接与链接脚本
        链接器ld把object文件中的每个section都作为一个整体,为其分配运行的地址(memory
layout),这个过程就是重定位(relocation);最后把所有目标文件合并为一个目标文件。
        链接通过一个linker
script来控制,这个脚本描述了输入文件的sections到输出文件的映射,以及输出文件的memory
layout。
        因此,linker总会使用一个linker
script,如果不特别指定,则使用默认的script;可以使用‘-T’命令行选项来指定一个linker
script。
*映像文件的输入段与输出段
        linker把多个输入文件合并为一个输出文件。输出文件和输入文件都是目标文件(object
file),输出文件通常被称为可执行文件(executable)。
        每个目标文件都有一系列section,输入文件的section称为input
section,输出文件的section则称为output
section。
        一个section可以是loadable的,即输出文件运行时需要将这样的section加载到memory(类似于RO&RW段);也可以是allocatable的,这样的section没有任何内容,某些时候用0对相应的memory区域进行初始化(类似于ZI段);如果一个section既非loadable也非allocatable,则它通常包含的是调试信息。
        每个loadable或allocatable的output
section都有两个地址,一是VMA(virtual
memory address),是该section的运行时域地址;二是LMA(load
memory address),是该section的加载时域地址。
        可以通过objdump工具附加'-h'选项来查看目标文件中的sections。
*简单的Linker
script
(1)
SECTIONS命令:
        The
SECTIONS command tells the linker how to map input sections into
output sections, and how to place the output sections in memory.
        命令格式如下:
        SECTIONS
        {
                sections-command
                sections-command
                ......
        }
        其中sections-command可以是ENTRY命令,符号赋值,输出段描述,也可以是overlay描述。
(2)
地址计数器‘.’(location
counter):
        该符号只能用于SECTIONS命令内部,初始值为‘0’,可以对该符号进行赋值,也可以使用该符号进行计算或赋值给其他符号。它会自动根据SECTIONS命令内部所描述的输出段的大小来计算当前的地址。
(3)
输出段描述(output
section description):
        前面提到在SECTIONS命令中可以作输出段描述,描述的格式如下:
        section
[address] [(type)] : [AT(lma)]
                {
                        output-section-command
                        output-section-command
                        ...
                }
[>region] [AT>lma_region] [:phdr :phdr ...] [=fillexp]
        很多附加选项是用不到的。其中的output-section-command又可以是符号赋值,输入段描述,要直接包含的数据值,或者某一特定的输出段关键字。
*linker
script 实例
==============================
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
    .
= 0xa3f00000;
            __boot_start
= .;
            .start                ALIGN(4)
: {
                        *(.text.start)
            }
            .setup                ALIGN(4)
: {
                        setup_block
= .;
                        *(.setup)
                        setup_block_end
= .;
            }
            .text                ALIGN(4)
: {
                        *(.text)
            }
            .rodata                ALIGN(4)
: {
                        *(.rodata)
            }
            .data                ALIGN(4)
: {
                        *(.data)
    }
            .got                ALIGN(4)
: {
                        *(.got)
            }
            __boot_end
= .;
            .bss                ALIGN(16)
: {
                        bss_start
= .;
                        *(.bss)
        *(COMMON)
                        bss_end
= .;
            }
            .comment        ALIGN(16)
: {
                        *(.comment)
            }
            stack_point
= __boot_start + 0x00100000;
            loader_size
= __boot_end - __boot_start;
            setup_size
= setup_block_end - setup_block;
}
=============================         
        在SECTIONS命令中的类似于下面的描述结构就是输出段描述:
        .start                ALIGN(4)
: {
    *(.text.start)
        }
        .start为output
section name,ALIGN(4)返回一个基于location
counter(.)的4字节对齐的地址值。*(.text.start)是输入段描述,*为通配符,意思是把所有被链接的object文件中的.text.start段都链接进这个名为.start的输出段。
        源文件中所标识的section及其属性实际上就是对输入段的描述,例如.text.start输入段在源文件start.S中的代码如下:
        .section
.text.start
        .global
_start
        _start
:
    b                start
[推荐阅读]
1.ARM学习报告002--GNU tool开发ARM程序及生成映象文件机理
2.Using ld, the GNU Linker
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/26710/showart_343210.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP