天天看點

嵌入式Linux引導過程之1.1——Xloader的xloader.lds

本文中的所有代碼版本都是基于st的spearplus開發闆的。

xloader是在系統上電之後,執行完rom中的frimware後最先開始執行的使用者程式,它的體積很小,執行的功能也很簡單,主要是對系統時 鐘以及外部sdram進行初始化,初始化完成之後就檢查flash中的uboot image是否準備好,如果準備好了就将flash中的uboot image根據image header中指定的load address加載到外部sdram中,然後就跳轉到uboot執行代碼。

這裡,我試圖從頭開始,在源代碼級别上來分析整個系統的引導過程。

script對連結腳本檔案進行了介紹。

現在,我們首先開看一看xloader.lds的代碼:

output_format("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")

output_arch(arm)

entry(xloader_entry)

sections

{

    . = 0x00000000;

    . = align(4);

    .text    :

    {

      ./obj/init.o    (.text)

      *(.text)

    }

    .rodata . :

        {

                *(.rodata)

        }

        . = align(4);

    .data : { *(.data) }

    .got : { *(.got) }

    __bss_start = .;

    .bss : { *(.bss) }

    _end = .;

}

下面,我們對這一段代碼逐句進行分析。

在gnu的文檔中,是這麼定義的:

output_format(default, big, little),在連結的時候,如果使用了-eb的指令行參數,則使用這裡的big參數指定的位元組序,如果使用了-el的指令行參數,則使用這裡的 little參數指定的位元組序,如果沒有使用任何指令行參數,則使用這裡的default參數指定的位元組序。

由xloader.lds中的定義可見,不管在連結的時候使用了何種指令行參數,輸出的目标檔案都是使用elf32-littlearm方式的位元組序。

output_arch(bfdarch),也就是指定了目标的體系結構,在這裡,spearplus内部使用的處理器核是arm926ejs的,是以體系結構也就是arm。

entry(symbol)

there are several ways to set the entry point. the linker will set the entry point by trying each of the following methods in order, and stopping when one of them succeeds:

    * the `-e' entry command-line option;

    * the entry(symbol) command in a linker script;

    * the value of the symbol start, if defined;

    * the address of the first byte of the `.text' section, if present;

    * the address 0.

也就是說,entry(xloader_entry)定義了整個程式的入口處,也就是在标号xloader_entry處。整個程式将從這裡開始運作。

接下來的部分,是對整個輸出目标檔案中各個段的存儲位置的定義。

     {

       sections-command

       ...

     }

對于其中的每一個sections-command,其完整的定義如下:

the full description of an output section looks like this:

     section [address] [(type)] :

       [at(lma)] [align(section_align)] [subalign(subsection_align)]

       {

         output-section-command

         ...

       } [>region] [at>lma_region] [:phdr :phdr ...] [=fillexp]

most output sections do not use most of the optional section attributes.

the whitespace around section is required, so that the section name is unambiguous. the colon and the curly braces are also required. the line breaks and other white space are optional.

下面來看看xloader.lds中sections的定義:

    /* location counter設定為0x00000000,其實由于在makefile中的

     * 連結選項中使用了-ttext $(text_base),而text_base=0xd2800b00

     * 是以,此處的設定其實是沒有作用的,代碼運作的時候将運作在text_base位址

     */

    . = align(4);    /* 四位元組對齊 */

    /* 将所有輸入目标檔案中的.text段即代碼段放在此處,并且,輸出目标檔案中的.text段中的

     * 開頭部分存放init.o的.text段。也就是運作的第一條代碼,也就是xloader_entry

     * 标号對應的代碼就在init.o當中

    /* 緊接着.text段,存放所有輸入目标檔案中的.rodata段,也就是

     * 隻讀資料段。此處注意.rodata後跟着的.,這個.表示目前location counter,

     * 對應于上述完整描述sections中的[address]

     * 此處表示.rodata段緊接着.text段存放,而不用任何對齊

        . = align(4);    /* 四位元組對齊 */

    /* 将所有輸入目标檔案中的.data讀寫資料段存儲在此處

     * 所有全局手動初始化的變量存儲在該段中,并且在輸出目标檔案中已經配置設定了存儲空間

    /* .got段是global offset table,具體的作用還沒有搞清楚 */

    /* .bss段的開始,所有全局未初始化變量的大小等資訊存儲在該段中

     * 但是在輸出的目标檔案中并不為這些變量配置設定存儲空間,

     * 而是交給作業系統在初始化的時候配置設定記憶體,然後緊跟在.data段後面并初始化為零

     * 另外,此處還定義了兩個标号分别表示.bss的開始和結束(也是整個目标檔案的結束)

從這裡,我們能夠得到的最關鍵的資訊是:整個程式的入口在标号xloader_entry處,并且該标号定義在init.o目标檔案中,因為整個最終的連結之後的目标檔案中,位于最開頭的就是init.o目标檔案。

于是,我們可以根據這個線索來繼續追蹤整個的引導過程了。

參考文章:

對.lds連接配接腳本檔案的分析

<a target="_blank" href="http://blog.csdn.net/tony821224/archive/2008/01/18/2051755.aspx">http://blog.csdn.net/tony821224/archive/2008/01/18/2051755.aspx</a>

documentation for binutils 2.18--ld

<a target="_blank" href="http://sourceware.org/binutils/docs/ld/index.html">http://sourceware.org/binutils/docs/ld/index.html</a>

.bss段和.data段的差別

<a target="_blank" href="http://www.w3china.org/blog/more.asp?name=foxwolf&amp;id=29997">http://www.w3china.org/blog/more.asp?name=foxwolf&amp;id=29997</a>

什麼是bss段

<a target="_blank" href="http://blog.csdn.net/bobocheng1231/archive/2008/02/23/2115289.aspx">http://blog.csdn.net/bobocheng1231/archive/2008/02/23/2115289.aspx</a>

繼續閱讀