<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > SmartARM2200啟動(dòng)文件分析

          SmartARM2200啟動(dòng)文件分析

          作者: 時(shí)間:2016-11-10 來(lái)源:網(wǎng)絡(luò) 收藏
          先看圖如下:這是arm的啟動(dòng)過(guò)程。

          本文引用地址:http://www.ex-cimer.com/article/201611/317250.htm

          先對(duì)啟動(dòng)前的硬件描述一下,這樣在分析startup.s的時(shí)候就輕松多了。我使用的是smartarm2200開(kāi)發(fā)板,其中CPU芯片使用的LPC2210,沒(méi)有內(nèi)部flash(周公太摳門了)。因此說(shuō)到設(shè)置也就是兩點(diǎn):

          一,BOOT[1:0]的設(shè)置。決定是從內(nèi)部Memory還是外部Memory啟動(dòng)。面對(duì)摳門的周公,咱只能從外部存儲(chǔ)器啟動(dòng)了。無(wú)奈??!這也就引發(fā)了第二個(gè)擴(kuò)展存儲(chǔ)器的設(shè)置。

          二,bank0、bank1的設(shè)置。要是用于調(diào)試的話就把ram設(shè)成bank0,可以在ram啟動(dòng),這樣可以很容易進(jìn)行存儲(chǔ)器重映射。要是燒flash的話就把flash設(shè)成bank0。

          因此,我們?cè)诹鞒虉D中的路線是始終在最右邊走。哦,原來(lái)是從0x80000000啟動(dòng)啊!

          接下來(lái)就開(kāi)始進(jìn)入代碼了!首先看下圖是整體幾個(gè)文件的關(guān)系圖。

          剛才看到運(yùn)行首地址是0x80000000,那么怎么安排我們的flash或者ram?記得在單片機(jī)中經(jīng)常實(shí)用org 0x800方式就能搞定,我們?cè)赼ds中也可以設(shè)置RO、RW、ZI和入口點(diǎn)地址一額可以辦到。但這只能應(yīng)用一些很簡(jiǎn)單的情況,現(xiàn)在面臨的要復(fù)雜一點(diǎn),因而“分散加載方式”閃亮登場(chǎng)。這里不妨總結(jié)一下ARM鏈接方式:

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

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

          下面分析.scf文件,以mem_b.scf為例。

          /************** mem_b.scf文件 *************/

          ROM_LOAD 0x80000000//名 地址 范圍限制(本例子缺?。?br />{
          ROM_EXEC 0x80000000//片外存儲(chǔ)器 地址 范圍大?。ū纠笔。?br /> {
          Startup.o (vectors, +First) //startup文件中vector段放于開(kāi)頭
          * (+RO) //其他模塊的代碼與只讀數(shù)據(jù)放于此
          }
          IRAM 0x40000000 //片內(nèi)RAM 地址 范圍大小(缺?。?br /> {
          Startup.o (MyStacks) //startup文件中MyStacks段放于開(kāi)頭
          }

          STACKS_BOTTOM +0 UNINIT //棧底 地址 不用初始化 范圍大小限制(缺?。?br /> {
          Startup.o (StackBottom) //startup文件中MyStackBottom段放于開(kāi)頭
          }

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

          ERAM 0x80040000
          {
          * (+RW,+ZI) //所有的RW與ZI數(shù)據(jù)置于此,也就是未初始化和初始化的全局變量
          }

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

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

          }

          可以用文件的方式觀察內(nèi)存的實(shí)際格局,在ARM Linker的Listings選項(xiàng)卡下,選中Image Map復(fù)選框。這樣編譯的時(shí)候就會(huì)顯示內(nèi)存格局了。

          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

          Tableanon
          obj.o
          0x8000059c 0x00000018 Data RO 75 ZISection
          Tableanon
          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)

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

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

          一般的可執(zhí)行程序都包括代碼段、數(shù)據(jù)段。也可以簡(jiǎn)單的看作由兩部分組成:RO段和RW段。RO段一般包括代碼段和一些常量,在運(yùn)行的時(shí)候是只讀的。而RW段包括一些全局變量和靜態(tài)變量,在運(yùn)行的時(shí)候是可以改變的(讀寫)。如果有部分全局變量被初始化為零,則RW段里還包括了ZI段。
          RO: Read Only 代碼段
          RW: Read Write 已初始化的全局變量
          ZI: Zero Init 未初始化的全局變量

          因?yàn)镽O段是只讀的,在運(yùn)行的時(shí)候不可以改變,所以,在運(yùn)行的時(shí)候,RO段可以駐留在Flash里(當(dāng)然也可以在SDRAM或者SRAM里了)。而RW段是可以讀寫的,所以,在運(yùn)行的時(shí)候必須被裝載到SDRAM或者SRAM里。
          在用ADS編譯的時(shí)候,是需要設(shè)置RO BASE 和RW BASE的,用過(guò)ADS的應(yīng)該都清楚這點(diǎn)。通過(guò)RO BASE 和RW BASE的設(shè)置,告訴鏈接器(linker)該程序的起始運(yùn)行地址(RO BASE)和 RW段的地址 (RW BASE)。如果一個(gè)程序只有RO段,沒(méi)有RW段,那么這個(gè)程序可以完全在Flash里運(yùn)行,不需要用到SDRAM 或者 SRAM。如果包括RW段和RO段,那么該程序的RW段必須在被訪問(wèn)以前被拷貝到SDRAM 或者SRAM里去,以保證程序可以正確運(yùn)行。下面這個(gè)圖說(shuō)明了一個(gè)程序執(zhí)行前(load view)和執(zhí)行時(shí)(execute view)的狀態(tài)。從圖中可以看到,整個(gè)程序在執(zhí)行前始放在ROM里的,在執(zhí)行的時(shí)候,RW段被拷貝到了RAM里的合適位置去。

          程序一開(kāi)始總是存儲(chǔ)在ROM/Flash里面的,其RO部分既可以在ROM/Flash里面執(zhí)行,也可以轉(zhuǎn)移到速度更快的RAM中去;而RW和ZI這兩部分是必須轉(zhuǎn)移到可寫的RAM里去。所謂應(yīng)用程序執(zhí)行環(huán)境的初始化,就是完成必要的從ROM到RAM的數(shù)據(jù)傳輸和內(nèi)容清零。

            不同的工具鏈會(huì)提供一些不同的機(jī)制和方法幫助用戶完成這一步操作,主要是跟鏈接器(Linker)相關(guān)。下面是在ARM開(kāi)發(fā)工具環(huán)境ADS下,一種常用存儲(chǔ)器模型的直接實(shí)現(xiàn):

            

          LDR r0, = |Image

          RO
          Limit| ;得到RO段末的下一字節(jié)的地址 ,ROM中的RW的開(kāi)始地址
            LDR r1, = |Image
          RW
          Base| ;得到RAM中的RW段的初始地址
            LDR r3, = |Image
          ZI
          Base| ;全局變量的初始地址
            CMP r0, r1 ;
            BEQ LOOP1
          LOOP0
            CMP r1, r3 ;是否到RAM中的RW段的末地址,如果沒(méi)到,則一直將ROM(FLASH變 量與數(shù)據(jù)段拷貝到RAM中
            LDRCC r2, [r0], #4;[R0]=[R1]
            STRCC r2, [r1], #4 ;
            BCC LOOP0
          LOOP1
            LDR r1, = |Image
          ZI
          Limit| ; LOOP1與LOOP2執(zhí)行將ZI初始化為0
            MOV r2, #0
          LOOP2
            CMP r3, r1
            STRCC r2, [r3], #4 ;
            BCC LOOP2

          在ADS里,有一些預(yù)先定義了的變量可以用(linker defined symbol)。在下面的實(shí)現(xiàn)里,用到了幾個(gè)預(yù)定義的變量:
          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)
          = 等于整個(gè)程序的大小
          注:ZI段始包括在RW段里面的。



          關(guān)鍵詞: SmartARM2200啟動(dòng)文

          評(píng)論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();