SmartARM2200開機檔案分析

來源:互聯網
上載者:User

 

  先看圖如下:這是arm的啟動過程。

 

 

          

    先對啟動前的硬體描述一下,這樣在分析startup.s的時候就輕鬆多了。我使用的是smartarm2200開發板,其中CPU晶片使用的LPC2210,沒有內部flash(周公太摳門了)。因此說到設定也就是兩點:

一,BOOT[1:0]的設定。決定是從內部Memory還是外部Memory啟動。面對摳門的周公,咱只能從外部儲存空間啟動了。無奈啊!這也就引發了第二個擴充儲存空間的設定。

二,bank0、bank1的設定。要是用於調試的話就把ram設成bank0,可以在ram啟動,這樣可以很容易進行儲存空間重新對應。要是燒flash的話就把flash設成bank0。

因此,我們在流程圖中的路線是始終在最右邊走。哦,原來是從0x80000000啟動啊!

接下來就開始進入代碼了!首先看是整體幾個檔案的關係圖。

    剛才看到運行首地址是0x80000000,那麼怎麼安排我們的flash或者ram?記得在單片機中經常實用org 0x800方式就能搞定,我們在ads中也可以設定RO、RW、ZI和進入點地址一額可以辦到。但這隻能應用一些很簡單的情況,現在面臨的要複雜一點,因而“分散載入方式”閃亮登場。這裡不妨總結一下ARM連結方式:

    (1)simple方式:(三點設定)分別是,Output下:RO(代碼基址) RW(資料基址包括ZI)。Layout下:Object/Symble填入startup.o  Section填入start(根據實際情況定)Option下:Image Entry Pointer填入地址。

    (2)scattered方式:(也要三步)分別是,編寫.scf檔案;在output下填入該檔案;Option下填入入口地址。

下面分析.scf檔案,以mem_b.scf為例。

/**************  mem_b.scf檔案  *************/

ROM_LOAD 0x80000000                          //名      地址      範圍限制(本例子預設)
{
    ROM_EXEC 0x80000000                      //片外儲存空間   地址  範圍大小(本例預設)
    {
        Startup.o (vectors, +First)               //startup檔案中vector段放於開頭
        * (+RO)                                         //其他模組的代碼與唯讀資料放於此
    }
    IRAM 0x40000000                              //片內RAM  地址  範圍大小(預設)
    {
        Startup.o (MyStacks)                      //startup檔案中MyStacks段放於開頭
    }

    STACKS_BOTTOM +0 UNINIT               //棧底 地址 不用初始化 範圍大小限制(預設)
    {
        Startup.o (StackBottom)                //startup檔案中MyStackBottom段放於開頭
    }

    STACKS 0x40004000 UNINIT
    {
        Startup.o (Stacks)
    }

    ERAM 0x80040000
    {
        * (+RW,+ZI)                              //所有的RW與ZI資料置於此,也就是未初始化和初始化的全域變數
    }

    HEAP +0 UNINIT
    {
        Startup.o (Heap)
    }

    HEAP_BOTTOM 0x80080000 UNINIT
    {
        Startup.o (HeapTop)
    }

}

 可以用檔案的方式觀察記憶體的實際格局,在ARM Linker的Listings選項卡下,選中Image Map複選框。這樣編譯的時候就會顯示記憶體格局了。

Memory Map of the image

  Image Entry point : 0x80000000

  Load Region ROM_LOAD (Base: 0x80000000, Size: 0x000005b4, Max: 0xffffffff, ABSOLUTE)

    Execution Region ROM_EXEC (Base: 0x80000000, Size: 0x000005b4, Max: 0xffffffff, ABSOLUTE)

    Base Addr    Size         Type   Attr  Idx  E Section Name        Object

    0x80000000   0x00000110   Code   RO     1   * vectors             Startup.o
    0x80000110   0x000000a8   Code   RO    53   * !!!                 __main.o(c_a__un.l)
    0x800001b8   0x000000dc   Code   RO    10     .text               target.o
    0x80000294   0x00000078   Code   RO    42     .text               main.o
    0x8000030c   0x00000008   Code   RO    55     .text               _no_redirect.o(c_a__un.l)
    0x80000314   0x000000a4   Code   RO    57     .text               stkheap2.o(c_a__un.l)
    0x800003b8   0x00000004   Code   RO    59     .text               use_no_semi.o(c_a__un.l)
    0x800003bc   0x00000028   Code   RO    61     .text               kernel.o(c_a__un.l)
    0x800003e4   0x0000000c   Code   RO    63     .text               libspace.o(c_a__un.l)
    0x800003f0   0x00000018   Code   RO    66     .text               exit.o(c_a__un.l)
    0x80000408   0x000000fc   Code   RO    68     .text               lib_init.o(c_a__un.l)
    0x80000504   0x00000010   Code   RO    72     .text               rt_fp_status_addr.o(c_a__un.l)
    0x80000514   0x00000014   Code   RO    70     x$fpl$fpinit        fpinit.o(f_a_p.l)
    0x80000528   0x00000020   Data   RO    43     .constdata          main.o
    0x80000548   0x00000054   Data   RO    74     Region$$Table       anon$$obj.o
    0x8000059c   0x00000018   Data   RO    75     ZISection$$Table    anon$$obj.o
    Execution Region IRAM (Base: 0x40000000, Size: 0x00000400, Max: 0xffffffff, ABSOLUTE)

    Base Addr    Size         Type   Attr  Idx  E Section Name        Object

    0x40000000   0x00000400   Zero   RW     2     MyStacks            Startup.o
    Execution Region STACKS_BOTTOM (Base: 0x40000400, Size: 0x00000004, Max: 0xffffffff, ABSOLUTE, UNINIT)

    Base Addr    Size         Type   Attr  Idx  E Section Name        Object

    0x40000400   0x00000004   Zero   RW     4     StackBottom         Startup.o
    Execution Region STACKS (Base: 0x40004000, Size: 0x00000000, Max: 0xffffffff, ABSOLUTE, UNINIT)

    Base Addr    Size         Type   Attr  Idx  E Section Name        Object

    0x40004000   0x00000000   Zero   RW     6     Stacks              Startup.o
    Execution Region ERAM (Base: 0x80040000, Size: 0x00000060, Max: 0xffffffff, ABSOLUTE)

    Base Addr    Size         Type   Attr  Idx  E Section Name        Object

    0x80040000   0x00000060   Zero   RW    64     .bss                libspace.o(c_a__un.l)
    Execution Region HEAP (Base: 0x80040060, Size: 0x00000004, Max: 0xffffffff, ABSOLUTE, UNINIT)

    Base Addr    Size         Type   Attr  Idx  E Section Name        Object

    0x80040060   0x00000004   Zero   RW     3     Heap                Startup.o
    Execution Region HEAP_BOTTOM (Base: 0x80080000, Size: 0x00000000, Max: 0xffffffff, ABSOLUTE, UNINIT)

    Base Addr    Size         Type   Attr  Idx  E Section Name        Object

    0x80080000   0x00000000   Zero   RW     5     HeapTop             Startup.o

  Load Region LR$$Debug (Base: 0x00000000, Size: 0x00000000, Max: 0xffffffff, ABSOLUTE)

    Execution Region ER$$Debug (Base: 0x00000000, Size: 0x00000000, Max: 0xffffffff, ABSOLUTE)

    Base Addr    Size         Type   Attr  Idx  E Section Name        Object

    0x00000000   0x00000010   Dbug   RW     9     .debug_abbrev       Startup.o
    0x00000010   0x000003ec   Dbug   RW    19     .debug_abbrev       target.o
    0x00000000   0x0000014c   Dbug   RW    18     .debug_frame        target.o
    0x0000014c   0x00000058   Dbug   RW    52     .debug_frame        main.o
    0x000001a4   0x0000003c   Dbug   RW    54     .debug_frame        __main.o(c_a__un.l)
    0x000001e0   0x0000004c   Dbug   RW    56     .debug_frame        _no_redirect.o(c_a__un.l)
    0x0000022c   0x00000094   Dbug   RW    58     .debug_frame        stkheap2.o(c_a__un.l)
    0x000002c0   0x00000044   Dbug   RW    60     .debug_frame        use_no_semi.o(c_a__un.l)
    0x00000304   0x00000058   Dbug   RW    62     .debug_frame        kernel.o(c_a__un.l)
    0x0000035c   0x00000044   Dbug   RW    65     .debug_frame        libspace.o(c_a__un.l)
    0x000003a0   0x0000004c   Dbug   RW    67     .debug_frame        exit.o(c_a__un.l)
    0x000003ec   0x0000007c   Dbug   RW    69     .debug_frame        lib_init.o(c_a__un.l)
    0x00000468   0x0000004c   Dbug   RW    71     .debug_frame        fpinit.o(f_a_p.l)
    0x000004b4   0x0000004c   Dbug   RW    73     .debug_frame        rt_fp_status_addr.o(c_a__un.l)
    0x00000000   0x00000074   Dbug   RW     7     .debug_info         Startup.o
    0x00000074   0x0000007c   Dbug   RW    12     .debug_info         target.o
    0x000000f0   0x00000108   Dbug   RW    35     .debug_info         target.o
    0x000001f8   0x000000e4   Dbug   RW    31     .debug_info         target.o
    0x000002dc   0x00000540   Dbug   RW    15     .debug_info         target.o
    0x0000081c   0x00000110   Dbug   RW    27     .debug_info         target.o
    0x0000092c   0x00000090   Dbug   RW    45     .debug_info         main.o
    0x000009bc   0x00000134   Dbug   RW    49     .debug_info         main.o
    0x00000000   0x0000009c   Dbug   RW     8     .debug_line         Startup.o
    0x0000009c   0x000000b8   Dbug   RW    11     .debug_line         target.o
    0x00000154   0x000000f8   Dbug   RW    14     .debug_line         target.o
    0x0000024c   0x00000064   Dbug   RW    26     .debug_line         target.o
    0x000002b0   0x00000050   Dbug   RW    30     .debug_line         target.o
    0x00000300   0x00000050   Dbug   RW    34     .debug_line         target.o
    0x00000350   0x00000078   Dbug   RW    44     .debug_line         main.o
    0x000003c8   0x000000a4   Dbug   RW    48     .debug_line         main.o
    0x00000000   0x000002c0   Dbug   RW    17     .debug_loc          target.o
    0x000002c0   0x00000064   Dbug   RW    51     .debug_loc          main.o
    0x00000000   0x00000190   Dbug   RW    13     .debug_macinfo      target.o
    0x00000190   0x00000078   Dbug   RW    29     .debug_macinfo      target.o
    0x00000208   0x0000004c   Dbug   RW    33     .debug_macinfo      target.o
    0x00000254   0x000001f0   Dbug   RW    37     .debug_macinfo      target.o
    0x00000444   0x00000190   Dbug   RW    47     .debug_macinfo      main.o
    0x00000000   0x00000128   Dbug   RW    16     .debug_pubnames     target.o
    0x00000128   0x00000064   Dbug   RW    28     .debug_pubnames     target.o
    0x0000018c   0x00000058   Dbug   RW    32     .debug_pubnames     target.o
    0x000001e4   0x00000084   Dbug   RW    36     .debug_pubnames     target.o
    0x00000268   0x00000020   Dbug   RW    46     .debug_pubnames     main.o
    0x00000288   0x00000028   Dbug   RW    50     .debug_pubnames     main.o
================================================================================

Image component sizes
      Code    RO Data    RW Data    ZI Data      Debug  

       612        140          0       1032       8356   Object Totals
       708          0          0         96        860   Library Totals

================================================================================
      Code    RO Data    RW Data    ZI Data      Debug  

      1320        140          0       1128       9216   Grand Totals

================================================================================

    Total RO  Size(Code + RO Data)                 1460 (   1.43kB)
    Total RW  Size(RW Data + ZI Data)              1128 (   1.10kB)
    Total ROM Size(Code + RO Data + RW Data)       1460 (   1.43kB)

================================================================================

 

 

 ****************************************************************************

 

 一般的可執行程式都包括程式碼片段、資料區段。也可以簡單的看作由兩部分組成:RO段和RW段。RO段一般包括程式碼片段和一些常量,在啟動並執行時候是唯讀。而RW段包括一些全域變數和靜態變數,在啟動並執行時候是可以改變的(讀寫)。如果有部分全域變數被初始化為零,則RW段裡還包括了ZI段。
RO: Read Only  程式碼片段
RW: Read Write 已初始化的全域變數
ZI: Zero Init   未初始化的全域變數

     因為RO段是唯讀,在啟動並執行時候不可以改變,所以,在啟動並執行時候,RO段可以駐留在Flash裡(當然也可以在SDRAM或者SRAM裡了)。而RW段是可以讀寫的,所以,在啟動並執行時候必須被裝載到SDRAM或者SRAM裡。
     在用ADS編譯的時候,是需要設定RO BASE 和RW BASE的,用過ADS的應該都清楚這點。通過RO BASE 和RW BASE的設定,告訴連結器(linker)該程式的起始運行地址(RO BASE)和 RW段的地址 (RW BASE)。如果一個程式只有RO段,沒有RW段,那麼這個程式可以完全在Flash裡運行,不需要用到SDRAM 或者 SRAM。如果包括RW段和RO段,那麼該程式的RW段必須在被訪問以前被拷貝到SDRAM 或者SRAM裡去,以保證程式可以正確運行。下面這個圖說明了一個程式執行前(load view)和執行時(execute view)的狀態。可以看到,整個程式在執行前始放在ROM裡的,在執行的時候,RW段被拷貝到了RAM裡的合適位置去。

    程式一開始總是儲存在ROM/Flash裡面的,其RO部分既可以在ROM/Flash裡面執行,也可以轉移到速度更快的RAM中去;而RW和ZI這兩部分是必須轉移到可寫的RAM裡去。所謂應用程式執行環境的初始化,就是完成必要的從ROM到RAM的資料轉送和內容清零。

  不同的工具鏈會提供一些不同的機制和方法協助使用者完成這一步操作,主要是跟連結器(Linker)相關。下面是在ARM開發工具環境ADS下,一種常用儲存空間模型的直接實現:

  

    LDR r0, = |Image$$RO$$Limit| ;得到RO段末的下一位元組的地址 ,ROM中的RW的開始地址
  LDR r1, = |Image$$RW$$Base| ;得到RAM中的RW段的初始地址
  LDR r3, = |Image$$ZI$$Base| ;全域變數的初始地址  
  CMP r0, r1 ; 
  BEQ LOOP1 
LOOP0 
  CMP r1, r3 ; 是否到RAM中的RW段的末地址,如果沒到,則一直將ROM(FLASH變    量與資料區段拷貝到RAM中
  LDRCC r2, [r0], #4 ;[R0]=[R1] 
  STRCC r2, [r1], #4 ;  
  BCC LOOP0 
LOOP1 
  LDR r1, = |Image$$ZI$$Limit| ; LOOP1與LOOP2執行將ZI初始化為0
  MOV r2, #0 
LOOP2 
  CMP r3, r1 
  STRCC r2, [r3], #4 ; 
  BCC LOOP2

    在ADS裡,有一些預先定義了的變數可以用(linker defined symbol)。在下面的實現裡,用到了幾個預定義的變數:
Image$$RO$$Base 該變數指定了RO段的 BASE
Image$$RO$$Limit 該變數指定了RO段的 Limit
Image$$RW$$Base 該變數指定了RW段的 BASE
Image$$RW$$Limit 該變數指定了RW段的 Limit
Image$$ZI$$Base 該變數指定了ZI段的 BASE
Image$$ZI$$Limit 該變數指定了ZI段的 Limit
註:具體可以參考ADS Linker Guide
Image$$RO$$Limit 減 Image$$RO$$Base 等於RO段的大小
Image$$RW$$Limit 減 Image$$RW$$Base 等於RW段的大小
Image$$ZI$$Limit 減 Image$$ZI$$Base 等於ZI段的大小
(Image$$RO$$Limit 減 Image$$RO$$Base)
+ (Image$$RW$$Limit 減 Image$$RW$$Base)
= 等於整個程式的大小
註:ZI段始包括在RW段裡面的。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.