1. 程式人生 > >arm鏈接腳本

arm鏈接腳本

detail 賦值 img 數據 我們 targe sym 否則 靜態

一. 為什麽需要鏈接腳本

  1.1. 從源碼到可執行程序(主要有三個步驟:預編譯、編譯、鏈接)

    1.1.1. 預編譯

      a. 預編譯器執行。譬如C中的宏定義就是由預編譯器處理,註釋等也是由預編譯器處理的。

    1.1.2. 編譯

      a. 由編譯器來執行。把源碼.c .S編程機器碼.o文件。所以可以看到每個源碼.s .c文件編譯後都有相對應的.o文件

    1.1.3. 鏈接

      a. 由鏈接器來執行。把.o文件中的各函數(段)按照一定規則(鏈接腳本來指定)累積在一起,

形成可執行文件。

  1.2. 鏈接腳本究竟要做什麽?

    1.2.1. 鏈接腳本其實是個規則文件,

      a. 他是程序員用來指揮鏈接器工作的。鏈接器會參考鏈接腳本,並且使用其中規定的規則來處理.o文件中那些段,將其鏈接成一個可執行程序。

    1.2.2. 常見鏈接腳本命令

      1.2.2.1 ENTRY(SYMBOL)

        a. 將SYMBOL的值設置成入口地址。一般設置為_start

      1.2.2.2. OUTPUT(FILENAME)

        a. 定義輸出文件的名字。可以用它來指定默認的輸出文件名稱。當然我們一般都用手動-o進行指定,如果我們沒有進行手動指定的話,輸出文件名稱就以這個FILENAME為輸出文件名。

      1.2.2.3. OUTPUT_FORMAT(default, big, little)

        a. 定義3種輸出文件的格式。若有命令行選項-EB(大端),則使用第二個輸出格式,有命令行指定-EL(小端),則使用第三個格式。否則使用默認的default輸出格式。

      1.2.2.4. OUT_ARCH(arch)

        a. 設置輸出文件的體系架構

      1.2.2.5. SECTIONS命令

        a. 最重要的,最基本的,也是最主要的命令,它告訴鏈接器如何把輸入文件的各個section輸出到目標文件中的各個section中去

        b. ‘SECTIONS‘是一個功能很強大的命令. 這裏這們會描述一個很簡單的使用。讓我們假設你的程序只有代碼段,初始化過的數據段, 和未初始化過的數據段. 這些會存在於‘.text‘,‘.data‘和‘.bss‘段

技術分享圖片
SECTIONS命令的格式如下:

  SECTIONS 

        {

                一條或者多條section-command

                或者符號賦值語句

        }

        section-command的常見格式如下:

        secname [address] : [AT(LMA)] 

        { contents } 


PS :首先中括號的選項是可選的,可以不寫
View Code

    1.2.2. 簡單示例:

技術分享圖片
ENTRY(_start);

OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm");

OUTPUT_ARCH(arm);

SECTIONS
{
        . = 0x50008000;
        . = ALIGN(4);
        .text : {
                *(.text);
        }
        . = ALIGN(4);

        .data : {

                *(.data);
        }
        . = ALIGN(4);

        .bss : {
                *(.bss);
        }
}
View Code

      a. 你使用關鍵字‘SECTIONS‘寫了這個SECTIONS命令, 後面跟有一串放在花括號中的符號賦值和輸出節描述的內容.

      b. ‘.‘ 點號在鏈接腳本中代表當前位置。
      c. ‘=‘ 等號代表賦值

      d. 第二行定義一個輸出段,‘.text‘. 冒號是語法需要,現在可以被忽略. 段名後面的花括號中,你列出所有應當被放入到這個輸出段中的輸入段的名字. ‘*‘是一個通配符,匹配任何文件名.表達式‘*(.text)‘意思是所有的輸
入文件中的‘.text‘輸入段.
      
e. address表示當連接器執行此程序的時候應該把這個段加載到內存的哪個地址,此地址大多數情況下和CPU執行此處時地址相同,但當進行重定位是就可以實現鏈接地址和CPU執行地址不同(當然代碼必須是位置無關編碼)

      f. . = ALIGN(4);表示後面地址按四字節對齊

二. 程序段的概念

  2.1. 通用段

    2.1.1. 這種是編譯器鏈接器內部定好的,先天性的名字

    2.1.2. 代碼段:(.text)

      a. 又叫文本段,代碼段其實就是函數編譯後生成的東西

    2.1.3. 數據段:(.data)

      a. 數據段就是C語言中有顯式初始化為非0的全局變量,以及非0靜態局部變量

    2.1.3. bss段:(.bss)

      a. 又叫ZI(zero initial)段,就是零初始化段,對應C語言中初始化為0或未初始化的全局變量以及初始化為0或未初始化靜態局部變量。

  2.2. 自定義段

    a. 段名由程序員自己定義,段的屬性和特征也由程序員自己定義

三. uboot鏈接文件

技術分享圖片
/*
 * (C) Copyright 2002
 * Gary Jennejohn, DENX Software Engineering, <[email protected]>
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
    . = 0x00000000;

    . = ALIGN(4);
    .text      :
    {
      cpu/s5pc11x/start.o    (.text)
      cpu/s5pc11x/s5pc110/cpu_init.o    (.text)
      board/samsung/x210/lowlevel_init.o    (.text)
          cpu/s5pc11x/onenand_cp.o      (.text)                 
          cpu/s5pc11x/nand_cp.o (.text)                     
          cpu/s5pc11x/movi.o (.text) 
          common/secure_boot.o (.text) 
      common/ace_sha1.o (.text)
      cpu/s5pc11x/pmic.o (.text)
      *(.text)
    }

    . = ALIGN(4);
    .rodata : { *(.rodata) }

    . = ALIGN(4);
    .data : { *(.data) }

    . = ALIGN(4);
    .got : { *(.got) }

    __u_boot_cmd_start = .;
    .u_boot_cmd : { *(.u_boot_cmd) }
    __u_boot_cmd_end = .;

    . = ALIGN(4);
    .mmudata : { *(.mmudata) }

    . = ALIGN(4);
    __bss_start = .;
    .bss : { *(.bss) }
    _end = .;
}
View Code

參考《朱老師.1.2ARM裸機課件》

參考文獻《https://blog.csdn.net/huangbo_embed/article/details/22419349》

arm鏈接腳本