新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 引用 ADS1.2下ARM映像文件

        引用 ADS1.2下ARM映像文件

        作者: 時間:2016-11-10 來源:網絡 收藏
        ARM中的各種源文件(包括匯編文件,C語言程序及C++程序等)經過ARM編譯器編譯后生成ELF(Executable and linking format)格式的目標文件。這些目標文件和相應的C/C++運行 時用到的庫經過ARM連接器處理后,生成ELF格式的映像文件(image),這種ELF格式的映像文件是一種可執行文件,可被寫入嵌入式設備的ROM 中。

        bin文件是真正的可執行文件,axf文件是ARM的調試文件,除了包含bin的內容之外,還附加了其他的調試信息,這些調試信息加在可執行的二進制數據的前面,所以把axf文件寫到ARM的指令執行地址(一般是0x0)將不能運行,因為在此地址前幾十個字節的數據不是可執行的二進制數據,而是頭部的調試信息;而bin文件正是去掉了調試信息的可以執行的“精華”部分。

        本文引用地址:http://www.104case.com/article/201611/317261.htm

        ARM映像文件的組成:ARM映像文件是一個層次性結構的文件,包括了域(region),輸出段(output section)和輸入段(input section)。一個映像文件由一個或者多個域組成;每個域最多由三個輸出段組成組成;每個輸出段又包含一個或者多個輸入段;各輸入端包含了目標文件中的代碼和數據。

        相關術語:

        1。域 (region):一個映象文件由一個或多個域組成。反過來說域是組成映象文件的最大的結構。所謂域,指的就是整個bin映像文件所處在的區域,它又分為加載域和運行域。加載域就是映像文件被靜態存放的工作區域,一般來說flash里的整個bin文件所在的地址空間就是加載域,當然程序一般都不會放在flash里執行,一般都會搬到sdram里運行工作,它們在被搬到sdram里工作所處的地址空間就是運行域。一個域通常映射到一個物理存儲器上,如ROM和RAM等。

        2。段(Section):一個域包含一個或多個輸出段,一個輸出段包含一個或多個輸入段。我們輸入的代碼,一般有代碼部分和數據部分,這就是所謂的輸入段,每個輸入段都有相應的屬性,可以為只讀(ro),可讀寫的(rw)以及初始化成0的(zi)。

        3。RO,RW,ZI:輸入段中包含4類內容:代碼、已經初始化的數據、未經初始化的存儲區域、內容初始化為0的存儲區域。每個輸入段有相應的屬性,可以為只讀(RO)、可讀寫(RW)以及初始化為0的(ZI)。ARM連接器根據各輸入段的屬性將這些輸入段分組,再組成對應屬性的輸出段。對于加載域中的輸出段,一般來說ro段后面緊跟著rw段,rw段后面緊跟著zi段。在運行域中這些輸出段并不連續,但rw和zi一定是連著的。zi段和rw段中的數據其實可以是rw屬性。

        注:(1); C中的指令以及常量被編譯后是RO類型數據。

        (2); C中的未被初始化或初始化為0的變量編譯后是ZI類型數據。

        (3); C中的已被初始化成非0值的變量編譯后市RW類型數據。

        4。加載時地址:是映象文件位于存儲器(還沒有運行,一般在ROM中)時的地址

        5。運行時地址:是映象文件運行時的地址。

        通常一個映像文件中包含若干個域,各個域又包含若干的輸出段。ARM連接器就需要知道如下信息以決定生成相應的映像文件。燒錄到ROM中的image文件與實際運行時的ARM程序之間并不是完全一樣的。因此就有必要了解ARM程序是如何從ROM中的image到達實際運行狀態的。

        *分組信息 :決定如何各將輸入段組織成相應的輸出段和域。
        *定位信息 :決定各個域在存儲器空間中的起始地址。

        根據映像文件中地址映射的復雜程度有兩種方法告訴ARM連接器這些相關的信息。

        (1)當映像文件中最多包含兩個域,每個域最多有三個輸出段時,可以使用連接器選項告訴連接器相關的地址映射關系。選項有-ropi,-rwpi,-ro_base,-rw_base,-split等。

        (2)當映像文件地址映射關系更復雜時,可以使用一個配置文件(分散加載文件)告訴連接器相關的地址映射關系。ARM映像文件

        數據移動:

        上面已經提到了RW段加載地址一般在ROM中,運行時需要被搬運到RAM中。加載時狀態的映象文件中的RO、RW和ZI的地址都是臨時的,他們在運行時要被BootLoader程序搬運到真正的運行時地址。這個地址是連接時設置的地址。這個問題很重要,如果在編譯前沒有正確的設置運行時地址,那么程序就不能被搬運到正確的RAM地址中運行。

        了解了以上內容,那么就可以打開ADS1.2來看一下具體的設置。

        打開ADS的一個工程后,點擊如下圖所示的Debug Settings按鈕打開對話框。打開Target Settings對話框后,在左邊列表中選擇Linker選項。點擊它下面的的ARM Linker。然后在右面的選項卡選擇Output選項卡。如下圖所示。

        看看ADS 開發文檔ARMDeveloper suite 1.2 的ADS_CodeWarriorIDEGuide.pdf 怎么說的

        RO Base This text field sets both the load address and execution address of the region containing the RO

        section. If you do not enter a value, the value defaults to 0x8000.

        意思是,這個文本框設置加載時地址和運行時地址。如果沒有設置值,默認時0x8000。這個值將會對應ADS的預定義變量Image$$RO$$Base,指定了RO的base。這個變量可以被初始化程序IMPORT進去。這個參數有兩個意思:1,如果生成可執行bin文件燒寫到flash中去,那么這個地址就是要燒到flash中的地址(一般是0x0)。這里又出現一個問題,如果使用的ARM芯片是支持memory remap的(如三星的4510芯片),那么可以在bootloader程序中將RO段搬運到RAM中,再把RAM remap 到0x0,這樣系統讀取RO段的時候就可以在RAM中讀了。如果ARM芯片不支持remap(如三星的44b0x),那么RO段不能搬運到RAM中,而在FLASH中讀取。2,如果生成afx調試文件,那么這個地址是調試時加載到RAM中的地址。

        根據上面的1,2可知,如果要燒寫FLASH 那么RO Base 應該設置成ARM片選的FLASH 的首地址;如果要調試那么RO Base要設置成RAM地址。

        RW Base 這個文本框設定包含RW和ZI輸出段的運行時域地址。如果你在這里輸入一個值,連接器創建一個包含兩個運行時域的映象,這兩個域是:

        包含RO輸出段的運行時域

        包含RW和ZI輸出段的運行時域

        如果你輸入了RW Base值并且選擇了Split image選項,連接器創建的映象文件分別包含RW輸出段和ZI輸出段的裝載時地址和運行時地址,并都由你輸入的RW Base值指定。

        對于簡單連接方式,當沒有輸入RW Base值時,映象文件包含一個加載時域和一個運行時域。這時,RO輸出段、RW輸出段、ZI輸出段都包含在一個域中。當輸入RW Base值時,映象文件包含兩個運行時域,一個包含RO輸出段,一個包含RW輸出段和ZI輸出段。當指定了-split選項時,映象文件又多包含兩個加載時域,一個包含RO輸出段,一個包含RW輸出段和ZI輸出段。

        簡單的初始化用戶程序的執行環境

        ARM映像文件一開始總是存儲在ROM/Flash里面的,其RO部分既可以在ROM/Flash里面執行,也可以轉移到速度更快的RAM中執行;而RW和ZI這兩部分是必須轉移到可寫的RAM里去,其實RW包括ZI區域,ZI區域放的是未賦值的全局變量,RW 區域放的是已賦值(賦0除外)的全局變量。所謂應用程序執行環境的初始化,就是完成必要的從ROM到RAM的數據傳輸和內容清零。

        先介紹幾個必要的符號,編譯器使用下列符號來記錄各段的起始和結束地址:
        |Image$$RO$$Base| :RO段起始地址
        |Image$$RO$$Limit| :RO段結束地址加1 (在加載域中,是RW的起始地址)
        |Image$$RW$$Base| :RW段起始地址 (在運行域中即運行的時候,是RW的起始地址)
        |Image$$RW$$Limit| :ZI段結束地址加1
        |Image$$ZI$$Base| :ZI段起始地址
        |Image$$ZI$$Limit| :ZI段結束地址加1
        這些符號的值是根據鏈接器中設置的中ro-base和rw-base的設置來計算的。 由于rw和zi相連,|Image$$ZI$$Base|就等于|Image$$RW$$Limit| .其它的值都是編譯器自動計算出來的。我們還可以通過scatter文件更詳細得指定各個輸出段的工作地址。
        初始化用戶執行環境主要是把ro、rw、zi三段拷貝到指定的位置。

        下面的程序是rw、zi段在運行域中的搬運過程:

        ;Copy and paste RW data/zero initialized data
        ldr r0, =|Image$$RO$$Limit| /*取RO區末地址后面的地址,即RW數據源的起始地址*/
        ldr r1, =|Image$$RW$$Base|/*取RW區在RAM里的執行區起始地址,即編譯器選項RW_Base指定的地址*/
        ldr r3, =|Image$$ZI$$Base|/*取ZI區在RAM里面的起始地址*/


        ;Zero init base => top of initialised data
        cmp r0, r1 /* 比較ROM區中數據段首地址和RAM區中RW段目標首地址*/
        beq %F2 /*相等代表當前已經是在RAM中運行*/(F表示after,B表示before,r0與r1相等則轉跳)
        /*B %F2表向前跳到標號為2的Lable處*/
        1
        cmp r1, r3 /*不相等則和RAM區中ZI段的目標地址比較*/
        ldrcc r2, [r0], #4/*如果r1 strcc r2, [r1], #4/*如果r1 bcc %B1 /*如果r12
        ldr r1, =|Image$$ZI$$Limit| /* 取ZI段的結束地址 */
        mov r2, #0 /*將r2賦值為0*/
        3
        cmp r3, r1 ; Zero init
        strcc r2, [r3], #4 /*如果r3 bcc %B3 /*如果r3



        關鍵詞: ADS1.2ARM映像文

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 巢湖市| 商南县| 旬邑县| 昌乐县| 平舆县| 安达市| 营山县| 孟州市| 沈阳市| 新野县| 平舆县| 贡嘎县| 西乌| 文水县| 沈阳市| 丽水市| 嵊州市| 平邑县| 太和县| 磐石市| 镇沅| 白水县| 宾阳县| 郑州市| 丰镇市| 莎车县| 宜阳县| 吕梁市| 延长县| 西乌珠穆沁旗| 应城市| 苏尼特右旗| 涞水县| 澄城县| 汝阳县| 恩平市| 镇巴县| 巴彦淖尔市| 开封县| 禹城市| 伊川县|